diff -Nru a/Documentation/cli-sti-removal.txt b/Documentation/cli-sti-removal.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/cli-sti-removal.txt	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,134 @@
+
+#### cli()/sti() removal guide, started by Ingo Molnar <mingo@redhat.com>
+
+
+as of 2.5.28, five popular macros have been removed on SMP, and
+are being phased out on UP:
+
+ cli(), sti(), save_flags(flags), save_flags_cli(flags), restore_flags(flags)
+
+until now it was possible to protect driver code against interrupt
+handlers via a cli(), but from now on other, more lightweight methods
+have to be used for synchronization, such as spinlocks or semaphores.
+
+for example, driver code that used to do something like:
+
+	struct driver_data;
+
+	irq_handler (...)
+	{
+		....
+		driver_data.finish = 1;
+		driver_data.new_work = 0;
+		....
+	}
+
+	...
+
+	ioctl_func (...)
+	{
+		...
+		cli();
+		...
+		driver_data.finish = 0;
+		driver_data.new_work = 2;
+		...
+		sti();
+		...
+	}
+
+was SMP-correct because the cli() function ensured that no
+interrupt handler (amongst them the above irq_handler()) function
+would execute while the cli()-ed section is executing.
+
+but from now on a more direct method of locking has to be used:
+
+	spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
+	struct driver_data;
+
+	irq_handler (...)
+	{
+		unsigned long flags;
+		....
+		spin_lock_irqsave(&driver_lock, flags);
+		....
+		driver_data.finish = 1;
+		driver_data.new_work = 0;
+		....
+		spin_unlock_irqrestore(&driver_lock, flags);
+		....
+	}
+
+	...
+
+	ioctl_func (...)
+	{
+		...
+		spin_lock_irq(&driver_lock);
+		...
+		driver_data.finish = 0;
+		driver_data.new_work = 2;
+		...
+		spin_unlock_irq(&driver_lock);
+		...
+	}
+
+the above code has a number of advantages:
+
+- the locking relation is easier to understand - actual lock usage
+  pinpoints the critical sections. cli() usage is too opaque.
+  Easier to understand means it's easier to debug.
+
+- it's faster, because spinlocks are faster to acquire than the
+  potentially heavily-used IRQ lock. Furthermore, your driver does
+  not have to wait eg. for a big heavy SCSI interrupt to finish,
+  because the driver_lock spinlock is only used by your driver.
+  cli() on the other hand was used by many drivers, and extended
+  the critical section to the whole IRQ handler function - creating
+  serious lock contention.
+
+ 
+to make the transition easier, we've still kept the cli(), sti(),
+save_flags(), save_flags_cli() and restore_flags() macros defined
+on UP systems - but their usage will be phased out until 2.6 is
+released.
+
+drivers that want to disable local interrupts (interrupts on the
+current CPU), can use the following five macros:
+
+  local_irq_disable(), local_irq_enable(), local_irq_save(flags),
+  local_irq_save_off(flags), local_irq_restore(flags)
+
+but beware, their meaning and semantics are much simpler, far from
+that of the old cli(), sti(), save_flags(flags) and restore_flags(flags)
+SMP meaning:
+
+    local_irq_disable()       => turn local IRQs off
+
+    local_irq_enable()        => turn local IRQs on
+
+    local_irq_save(flags)     => save the current IRQ state into flags. The
+                                 state can be on or off. (on some
+                                 architectures there's even more bits in it.)
+
+    local_irq_save_off(flags) => save the current IRQ state into flags and
+                                 disable interrupts.
+
+    local_irq_restore(flags)  => restore the IRQ state from flags.
+
+(local_irq_save can save both irqs on and irqs off state, and
+local_irq_restore can restore into both irqs on and irqs off state.)
+
+another related change is that synchronize_irq() now takes a parameter:
+synchronize_irq(irq). This change too has the purpose of making SMP
+to make the transition easier, we've still kept the cli(), sti(),
+save_flags() and restore_flags() macros defined on UP systems - but
+their usage will be phased out until the 2.6 kernel is released.
+
+
+why were these changes done? The main reason was the architectural burden
+of maintaining the cli()/sti() interface - it became a real problem. The
+new interrupt system is much more streamlined, easier to understand, debug,
+and it's also a bit faster - the same happened to it that will happen to
+cli()/sti() using drivers once they convert to spinlocks :-)
+
diff -Nru a/Documentation/fb/README-sstfb.txt b/Documentation/fb/README-sstfb.txt
--- a/Documentation/fb/README-sstfb.txt	Wed Jul 24 14:03:36 2002
+++ b/Documentation/fb/README-sstfb.txt	Wed Jul 24 14:03:36 2002
@@ -9,12 +9,12 @@
 	combinations and it seems that it works.
 	  The main page is located at <http://sstfb.sourceforge.net>, and if
 	you want the latest version, check out the CVS, as the driver is a work
-	in progress, i feel incomfortable with releasing tarballs of something
+	in progress, I feel uncomfortable with releasing tarballs of something
 	not completely working...Don't worry, it's still more than useable
 	(I eat my own dog food)
 
 	  Please read the Bug section, and report any success or failure to me
-	(Ghozlane Toumi <gtoumi@messel.emse.fr>).
+	(Ghozlane Toumi <gtoumi@laposte.net>).
 	  BTW, If you have only one monitor , and you don't feel like playing
 	with the vga passthrou cable, I can only suggest borrowing a screen
 	somewhere... 
@@ -22,8 +22,9 @@
 
 Installation 
 
-	  This driver (should) work on ix86, with any 2.2.x kernel (tested
+	  This driver (should) work on ix86, with "late" 2.2.x kernel (tested
 	with x = 19) and "recent" 2.4.x kernel, as a module or compiled in.
+	  It has been included in mainstream kernel since the infamous 2.4.10.
 	  You can apply the patches found in sstfb/kernel/*-2.{2|4}.x.patch,
 	and copy sstfb.c to linux/drivers/video/, or apply a single patch, 
 	sstfb/patch-2.{2|4}.x-sstfb-yymmdd to your linux source tree.
@@ -41,7 +42,7 @@
 	  module, the 3dfx takes control of the output, so you'll have to
 	  plug the monitor to the "normal" video board in order to issue
 	  the commands, or you can blindly use sst_dbg_vgapass
-          in the tools directory (See Tools). The latest option is pass the
+          in the tools directory (See Tools). The latest solution is pass the
 	  parameter vgapass=1 when insmodding the driver. (See Kernel/Modules
 	  Options)
 
@@ -77,36 +78,39 @@
 	in kernel :  video=sstfb:option1,option2:value2,option3 ...
 	
 	sstfb supports the folowing options :
-	module		kernel		description
 
-	vgapass=1	vgapass		enable or disable VGA passthrou cable
-	vgapass=0	vganopass	when enabled, the monitor will
-					get the signal from the VGA board
-					and not from the voodoo. default nopass
-
-	mem=x		mem:x		force frame buffer memory in MiB
-					allowed values: 1, 2, 4. default detect
-
-	inverse=1	inverse		suposed to enable inverse console.
-					doesn't work ...
-
-	clipping=1	clipping	enable or disable clipping . with
-	clipping=0	noclipping	clipping enabled, all offscreen reads
-					and writes are disgarded. default:
-					enable clipping.
-
-	gfxclk=x	gfxclk:x	force graphic clock frequency (in MHz)
-					becarefull with this option .
-					default is 50Mhz for voodoo1, 75MHz
-					for voodoo2. Be carefull, this one is
-					dangerous. default=auto
-
-	slowpci=0	slowpci		enable or disable fast PCI read/writes
-	slowpci=1	fastpci		default : fastpci
-
-	dev=x		dev:x		attach the driver to device number x
-					0 is the first compatible board (in 
-					lspci order)
+Module		Kernel		Description
+
+vgapass=0	vganopass	Enable or disable VGA passthrou cable.
+vgapass=1	vgapass		When enabled, the monitor will get the signal
+				from the VGA board and not from the voodoo.
+				Default: nopass
+
+mem=x		mem:x		Force frame buffer memory in MiB
+				allowed values: 0, 1, 2, 4.
+				Default: 0 (= autodetect)
+
+inverse=1	inverse		Supposed to enable inverse console.
+				doesn't work yet...
+
+clipping=1	clipping	Enable or disable clipping.
+clipping=0	noclipping	With clipping enabled, all offscreen
+				reads and writes are disgarded.
+				Default: enable clipping.
+
+gfxclk=x	gfxclk:x	Force graphic clock frequency (in MHz).
+				Be carefull with this option, it may be
+				DANGEROUS.
+				Default: auto 
+					50Mhz for Voodoo 1,
+					75MHz for Voodoo 2. 
+
+slowpci=1	fastpci		Enable or disable fast PCI read/writes.
+slowpci=1	slowpci		Default : fastpci
+
+dev=x		dev:x		Attach the driver to device number x.
+				0 is the first compatible board (in 
+				lspci order)
 
 Tools
 
@@ -126,8 +130,8 @@
 
 	- DO NOT use glide while the sstfb module is in, you'll most likely
 	hang your computer.
-	- if you see some artefacts (pixels not cleaning and stuff like that), 
-	try turning off clipping (clipping=0)
+	- If you see some artefacts (pixels not cleaning and stuff like that), 
+	try turning off clipping (clipping=0), and/or using slowpci
 	- the driver don't detect the 4Mb frame buffer voodoos, it seems that
 	the 2 last Mbs wrap around. looking into that .
 	- The driver is 16 bpp only, 24/32 won't work.
@@ -137,8 +141,8 @@
 	patterns at the border of your windows (the pixels loose the lowest
 	byte -> basicaly the blue component nd some of the green) . I'm unable
 	to reproduce this with XFree86-3.3, but one of the testers has this
-	problem with XFree86-4. I don't know yet if this is the drivers fault
-	or X's (most likely the driver, of course).
+	problem with XFree86-4. apparently recent Xfree86-4.x solve this
+	problem.
 	- I didn't really test changing the palette, so you may find some weird
 	things when playing with that.
 	- Sometimes the driver will not recognise the DAC , and the
@@ -147,6 +151,9 @@
 	contact me .
 	- the 24/32 is not likely to work anytime soon , knowing that the
 	hardware does ... unusual thigs in 24/32 bpp
+	- When used with anther video board, current limitations of linux
+	console subsystem can cause some troubles, specificaly, you should
+	disable software scrollback , as it can oops badly ...
 
 Todo
 
@@ -154,14 +161,14 @@
 	- Buy more coffee.
 	- test/port to other arch.
 	- try to add panning using tweeks with front and back buffer .
-	- try to implement accel en voodoo2 , this board can actualy do a 
+	- try to implement accel on voodoo2 , this board can actualy do a 
 	  lot in 2D even if it was sold as a 3D only board ...
 
 ghoz.
 
 -- 
-Ghozlane Toumi <gtoumi@messel.emse.fr>
+Ghozlane Toumi <gtoumi@laposte.net>
 
 
-$Date: 2001/08/29 00:21:11 $
+$Date: 2002/05/09 20:11:45 $
 http://sstfb.sourceforge.net/README
diff -Nru a/Documentation/filesystems/devfs/ChangeLog b/Documentation/filesystems/devfs/ChangeLog
--- a/Documentation/filesystems/devfs/ChangeLog	Wed Jul 24 14:03:36 2002
+++ b/Documentation/filesystems/devfs/ChangeLog	Wed Jul 24 14:03:36 2002
@@ -1931,3 +1931,13 @@
 
 - Protected <scan_dir_for_removable> and <get_removable_partition>
   from changing directory contents
+===============================================================================
+Changes for patch v214
+
+- Switched to ISO C structure field initialisers
+
+- Switch to set_current_state() and move before add_wait_queue()
+
+- Updated README from master HTML file
+
+- Fixed devfs entry leak in <devfs_readdir> when *readdir fails
diff -Nru a/Documentation/filesystems/devfs/README b/Documentation/filesystems/devfs/README
--- a/Documentation/filesystems/devfs/README	Wed Jul 24 14:03:37 2002
+++ b/Documentation/filesystems/devfs/README	Wed Jul 24 14:03:37 2002
@@ -3,7 +3,7 @@
 
 Linux Devfs (Device File System) FAQ
 Richard Gooch
-7-APR-2002
+21-JUL-2002
 
 
 Document languages:
@@ -788,6 +788,9 @@
 make sure the kernel does not mount devfs at boot time
 
 
+make sure you have a correct /dev/console entry in your
+root file-system (where your disc-based /dev lives)
+
 create the /dev-state directory
 
 
@@ -1288,9 +1291,10 @@
 
 SCSI Generic Devices
 
-All SCSI CD-ROMs are placed under /dev/sg. A similar naming
-scheme is used as for SCSI discs. A SCSI generic device with the
-parameters:c=1,b=2,t=3,u=4 would appear as:
+The generic (aka. raw) interface for all SCSI devices are placed under
+/dev/sg. A similar naming scheme is used as for SCSI discs. A
+SCSI generic device with the parameters:c=1,b=2,t=3,u=4 would appear
+as:
 
 	/dev/sg/c1b2t3u4
 
@@ -1603,6 +1607,23 @@
 then mount(8) will fail to find devices. The solution is to
 make sure that devfs is mounted on /dev. See above for how to
 do that.
+
+
+I have extra or incorrect entries in /dev
+
+You may have stale entries in your dev-state area. Check for a
+RESTORE configuration line in your devfsd configuration
+(typically /etc/devfsd.conf). If you have this line, check
+the contents of the specified directory for stale entries. Remove
+any entries which are incorrect, then reboot.
+
+
+I get "Unable to open initial console" messages at boot
+
+This usually happens when you don't have devfs automounted onto
+/dev at boot time, and there is no valid
+/dev/console entry on your root file-system. Create a valid
+/dev/console device node.
 
 
 
diff -Nru a/Documentation/filesystems/jfs.txt b/Documentation/filesystems/jfs.txt
--- a/Documentation/filesystems/jfs.txt	Wed Jul 24 14:03:38 2002
+++ b/Documentation/filesystems/jfs.txt	Wed Jul 24 14:03:38 2002
@@ -1,136 +1,38 @@
-IBM's Journaled File System (JFS) for Linux version 1.0.15
+IBM's Journaled File System (JFS) for Linux
+
+JFS Homepage:  http://oss.software.ibm.com/jfs/
+
 Team members
+------------
 Steve Best         sbest@us.ibm.com
 Dave Kleikamp      shaggy@austin.ibm.com  
 Barry Arndt        barndt@us.ibm.com
-Christoph Hellwig  hch@caldera.de
-
-
-Release February 15, 2002 (version 1.0.15)
-
-This is our fifty-third release of IBM's Enterprise JFS technology port to Linux.
-Beta 1 was release 0.1.0 on 12/8/2000, Beta 2 was release 0.2.0 on 3/7/2001, 
-Beta 3 was release 0.3.0 on 4/30/2001, and release 1.0.0 on 6/28/2001.
- 
-The changelog.jfs file contains detailed information of changes done in each source
-code drop.
-
-JFS has a source tree that can be built on 2.4.3 - 2.4.17 and 2.5.4 kernel.org
-source trees.
- 
-Our current goal on the 2.5.x series of the kernel is to update to the latest 
-2.5.x version and only support the latest version of this kernel.
-This will change when the distros start shipping the 2.5.x series of the kernel.
-
-Our current goal on the 2.4.x series of the kernel is to continue to support
-all of the kernels in this series as we do today.
-
-There is an anonymous cvs access available for the JFS tree. The steps below are
-what is needed to pull the JFS cvs tree from the oss.software.ibm.com server.
-
-id anoncvs
-password anoncvs
-
-To checkout 2.4.x series of the JFS files do the following:
-CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
-cvs checkout linux24
-
-To checkout 2.5.2 series of the JFS files do the following:
-CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
-cvs checkout linux25
-
-To checkout the JFS utilities do the following:
-CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
-cvs checkout jfsutils
-
-The cvs tree contains the latest changes being done to JFS. To receive notification
-of commits to the cvs tree, please send e-mail to linuxjfs@us.ibm.com stating that 
-you would like notifications sent to you. 
-
-The jfs-2.4-1.0.15-patch.tar.gz is the easiest way to get the latest file system
-source code on your system. There are also patch files that can move your jfs source
-code from one release to another. If you have release 1.0.14 and would like to move
-to release 1.0.15 the patch file named jfs-2.4-1_0_14-to-1_0_15-patch.gz will do that.
-
-The jfs-2.4-1.0.15-patch.tar.gz file contains a readme and patch files for different
-levels of the 2.4 kernel. Please see the README in the jfs-2.4-1.0.15-patch.tar.gz
-file for help on applying the two patch files. 
-
-
-The following files in the kernel source tree have been changed so JFS can be built.
-The jfs-2.4-1.0.15.tar.gz source tar ball contains each of the files below with
-the extension of the kernel level it is associated with. As an example, there are now
-four Config.in files named Config.in-2.4.0, Config.in-2.4.5, Config.in-2.4.7 and 
-Config.in-2.4.17.
-
-
-If you use the jfs-2.4-1.0.15.tar.gz to build JFS you must rename each of the 
-kernel files to the file names listed below. The standard kernel from www.kernel.org 
-is the source of the kernel files that are included in the jfs tar file. 
-
-
-In sub dir fs Config.in, Makefile
-In sub dir fs/nls Config.in
-In sub dir Documentation Configure.help, Changes
-In sub dir Documentation/filesystems 00-INDEX
-In sub dir linux MAINTAINERS
+Christoph Hellwig  hch@infradead.org
 
-Please backup the above files before the JFS tar file is added to the kernel source 
-tree. All JFS files are located in the include/linux/jfs or fs/jfs sub dirs.
+The following mount options are supported:
 
-Our development team has used the Linux kernel levels  2.4.3 - 2.4.17 kernels
-with gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) 
-for our port so far. A goal of the JFS team is to have JFS run on all architectures
-that Linux supports, there is no architecture specific code in JFS. JFS has been run
-on the following architectures (x86, PowerPC, Alpha, s/390, ARM) so far. 
-
-To make JFS build, during the "make config" step of building the kernel answer y to
-the Prompt for development and/or incomplete code/drivers in the Code maturity level
-options section. In the Filesystems section use the m for the answer to 
-JFS filesystem support (experimental) (CONFIG_JFS_FS) [Y/m/n?]
- 
-
-Build in /usr/src/linux with the command:
-
-
-make modules
-make modules_install
-
-If you rebuild jfs.o after having mounted and unmounted a partition, "modprobe -r jfs" 
-will unload the old module.
-
-For the file system debugging messages are being written to /var/log/messages.
-
-Please see the readme in the utilities package for information about building
-the JFS utilities.
+iocharset=name	Character set to use for converting from Unicode to
+		ASCII.  The default is compiled into the kernel as
+		CONFIG_NLS_DEFAULT.  Use iocharset=utf8 for UTF8
+		translations.  This requires CONFIG_NLS_UTF8 to be set
+		in the kernel .config file.
 
 JFS TODO list:
 
 Plans for our near term development items
 
-   - get defrag capabilities operational in the FS
-   - get extendfs capabilities operational in the FS
-   - test EXTENDFS utility, for growing JFS partitions
-   - test defrag utility, calls file system to defrag the file system.
-   - add support for block sizes (512,1024,2048)
-   - add support for logfile on dedicated partition
+   - implement online resize for extending JFS volumes
+   - enhance support for logfile on dedicated partition
+   - get access control list functionality operational
+   - get extended attributes functionality operational
 
-   
 Longer term work items
 
-   - get access control list functionality operational
-   - get extended attributes functionality operational
+   - implement defrag utility, for online defragmenting
    - add quota support
+   - add support for block sizes (512,1024,2048)
 
 Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com.
 
-The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe"
-at our web page http://oss.software.ibm.com/jfs/.
-
-
-
-
-
-
-
-
+The JFS mailing list can be subscribed to by using the link labeled
+"Mail list Subscribe" at our web page http://oss.software.ibm.com/jfs/.
diff -Nru a/Documentation/preempt-locking.txt b/Documentation/preempt-locking.txt
--- a/Documentation/preempt-locking.txt	Wed Jul 24 14:03:35 2002
+++ b/Documentation/preempt-locking.txt	Wed Jul 24 14:03:35 2002
@@ -70,7 +70,8 @@
 preempt_enable()		decrement the preempt counter
 preempt_disable()		increment the preempt counter
 preempt_enable_no_resched()	decrement, but do not immediately preempt
-preempt_get_count()		return the preempt counter
+preempt_check_resched()		if needed, reschedule
+preempt_count()			return the preempt counter
 
 The functions are nestable.  In other words, you can call preempt_disable
 n-times in a code path, and preemption will not be reenabled until the n-th
@@ -80,6 +81,13 @@
 Note that you do not need to explicitly prevent preemption if you are holding
 any locks or interrupts are disabled, since preemption is implicitly disabled
 in those cases.
+
+But keep in mind that 'irqs disabled' is a fundamentally unsafe way of
+disabling preemption - any spin_unlock() decreasing the preemption count
+to 0 might trigger a reschedule. A simple printk() might trigger a reschedule.
+So use this implicit preemption-disabling property only if you know that the
+affected codepath does not do any of this. Best policy is to use this only for
+small, atomic code that you wrote and which calls no complex functions.
 
 Example:
 
diff -Nru a/Documentation/s390/cds.txt b/Documentation/s390/cds.txt
--- a/Documentation/s390/cds.txt	Wed Jul 24 14:03:36 2002
+++ b/Documentation/s390/cds.txt	Wed Jul 24 14:03:36 2002
@@ -885,8 +885,8 @@
 
 Prior to call do_IO() the device driver must assure disabled state, i.e. the 
 I/O mask value in the PSW must be disabled. This can be accomplished by calling 
-__save_flags( flags). The current PSW flags are preserved and can be restored 
-by __restore_flags( flags) at a later time.
+local_save_flags( flags). The current PSW flags are preserved and can be restored 
+by local_irq_restore( flags) at a later time.
 
 If the device driver violates this rule while running in a uni-processor
 environment an interrupt might be presented prior to the do_IO() routine
diff -Nru a/Documentation/serial/driver b/Documentation/serial/driver
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/serial/driver	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,300 @@
+
+			Low Level Serial API
+			--------------------
+
+
+   $Id: driver,v 1.10 2002/07/22 15:27:30 rmk Exp $
+
+
+This document is meant as a brief overview of some aspects of the new serial
+driver.  It is not complete, any questions you have should be directed to
+<rmk@arm.linux.org.uk>
+
+The reference implementation is contained within serial_amba.c.
+
+
+
+Low Level Serial Hardware Driver
+--------------------------------
+
+The low level serial hardware driver is responsible for supplying port
+information (defined by uart_port) and a set of control methods (defined
+by uart_ops) to the core serial driver.  The low level driver is also
+responsible for handling interrupts for the port, and providing any
+console support.
+
+
+Console Support
+---------------
+
+The serial core provides a few helper functions.  This includes identifing
+the correct port structure (via uart_get_console) and decoding command line
+arguments (uart_parse_options).
+
+
+Locking
+-------
+
+It is the responsibility of the low level hardware driver to perform the
+necessary locking using port->lock.  There are some exceptions (which
+are described in the uart_ops listing below.)
+
+There are three locks.  A per-port spinlock, a per-port tmpbuf semaphore,
+and an overall semaphore.
+
+From the core driver perspective, the port->lock locks the following
+data:
+
+	port->mctrl
+	port->icount
+	info->xmit.head (circ->head)
+	info->xmit.tail (circ->tail)
+
+The low level driver is free to use this lock to provide any additional
+locking.
+
+The core driver uses the info->tmpbuf_sem lock to prevent multi-threaded
+access to the info->tmpbuf bouncebuffer used for port writes.
+
+The port_sem semaphore is used to protect against ports being added/
+removed or reconfigured at inappropriate times.
+
+
+uart_ops
+--------
+
+The uart_ops structure is the main interface between serial_core and the
+hardware specific driver.  It contains all the methods to control the
+hardware.
+
+  tx_empty(port)
+	This function tests whether the transmitter fifo and shifter
+	for the port described by 'port' is empty.  If it is empty,
+	this function should return TIOCSER_TEMT, otherwise return 0.
+	If the port does not support this operation, then it should
+	return TIOCSER_TEMT.
+
+	Locking: none.
+	Interrupts: caller dependent.
+	This call must not sleep
+
+  set_mctrl(port, mctrl)
+	This function sets the modem control lines for port described
+	by 'port' to the state described by mctrl.  The relevant bits
+	of mctrl are:
+		- TIOCM_RTS	RTS signal.
+		- TIOCM_DTR	DTR signal.
+		- TIOCM_OUT1	OUT1 signal.
+		- TIOCM_OUT2	OUT2 signal.
+	If the appropriate bit is set, the signal should be driven
+	active.  If the bit is clear, the signal should be driven
+	inactive.
+
+	Locking: port->lock taken.
+	Interrupts: locally disabled.
+	This call must not sleep
+
+  get_mctrl(port)
+	Returns the current state of modem control inputs.  The state
+	of the outputs should not be returned, since the core keeps
+	track of their state.  The state information should include:
+		- TIOCM_DCD	state of DCD signal
+		- TIOCM_CTS	state of CTS signal
+		- TIOCM_DSR	state of DSR signal
+		- TIOCM_RI	state of RI signal
+	The bit is set if the signal is currently driven active.  If
+	the port does not support CTS, DCD or DSR, the driver should
+	indicate that the signal is permanently active.  If RI is
+	not available, the signal should not be indicated as active.
+
+	Locking: none.
+	Interrupts: caller dependent.
+	This call must not sleep
+
+  stop_tx(port,tty_stop)
+	Stop transmitting characters.  This might be due to the CTS
+	line becoming inactive or the tty layer indicating we want
+	to stop transmission.
+
+	tty_stop: 1 if this call is due to the TTY layer issuing a
+	          TTY stop to the driver (equiv to rs_stop).
+
+	Locking: port->lock taken.
+	Interrupts: caller dependent.
+	This call must not sleep
+
+  start_tx(port,tty_start)
+	start transmitting characters.  (incidentally, nonempty will
+	always be nonzero, and shouldn't be used - it will be dropped).
+
+	tty_start: 1 if this call was due to the TTY layer issuing
+	           a TTY start to the driver (equiv to rs_start)
+
+	Locking: port->lock taken.
+	Interrupts: locally disabled.
+	This call must not sleep
+
+  stop_rx(port)
+	Stop receiving characters; the port is in the process of
+	being closed.
+
+	Locking: none.
+	Interrupts: caller dependent.
+	This call must not sleep
+
+  enable_ms(port)
+	Enable the modem status interrupts.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  break_ctl(port,ctl)
+	Control the transmission of a break signal.  If ctl is
+	nonzero, the break signal should be transmitted.  The signal
+	should be terminated when another call is made with a zero
+	ctl.
+
+	Locking: none.
+	Interrupts: caller dependent.
+	This call must not sleep
+
+  startup(port)
+	Grab any interrupt resources and initialise any low level driver
+	state.  Enable the port for reception.  It should not activate
+	RTS nor DTR; this will be done via a separate call to set_mctrl.
+
+	Locking: port_sem taken.
+	Interrupts: globally disabled.
+
+  shutdown(port)
+	Disable the port, disable any break condition that may be in
+	effect, and free any interrupt resources.  It should not disable
+	RTS nor DTR; this will have already been done via a separate
+	call to set_mctrl.
+
+	Locking: port_sem taken.
+	Interrupts: caller dependent.
+
+  change_speed(port,cflag,iflag,quot)
+	Change the port parameters, including word length, parity, stop
+	bits.  Update read_status_mask and ignore_status_mask to indicate
+	the types of events we are interested in receiving.  Relevant
+	cflag bits are:
+		CSIZE	- word size
+		CSTOPB	- 2 stop bits
+		PARENB	- parity enable
+		PARODD	- odd parity (when PARENB is in force)
+		CREAD	- enable reception of characters (if not set,
+			  still receive characters from the port, but
+			  throw them away.
+		CRTSCTS	- if set, enable CTS status change reporting
+		CLOCAL	- if not set, enable modem status change
+			  reporting.
+	Relevant iflag bits are:
+		INPCK	- enable frame and parity error events to be
+			  passed to the TTY layer.
+		BRKINT
+		PARMRK	- both of these enable break events to be
+			  passed to the TTY layer.
+
+		IGNPAR	- ignore parity and framing errors
+		IGNBRK	- ignore break errors,  If IGNPAR is also
+			  set, ignore overrun errors as well.
+	The interaction of the iflag bits is as follows (parity error
+	given as an example):
+	Parity error	INPCK	IGNPAR
+	None		n/a	n/a	character received
+	Yes		n/a	0	character discarded
+	Yes		0	1	character received, marked as
+					TTY_NORMAL
+	Yes		1	1	character received, marked as
+					TTY_PARITY
+
+	Locking: none.
+	Interrupts: caller dependent.
+	This call must not sleep
+
+  pm(port,state,oldstate)
+	perform any power management related activities on the specified
+	port.  state indicates the new state (defined by ACPI D0-D3),
+	oldstate indicates the previous state.  Essentially, D0 means
+	fully on, D3 means powered down.
+
+	This function should not be used to grab any resources.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  type(port)
+	Return a pointer to a string constant describing the specified
+	port, or return NULL, in which case the string 'unknown' is
+	substituted.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  release_port(port)
+	Release any memory and IO region resources currently in use by
+	the port.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  request_port(port)
+	Request any memory and IO region resources required by the port.
+	If any fail, no resources should be registered when this function
+	returns, and it should return -EBUSY on failure.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  config_port(port,type)
+	Perform any autoconfiguration steps required for the port.  `type`
+	contains a bit mask of the required configuration.  UART_CONFIG_TYPE
+	indicates that the port requires detection and identification.
+	port->type should be set to the type found, or PORT_UNKNOWN if
+	no port was detected.
+
+	UART_CONFIG_IRQ indicates autoconfiguration of the interrupt signal,
+	which should be probed using standard kernel autoprobing techniques.
+	This is not necessary on platforms where ports have interrupts
+	internally hard wired (eg, system on a chip implementations).
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  verify_port(port,serinfo)
+	Verify the new serial port information contained within serinfo is
+	suitable for this port type.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  ioctl(port,cmd,arg)
+	Perform any port specific IOCTLs.  IOCTL commands must be defined
+	using the standard numbering system found in <asm/ioctl.h>
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+
+Other notes
+-----------
+
+It is intended some day to drop the 'unused' entries from uart_port, and
+allow low level drivers to register their own individual uart_port's with
+the core.  This will allow drivers to use uart_port as a pointer to a
+structure containing both the uart_port entry with their own extensions,
+thus:
+
+	struct my_port {
+		struct uart_port	port;
+		int			my_stuff;
+	};
+
+Todo
+----
+
+Please see the BUGS file in CVS at
+
+	http://cvs.arm.linux.org.uk/cgi/viewcvs.cgi/serial/BUGS
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Wed Jul 24 14:03:36 2002
+++ b/Makefile	Wed Jul 24 14:03:36 2002
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 27
+SUBLEVEL = 28
 EXTRAVERSION =
 
 # *DOCUMENTATION*
@@ -212,7 +212,7 @@
 
 CPPFLAGS := -D__KERNEL__ -I$(HPATH)
 
-CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
+CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -g \
 	  -fomit-frame-pointer -fno-strict-aliasing -fno-common
 AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
 
diff -Nru a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c
--- a/arch/alpha/kernel/core_apecs.c	Wed Jul 24 14:03:37 2002
+++ b/arch/alpha/kernel/core_apecs.c	Wed Jul 24 14:03:37 2002
@@ -131,7 +131,7 @@
 	unsigned int stat0, value;
 	unsigned int haxr2 = 0;
 
-	__save_and_cli(flags);	/* avoid getting hit by machine check */
+	local_irq_save(flags);	/* avoid getting hit by machine check */
 
 	DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
 
@@ -201,7 +201,7 @@
 		*(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
 		mb();
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return value;
 }
@@ -213,7 +213,7 @@
 	unsigned int stat0;
 	unsigned int haxr2 = 0;
 
-	__save_and_cli(flags);	/* avoid getting hit by machine check */
+	local_irq_save(flags);	/* avoid getting hit by machine check */
 
 	/* Reset status register to avoid losing errors.  */
 	stat0 = *(vuip)APECS_IOC_DCSR;
@@ -269,7 +269,7 @@
 		*(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
 		mb();
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static int
diff -Nru a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
--- a/arch/alpha/kernel/core_cia.c	Wed Jul 24 14:03:38 2002
+++ b/arch/alpha/kernel/core_cia.c	Wed Jul 24 14:03:38 2002
@@ -113,7 +113,7 @@
 	int cia_cfg = 0;
 
 	DBGC(("conf_read(addr=0x%lx, type1=%d) ", addr, type1));
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Reset status register to avoid losing errors.  */
 	stat0 = *(vip)CIA_IOC_CIA_ERR;
@@ -154,7 +154,7 @@
 		*(vip)CIA_IOC_CFG;
 	}
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	DBGC(("done\n"));
 
 	return value;
@@ -167,7 +167,7 @@
 	int stat0, cia_cfg = 0;
 
 	DBGC(("conf_write(addr=0x%lx, type1=%d) ", addr, type1));
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Reset status register to avoid losing errors.  */
 	stat0 = *(vip)CIA_IOC_CIA_ERR;
@@ -204,7 +204,7 @@
 		*(vip)CIA_IOC_CFG;
 	}
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	DBGC(("done\n"));
 }
 
diff -Nru a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c
--- a/arch/alpha/kernel/core_lca.c	Wed Jul 24 14:03:37 2002
+++ b/arch/alpha/kernel/core_lca.c	Wed Jul 24 14:03:37 2002
@@ -132,7 +132,7 @@
 	unsigned long flags, code, stat0;
 	unsigned int value;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Reset status register to avoid loosing errors.  */
 	stat0 = *(vulp)LCA_IOC_STAT0;
@@ -160,7 +160,7 @@
 
 		value = 0xffffffff;
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	return value;
 }
 
@@ -169,7 +169,7 @@
 {
 	unsigned long flags, code, stat0;
 
-	__save_and_cli(flags);	/* avoid getting hit by machine check */
+	local_irq_save(flags);	/* avoid getting hit by machine check */
 
 	/* Reset status register to avoid loosing errors.  */
 	stat0 = *(vulp)LCA_IOC_STAT0;
@@ -195,7 +195,7 @@
 		/* Reset machine check. */
 		wrmces(0x7);
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static int
diff -Nru a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
--- a/arch/alpha/kernel/core_mcpcia.c	Wed Jul 24 14:03:35 2002
+++ b/arch/alpha/kernel/core_mcpcia.c	Wed Jul 24 14:03:35 2002
@@ -97,7 +97,7 @@
 
 	cpu = smp_processor_id();
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n",
 		 addr, type1, mid));
@@ -131,7 +131,7 @@
 
 	DBG_CFG(("conf_read(): finished\n"));
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	return value;
 }
 
@@ -145,7 +145,7 @@
 
 	cpu = smp_processor_id();
 
-	__save_and_cli(flags);	/* avoid getting hit by machine check */
+	local_irq_save(flags);	/* avoid getting hit by machine check */
 
 	/* Reset status register to avoid losing errors.  */
 	stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
@@ -167,7 +167,7 @@
 	mb();
 
 	DBG_CFG(("conf_write(): finished\n"));
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static int
diff -Nru a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c
--- a/arch/alpha/kernel/core_t2.c	Wed Jul 24 14:03:35 2002
+++ b/arch/alpha/kernel/core_t2.c	Wed Jul 24 14:03:35 2002
@@ -132,7 +132,7 @@
 
 	cpu = smp_processor_id();
 
-	__save_and_cli(flags);	/* avoid getting hit by machine check */
+	local_irq_save(flags);	/* avoid getting hit by machine check */
 
 	DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
 
@@ -181,7 +181,7 @@
 	}
 	DBG(("conf_read(): finished\n"));
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	return value;
 }
 
@@ -194,7 +194,7 @@
 
 	cpu = smp_processor_id();
 
-	__save_and_cli(flags);	/* avoid getting hit by machine check */
+	local_irq_save(flags);	/* avoid getting hit by machine check */
 
 #if 0
 	{
@@ -234,7 +234,7 @@
 		mb();
 	}
 	DBG(("conf_write(): finished\n"));
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static int
diff -Nru a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
--- a/arch/alpha/kernel/irq.c	Wed Jul 24 14:03:39 2002
+++ b/arch/alpha/kernel/irq.c	Wed Jul 24 14:03:39 2002
@@ -85,9 +85,9 @@
 
 	do {
 		if (!(action->flags & SA_INTERRUPT))
-			__sti();
+			local_irq_enable();
 		else
-			__cli();
+			local_irq_disable();
 
 		status |= action->flags;
 		action->handler(irq, action->dev_id, regs);
@@ -95,7 +95,7 @@
 	} while (action);
 	if (status & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	__cli();
+	local_irq_disable();
 
 	irq_exit(cpu, irq);
 
diff -Nru a/arch/alpha/kernel/irq_smp.c b/arch/alpha/kernel/irq_smp.c
--- a/arch/alpha/kernel/irq_smp.c	Wed Jul 24 14:03:35 2002
+++ b/arch/alpha/kernel/irq_smp.c	Wed Jul 24 14:03:35 2002
@@ -85,9 +85,9 @@
 				show("wait_on_irq", where);
 				count = MAXCOUNT;
 			}
-			__sti();
+			local_irq_enable();
 			udelay(1); /* make sure to run pending irqs */
-			__cli();
+			local_irq_disable();
 
 			if (irqs_running())
 				continue;
@@ -153,7 +153,7 @@
 
         if (!local_irq_count(cpu))
 		release_irqlock(cpu);
-	__sti();
+	local_irq_enable();
 }
 
 /*
@@ -171,7 +171,7 @@
         unsigned long flags;
 	int cpu = smp_processor_id();
 
-        __save_flags(flags);
+        local_save_flags(flags);
         local_enabled = (!(flags & 7));
         /* default to local */
         retval = 2 + local_enabled;
@@ -197,10 +197,10 @@
                 __global_sti();
                 break;
         case 2:
-                __cli();
+                local_irq_disable();
                 break;
         case 3:
-                __sti();
+                local_irq_enable();
                 break;
         default:
                 printk(KERN_ERR "global_restore_flags: %08lx (%p)\n",
diff -Nru a/arch/alpha/kernel/ns87312.c b/arch/alpha/kernel/ns87312.c
--- a/arch/alpha/kernel/ns87312.c	Wed Jul 24 14:03:37 2002
+++ b/arch/alpha/kernel/ns87312.c	Wed Jul 24 14:03:37 2002
@@ -28,11 +28,11 @@
 	int data;
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	outb(0, ide_base);		/* set the index register for reg #0 */
 	data = inb(ide_base+1);		/* read the current contents */
 	outb(0, ide_base);		/* set the index register for reg #0 */
 	outb(data | 0x40, ide_base+1);	/* turn on IDE */
 	outb(data | 0x40, ide_base+1);	/* turn on IDE, really! */
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
diff -Nru a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
--- a/arch/alpha/kernel/process.c	Wed Jul 24 14:03:37 2002
+++ b/arch/alpha/kernel/process.c	Wed Jul 24 14:03:37 2002
@@ -88,7 +88,7 @@
 	int cpuid = smp_processor_id();
 
 	/* No point in taking interrupts anymore. */
-	__cli();
+	local_irq_disable();
 
 	cpup = (struct percpu_struct *)
 			((unsigned long)hwrpb + hwrpb->processor_offset
diff -Nru a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c
--- a/arch/alpha/kernel/smc37c669.c	Wed Jul 24 14:03:38 2002
+++ b/arch/alpha/kernel/smc37c669.c	Wed Jul 24 14:03:38 2002
@@ -2486,7 +2486,7 @@
     SMC37c669_CONFIG_REGS *SMC_base;
     unsigned long flags;
 
-    __save_and_cli(flags);
+    local_irq_save(flags);
     if ( ( SMC_base = SMC37c669_detect( index ) ) != NULL ) {
 #if SMC_DEBUG
 	SMC37c669_config_mode( TRUE );
@@ -2541,12 +2541,12 @@
 	SMC37c669_config_mode( FALSE );
         SMC37c669_display_device_info( );
 #endif
-	__restore_flags(flags);
+	local_irq_restore(flags);
         printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n",
 		(unsigned long) SMC_base );
     }
     else {
-	__restore_flags(flags);
+	local_irq_restore(flags);
 #if SMC_DEBUG
         printk( "No SMC37c669 Super I/O Controller found\n" );
 #endif
diff -Nru a/arch/alpha/kernel/smc37c93x.c b/arch/alpha/kernel/smc37c93x.c
--- a/arch/alpha/kernel/smc37c93x.c	Wed Jul 24 14:03:38 2002
+++ b/arch/alpha/kernel/smc37c93x.c	Wed Jul 24 14:03:38 2002
@@ -243,7 +243,7 @@
 	unsigned long SMCUltraBase;
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	if ((SMCUltraBase = SMCDetectUltraIO()) != 0UL) {
 #if SMC_DEBUG
 		SMCReportDeviceStatus(SMCUltraBase);
@@ -264,13 +264,13 @@
 		SMCReportDeviceStatus(SMCUltraBase);
 #endif
 		SMCRunState(SMCUltraBase);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 		printk("SMC FDC37C93X Ultra I/O Controller found @ 0x%lx\n",
 		       SMCUltraBase);
 		return 1;
 	}
 	else {
-		__restore_flags(flags);
+		local_irq_restore(flags);
 		DBG_DEVS(("No SMC FDC37C93X Ultra I/O Controller found\n"));
 		return 0;
 	}
diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
--- a/arch/alpha/kernel/smp.c	Wed Jul 24 14:03:37 2002
+++ b/arch/alpha/kernel/smp.c	Wed Jul 24 14:03:37 2002
@@ -175,7 +175,7 @@
 	current->active_mm = &init_mm;
 
 	/* Must have completely accurate bogos.  */
-	__sti();
+	local_irq_enable();
 
 	/* Wait boot CPU to stop with irq enabled before running
 	   calibrate_delay. */
diff -Nru a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
--- a/arch/arm/kernel/irq.c	Wed Jul 24 14:03:35 2002
+++ b/arch/arm/kernel/irq.c	Wed Jul 24 14:03:35 2002
@@ -190,7 +190,7 @@
 	spin_unlock(&irq_controller_lock);
 
 	if (!(action->flags & SA_INTERRUPT))
-		__sti();
+		local_irq_enable();
 
 	status = 0;
 	do {
diff -Nru a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
--- a/arch/cris/kernel/irq.c	Wed Jul 24 14:03:39 2002
+++ b/arch/cris/kernel/irq.c	Wed Jul 24 14:03:39 2002
@@ -266,7 +266,7 @@
 	action = irq_action[irq];
         if (action) {
                 if (!(action->flags & SA_INTERRUPT))
-                        __sti();
+                        local_irq_enable();
                 action = irq_action[irq];
                 do_random = 0;
                 do {
@@ -276,7 +276,7 @@
                 } while (action);
                 if (do_random & SA_SAMPLE_RANDOM)
                         add_interrupt_randomness(irq);
-                __cli();
+                local_irq_disable();
         }
         irq_exit(cpu);
 
diff -Nru a/arch/i386/boot/video.S b/arch/i386/boot/video.S
--- a/arch/i386/boot/video.S	Wed Jul 24 14:03:36 2002
+++ b/arch/i386/boot/video.S	Wed Jul 24 14:03:36 2002
@@ -96,7 +96,7 @@
 #define PARAM_VESAPM_SEG	0x2e
 #define PARAM_VESAPM_OFF	0x30
 #define PARAM_LFB_PAGES		0x32
-
+#define PARAM_VESA_ATTRIB	0x34
 
 /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
 #ifdef CONFIG_VIDEO_RETAIN
@@ -221,6 +221,8 @@
 	movl	%eax, %fs:(PARAM_LFB_COLORS)
 	movl	35(%di), %eax
 	movl	%eax, %fs:(PARAM_LFB_COLORS+4)
+	movw	0(%di), %ax
+	movw	%ax, %fs:(PARAM_VESA_ATTRIB)
 
 # get video mem size
 	leaw	modelist+1024, %di
diff -Nru a/arch/i386/config.in b/arch/i386/config.in
--- a/arch/i386/config.in	Wed Jul 24 14:03:37 2002
+++ b/arch/i386/config.in	Wed Jul 24 14:03:37 2002
@@ -185,10 +185,6 @@
 	 4GB           CONFIG_HIGHMEM4G \
 	 64GB          CONFIG_HIGHMEM64G" off
 
-if [ "$CONFIG_HIGHMEM4G" = "y" -o "$CONFIG_HIGHMEM64G" = "y" ]; then
-   bool 'Use high memory pte support' CONFIG_HIGHPTE
-fi
-
 if [ "$CONFIG_HIGHMEM4G" = "y" ]; then
    define_bool CONFIG_HIGHMEM y
 fi
diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
--- a/arch/i386/kernel/apic.c	Wed Jul 24 14:03:39 2002
+++ b/arch/i386/kernel/apic.c	Wed Jul 24 14:03:39 2002
@@ -485,13 +485,12 @@
 	apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
 	apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
 	
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 	disable_local_APIC();
 	rdmsr(MSR_IA32_APICBASE, l, h);
 	l &= ~MSR_IA32_APICBASE_ENABLE;
 	wrmsr(MSR_IA32_APICBASE, l, h);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void apic_pm_resume(void *data)
@@ -499,8 +498,7 @@
 	unsigned int l, h;
 	unsigned long flags;
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 	rdmsr(MSR_IA32_APICBASE, l, h);
 	l &= ~MSR_IA32_APICBASE_BASE;
 	l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
@@ -523,7 +521,7 @@
 	apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);
 	apic_write(APIC_ESR, 0);
 	apic_read(APIC_ESR);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	if (apic_pm_state.perfctr_pmdev)
 		pm_send(apic_pm_state.perfctr_pmdev, PM_RESUME, data);
 }
@@ -804,8 +802,8 @@
 	unsigned long flags;
 	int delta;
 
-	__save_flags(flags);
-	__sti();
+	local_save_flags(flags);
+	local_irq_enable();
 	/*
 	 * ok, Intel has some smart code in their APIC that knows
 	 * if a CPU was in 'hlt' lowpower mode, and this increases
@@ -842,7 +840,7 @@
 
 	printk("CPU%d<T0:%d,T1:%d,D:%d,S:%d,C:%d>\n", smp_processor_id(), t0, t1, delta, slice, clocks);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
@@ -935,7 +933,7 @@
 	printk("Using local APIC timer interrupts.\n");
 	using_apic_timer = 1;
 
-	__cli();
+	local_irq_disable();
 
 	calibration_result = calibrate_APIC_clock();
 	/*
@@ -943,7 +941,7 @@
 	 */
 	setup_APIC_timer((void *)calibration_result);
 
-	__sti();
+	local_irq_enable();
 
 	/* and update all other cpus */
 	smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1);
@@ -1084,12 +1082,9 @@
 	 * Besides, if we don't timer interrupts ignore the global
 	 * interrupt lock, which is the WrongThing (tm) to do.
 	 */
-	irq_enter(cpu, 0);
+	irq_enter();
 	smp_local_timer_interrupt(&regs);
-	irq_exit(cpu, 0);
-
-	if (softirq_pending(cpu))
-		do_softirq();
+	irq_exit();
 }
 
 /*
@@ -1099,6 +1094,7 @@
 {
 	unsigned long v;
 
+	irq_enter();
 	/*
 	 * Check if this really is a spurious interrupt and ACK it
 	 * if it is a vectored one.  Just in case...
@@ -1111,6 +1107,7 @@
 	/* see sw-dev-man vol 3, chapter 7.4.13.5 */
 	printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n",
 			smp_processor_id());
+	irq_exit();
 }
 
 /*
@@ -1121,6 +1118,7 @@
 {
 	unsigned long v, v1;
 
+	irq_enter();
 	/* First tickle the hardware, only then report what went on. -- REW */
 	v = apic_read(APIC_ESR);
 	apic_write(APIC_ESR, 0);
@@ -1140,6 +1138,7 @@
 	*/
 	printk (KERN_ERR "APIC error on CPU%d: %02lx(%02lx)\n",
 	        smp_processor_id(), v , v1);
+	irq_exit();
 }
 
 /*
diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
--- a/arch/i386/kernel/apm.c	Wed Jul 24 14:03:35 2002
+++ b/arch/i386/kernel/apm.c	Wed Jul 24 14:03:35 2002
@@ -222,6 +222,8 @@
 
 #include <linux/sysrq.h>
 
+extern rwlock_t xtime_lock;
+extern spinlock_t i8253_lock;
 extern unsigned long get_cmos_time(void);
 extern void machine_real_restart(unsigned char *, int);
 
@@ -512,9 +514,9 @@
  */
 #define APM_DO_CLI	\
 	if (apm_info.allow_ints) \
-		__sti(); \
+		local_irq_enable(); \
 	else \
-		__cli();
+		local_irq_disable();
 
 #ifdef APM_ZERO_SEGS
 #	define APM_DECL_SEGS \
@@ -568,7 +570,7 @@
 	APM_DECL_SEGS
 	unsigned long	flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	APM_DO_CLI;
 	APM_DO_SAVE_SEGS;
 	/*
@@ -588,7 +590,7 @@
 		: "a" (func), "b" (ebx_in), "c" (ecx_in)
 		: "memory", "cc");
 	APM_DO_RESTORE_SEGS;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	return *eax & 0xff;
 }
 
@@ -612,7 +614,7 @@
 	APM_DECL_SEGS
 	unsigned long	flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	APM_DO_CLI;
 	APM_DO_SAVE_SEGS;
 	{
@@ -636,7 +638,7 @@
 			: "memory", "cc");
 	}
 	APM_DO_RESTORE_SEGS;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	return error;
 }
 
@@ -1141,40 +1143,25 @@
 
 static void set_time(void)
 {
-	unsigned long	flags;
-
-	if (got_clock_diff) {	/* Must know time zone in order to set clock */
-		save_flags(flags);
-		cli();
+	if (got_clock_diff)	/* Must know time zone in order to set clock */
 		CURRENT_TIME = get_cmos_time() + clock_cmos_diff;
-		restore_flags(flags);
-	}
 }
 
 static void get_time_diff(void)
 {
 #ifndef CONFIG_APM_RTC_IS_GMT
-	unsigned long	flags;
-
 	/*
 	 * Estimate time zone so that set_time can update the clock
 	 */
-	save_flags(flags);
 	clock_cmos_diff = -get_cmos_time();
-	cli();
 	clock_cmos_diff += CURRENT_TIME;
 	got_clock_diff = 1;
-	restore_flags(flags);
 #endif
 }
 
-static void reinit_timer(void)
+static inline void reinit_timer(void)
 {
 #ifdef INIT_TIMER_AFTER_SUSPEND
-	unsigned long	flags;
-
-	save_flags(flags);
-	cli();
 	/* set the clock to 100 Hz */
 	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
 	udelay(10);
@@ -1182,7 +1169,6 @@
 	udelay(10);
 	outb(LATCH >> 8 , 0x40);	/* MSB */
 	udelay(10);
-	restore_flags(flags);
 #endif
 }
 
@@ -1203,13 +1189,21 @@
 		}
 		printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
 	}
+	/* serialize with the timer interrupt */
+	write_lock_irq(&xtime_lock);
+
+	/* protect against access to timer chip registers */
+	spin_lock(&i8253_lock);
+
 	get_time_diff();
-	cli();
 	err = set_system_power_state(APM_STATE_SUSPEND);
 	reinit_timer();
 	set_time();
 	ignore_normal_resume = 1;
-	sti();
+
+	spin_unlock(&i8253_lock);
+	write_unlock_irq(&xtime_lock);
+
 	if (err == APM_NO_ERROR)
 		err = APM_SUCCESS;
 	if (err != APM_SUCCESS)
@@ -1232,8 +1226,12 @@
 {
 	int	err;
 
+	/* serialize with the timer interrupt */
+	write_lock_irq(&xtime_lock);
 	/* If needed, notify drivers here */
 	get_time_diff();
+	write_unlock_irq(&xtime_lock);
+
 	err = set_system_power_state(APM_STATE_STANDBY);
 	if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
 		apm_error("standby", err);
@@ -1321,7 +1319,9 @@
 			ignore_bounce = 1;
 			if ((event != APM_NORMAL_RESUME)
 			    || (ignore_normal_resume == 0)) {
+				write_lock_irq(&xtime_lock);
 				set_time();
+				write_unlock_irq(&xtime_lock);
 				pm_send_all(PM_RESUME, (void *)0);
 				queue_event(event, NULL);
 			}
@@ -1336,7 +1336,9 @@
 			break;
 
 		case APM_UPDATE_TIME:
+			write_lock_irq(&xtime_lock);
 			set_time();
+			write_unlock_irq(&xtime_lock);
 			break;
 
 		case APM_CRITICAL_SUSPEND:
diff -Nru a/arch/i386/kernel/bluesmoke.c b/arch/i386/kernel/bluesmoke.c
--- a/arch/i386/kernel/bluesmoke.c	Wed Jul 24 14:03:37 2002
+++ b/arch/i386/kernel/bluesmoke.c	Wed Jul 24 14:03:37 2002
@@ -10,12 +10,15 @@
 #include <linux/config.h>
 #include <linux/irq.h>
 #include <linux/tqueue.h>
+#include <linux/interrupt.h>
+
 #include <asm/processor.h> 
 #include <asm/system.h>
 #include <asm/msr.h>
 #include <asm/apic.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
+#include <asm/hardirq.h>
 
 #ifdef CONFIG_X86_MCE
 
@@ -74,7 +77,9 @@
 
 asmlinkage void smp_thermal_interrupt(struct pt_regs regs)
 {
+	irq_enter();
 	vendor_thermal_interrupt(&regs);
+	irq_exit();
 }
 
 /* P4/Xeon Thermal regulation detect and init */
diff -Nru a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
--- a/arch/i386/kernel/cpu/common.c	Wed Jul 24 14:03:35 2002
+++ b/arch/i386/kernel/cpu/common.c	Wed Jul 24 14:03:35 2002
@@ -426,7 +426,7 @@
 
 	if (test_and_set_bit(nr, &cpu_initialized)) {
 		printk(KERN_WARNING "CPU#%d already initialized!\n", nr);
-		for (;;) __sti();
+		for (;;) local_irq_enable();
 	}
 	printk(KERN_INFO "Initializing CPU#%d\n", nr);
 
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S	Wed Jul 24 14:03:37 2002
+++ b/arch/i386/kernel/entry.S	Wed Jul 24 14:03:37 2002
@@ -72,12 +72,8 @@
 
 #ifdef CONFIG_PREEMPT
 #define preempt_stop		cli
-#define INC_PRE_COUNT(reg)	incl TI_PRE_COUNT(reg);
-#define DEC_PRE_COUNT(reg)	decl TI_PRE_COUNT(reg);
 #else
 #define preempt_stop
-#define INC_PRE_COUNT(reg)
-#define DEC_PRE_COUNT(reg)
 #define resume_kernel		restore_all
 #endif
 
@@ -189,10 +185,10 @@
 
 	# userspace resumption stub bypassing syscall exit tracing
 	ALIGN
-ret_from_intr:
-	preempt_stop
-	DEC_PRE_COUNT(%ebx)
 ret_from_exception:
+	preempt_stop
+ret_from_intr:
+	GET_THREAD_INFO(%ebx)
 	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
 	movb CS(%esp), %al
 	testl $(VM_MASK | 3), %eax
@@ -268,7 +264,7 @@
 
 work_notifysig:				# deal with pending signals and
 					# notify-resume requests
-	testl $(VM_MASK),EFLAGS(%esp)
+	testl $VM_MASK, EFLAGS(%esp)
 	movl %esp, %eax
 	jne work_notifysig_v86		# returning to kernel-space or
 					# vm86-space
@@ -338,8 +334,6 @@
 	ALIGN
 common_interrupt:
 	SAVE_ALL
-	GET_THREAD_INFO(%ebx)
-	INC_PRE_COUNT(%ebx)
 	call do_IRQ
 	jmp ret_from_intr
 
@@ -347,8 +341,6 @@
 ENTRY(name)				\
 	pushl $nr-256;			\
 	SAVE_ALL			\
-	GET_THREAD_INFO(%ebx);		\
-	INC_PRE_COUNT(%ebx)		\
 	call smp_/**/name;	\
 	jmp ret_from_intr;
 
@@ -408,10 +400,8 @@
 	movl $(__KERNEL_DS), %edx
 	movl %edx, %ds
 	movl %edx, %es
-	GET_THREAD_INFO(%ebx)
 	call *%edi
 	addl $8, %esp
-	preempt_stop
 	jmp ret_from_exception
 
 ENTRY(coprocessor_error)
@@ -438,7 +428,6 @@
 	pushl $0			# temporary storage for ORIG_EIP
 	call math_emulate
 	addl $4, %esp
-	preempt_stop
 	jmp ret_from_exception
 
 ENTRY(debug)
diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
--- a/arch/i386/kernel/i386_ksyms.c	Wed Jul 24 14:03:38 2002
+++ b/arch/i386/kernel/i386_ksyms.c	Wed Jul 24 14:03:38 2002
@@ -132,13 +132,7 @@
 EXPORT_SYMBOL_NOVERS(__write_lock_failed);
 EXPORT_SYMBOL_NOVERS(__read_lock_failed);
 
-/* Global SMP irq stuff */
-EXPORT_SYMBOL(synchronize_irq);
-EXPORT_SYMBOL(global_irq_holder);
-EXPORT_SYMBOL(__global_cli);
-EXPORT_SYMBOL(__global_sti);
-EXPORT_SYMBOL(__global_save_flags);
-EXPORT_SYMBOL(__global_restore_flags);
+/* Global SMP stuff */
 EXPORT_SYMBOL(smp_call_function);
 
 /* TLB flushing */
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	Wed Jul 24 14:03:37 2002
+++ b/arch/i386/kernel/io_apic.c	Wed Jul 24 14:03:37 2002
@@ -1219,7 +1219,7 @@
 {
 	unsigned int t1 = jiffies;
 
-	sti();
+	local_irq_enable();
 	/* Let ten ticks pass... */
 	mdelay((10 * 1000) / HZ);
 
diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
--- a/arch/i386/kernel/irq.c	Wed Jul 24 14:03:35 2002
+++ b/arch/i386/kernel/irq.c	Wed Jul 24 14:03:35 2002
@@ -184,250 +184,16 @@
 	return 0;
 }
 
-/*
- * Global interrupt locks for SMP. Allow interrupts to come in on any
- * CPU, yet make cli/sti act globally to protect critical regions..
- */
-
-#ifdef CONFIG_SMP
-unsigned char global_irq_holder = NO_PROC_ID;
-unsigned volatile long global_irq_lock; /* pendantic: long for set_bit --RR */
-
-extern void show_stack(unsigned long* esp);
-
-static void show(char * str)
-{
-	int i;
-	int cpu = smp_processor_id();
-
-	printk("\n%s, CPU %d:\n", str, cpu);
-	printk("irq:  %d [",irqs_running());
-	for(i=0;i < NR_CPUS;i++)
-		printk(" %d",local_irq_count(i));
-	printk(" ]\nbh:   %d [",spin_is_locked(&global_bh_lock) ? 1 : 0);
-	for(i=0;i < NR_CPUS;i++)
-		printk(" %d",local_bh_count(i));
-
-	printk(" ]\nStack dumps:");
-	for(i = 0; i < NR_CPUS; i++) {
-		unsigned long esp;
-		if (i == cpu)
-			continue;
-		printk("\nCPU %d:",i);
-		esp = init_tss[i].esp0;
-		if (!esp) {
-			/* tss->esp0 is set to NULL in cpu_init(),
-			 * it's initialized when the cpu returns to user
-			 * space. -- manfreds
-			 */
-			printk(" <unknown> ");
-			continue;
-		}
-		esp &= ~(THREAD_SIZE-1);
-		esp += sizeof(struct thread_info);
-		show_stack((void*)esp);
- 	}
-	printk("\nCPU %d:",cpu);
-	show_stack(NULL);
-	printk("\n");
-}
-	
-#define MAXCOUNT 100000000
-
-/*
- * I had a lockup scenario where a tight loop doing
- * spin_unlock()/spin_lock() on CPU#1 was racing with
- * spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but
- * apparently the spin_unlock() information did not make it
- * through to CPU#0 ... nasty, is this by design, do we have to limit
- * 'memory update oscillation frequency' artificially like here?
- *
- * Such 'high frequency update' races can be avoided by careful design, but
- * some of our major constructs like spinlocks use similar techniques,
- * it would be nice to clarify this issue. Set this define to 0 if you
- * want to check whether your system freezes.  I suspect the delay done
- * by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but
- * i thought that such things are guaranteed by design, since we use
- * the 'LOCK' prefix.
- */
-#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 0
-
-#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
-# define SYNC_OTHER_CORES(x) udelay(x+1)
-#else
-/*
- * We have to allow irqs to arrive between __sti and __cli
- */
-# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
-#endif
-
-static inline void wait_on_irq(int cpu)
-{
-	int count = MAXCOUNT;
-
-	for (;;) {
-
-		/*
-		 * Wait until all interrupts are gone. Wait
-		 * for bottom half handlers unless we're
-		 * already executing in one..
-		 */
-		if (!irqs_running())
-			if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
-				break;
-
-		/* Duh, we have to loop. Release the lock to avoid deadlocks */
-		clear_bit(0,&global_irq_lock);
-
-		for (;;) {
-			if (!--count) {
-				show("wait_on_irq");
-				count = ~0;
-			}
-			__sti();
-			SYNC_OTHER_CORES(cpu);
-			__cli();
-			if (irqs_running())
-				continue;
-			if (global_irq_lock)
-				continue;
-			if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
-				continue;
-			if (!test_and_set_bit(0,&global_irq_lock))
-				break;
-		}
-	}
-}
-
-/*
- * This is called when we want to synchronize with
- * interrupts. We may for example tell a device to
- * stop sending interrupts: but to make sure there
- * are no interrupts that are executing on another
- * CPU we need to call this function.
- */
-void synchronize_irq(void)
-{
-	if (irqs_running()) {
-		/* Stupid approach */
-		cli();
-		sti();
-	}
-}
-
-static inline void get_irqlock(int cpu)
-{
-	if (test_and_set_bit(0,&global_irq_lock)) {
-		/* do we already hold the lock? */
-		if ((unsigned char) cpu == global_irq_holder)
-			return;
-		/* Uhhuh.. Somebody else got it. Wait.. */
-		do {
-			do {
-				rep_nop();
-			} while (test_bit(0,&global_irq_lock));
-		} while (test_and_set_bit(0,&global_irq_lock));		
-	}
-	/* 
-	 * We also to make sure that nobody else is running
-	 * in an interrupt context. 
-	 */
-	wait_on_irq(cpu);
-
-	/*
-	 * Ok, finally..
-	 */
-	global_irq_holder = cpu;
-}
-
-#define EFLAGS_IF_SHIFT 9
-
-/*
- * A global "cli()" while in an interrupt context
- * turns into just a local cli(). Interrupts
- * should use spinlocks for the (very unlikely)
- * case that they ever want to protect against
- * each other.
- *
- * If we already have local interrupts disabled,
- * this will not turn a local disable into a
- * global one (problems with spinlocks: this makes
- * save_flags+cli+sti usable inside a spinlock).
- */
-void __global_cli(void)
-{
-	unsigned int flags;
-
-	__save_flags(flags);
-	if (flags & (1 << EFLAGS_IF_SHIFT)) {
-		int cpu;
-		__cli();
-		cpu = smp_processor_id();
-		if (!local_irq_count(cpu))
-			get_irqlock(cpu);
-	}
-}
-
-void __global_sti(void)
+#if CONFIG_SMP
+inline void synchronize_irq(unsigned int irq)
 {
-	int cpu = get_cpu();
-
-	if (!local_irq_count(cpu))
-		release_irqlock(cpu);
-	__sti();
-	put_cpu();
-}
-
-/*
- * SMP flags value to restore to:
- * 0 - global cli
- * 1 - global sti
- * 2 - local cli
- * 3 - local sti
- */
-unsigned long __global_save_flags(void)
-{
-	int retval;
-	int local_enabled;
-	unsigned long flags;
-	int cpu = smp_processor_id();
-
-	__save_flags(flags);
-	local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
-	/* default to local */
-	retval = 2 + local_enabled;
-
-	/* check for global flags if we're not in an interrupt */
-	if (!local_irq_count(cpu)) {
-		if (local_enabled)
-			retval = 1;
-		if (global_irq_holder == cpu)
-			retval = 0;
-	}
-	return retval;
-}
+	/* is there anything to synchronize with? */
+	if (!irq_desc[irq].action)
+		return;
 
-void __global_restore_flags(unsigned long flags)
-{
-	switch (flags) {
-	case 0:
-		__global_cli();
-		break;
-	case 1:
-		__global_sti();
-		break;
-	case 2:
-		__cli();
-		break;
-	case 3:
-		__sti();
-		break;
-	default:
-		printk("global_restore_flags: %08lx (%08lx)\n",
-			flags, (&flags)[-1]);
-	}
+	while (irq_desc[irq].status & IRQ_INPROGRESS)
+		cpu_relax();
 }
-
 #endif
 
 /*
@@ -439,15 +205,10 @@
  */
 int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
 {
-	int status;
-	int cpu = smp_processor_id();
-
-	irq_enter(cpu, irq);
-
-	status = 1;	/* Force the "do bottom halves" bit */
+	int status = 1;	/* Force the "do bottom halves" bit */
 
 	if (!(action->flags & SA_INTERRUPT))
-		__sti();
+		local_irq_enable();
 
 	do {
 		status |= action->flags;
@@ -456,9 +217,7 @@
 	} while (action);
 	if (status & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	__cli();
-
-	irq_exit(cpu, irq);
+	local_irq_disable();
 
 	return status;
 }
@@ -511,13 +270,7 @@
 void disable_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
-
-	if (!local_irq_count(smp_processor_id())) {
-		do {
-			barrier();
-			cpu_relax();
-		} while (irq_desc[irq].status & IRQ_INPROGRESS);
-	}
+	synchronize_irq(irq);
 }
 
 /**
@@ -581,6 +334,7 @@
 	struct irqaction * action;
 	unsigned int status;
 
+	irq_enter();
 	kstat.irqs[cpu][irq]++;
 	spin_lock(&desc->lock);
 	desc->handler->ack(irq);
@@ -640,8 +394,8 @@
 	desc->handler->end(irq);
 	spin_unlock(&desc->lock);
 
-	if (softirq_pending(cpu))
-		do_softirq();
+	irq_exit();
+
 	return 1;
 }
 
@@ -768,13 +522,8 @@
 			}
 			spin_unlock_irqrestore(&desc->lock,flags);
 
-#ifdef CONFIG_SMP
 			/* Wait to make sure it's not being used on another CPU */
-			while (desc->status & IRQ_INPROGRESS) {
-				barrier();
-				cpu_relax();
-			}
-#endif
+			synchronize_irq(irq);
 			kfree(action);
 			return;
 		}
@@ -826,7 +575,7 @@
 
 	/* Wait for longstanding interrupts to trigger. */
 	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
-		/* about 20ms delay */ synchronize_irq();
+		/* about 20ms delay */ barrier();
 
 	/*
 	 * enable any unassigned irqs
@@ -849,7 +598,7 @@
 	 * Wait for spurious interrupts to trigger
 	 */
 	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ synchronize_irq();
+		/* about 100ms delay */ barrier();
 
 	/*
 	 * Now filter out any obviously spurious interrupts
diff -Nru a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
--- a/arch/i386/kernel/ldt.c	Wed Jul 24 14:03:36 2002
+++ b/arch/i386/kernel/ldt.c	Wed Jul 24 14:03:36 2002
@@ -107,7 +107,8 @@
 void release_segments(struct mm_struct *mm)
 {
 	if (mm->context.size) {
-		clear_LDT();
+		if (mm == current->active_mm)
+			clear_LDT();
 		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
 			vfree(mm->context.ldt);
 		else
diff -Nru a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
--- a/arch/i386/kernel/mca.c	Wed Jul 24 14:03:36 2002
+++ b/arch/i386/kernel/mca.c	Wed Jul 24 14:03:36 2002
@@ -102,6 +102,12 @@
 
 static struct MCA_info* mca_info = NULL;
 
+/*
+ * Motherboard register spinlock. Untested on SMP at the moment, but
+ * are there any MCA SMP boxes?
+ */
+static spinlock_t mca_lock = SPIN_LOCK_UNLOCKED;
+
 /* MCA registers */
 
 #define MCA_MOTHERBOARD_SETUP_REG	0x94
@@ -213,8 +219,11 @@
 	}
 	memset(mca_info, 0, sizeof(struct MCA_info));
 
-	save_flags(flags);
-	cli();
+	/*
+	 * We do not expect many MCA interrupts during initialization,
+	 * but let us be safe:
+	 */
+	spin_lock_irq(&mca_lock);
 
 	/* Make sure adapter setup is off */
 
@@ -300,8 +309,7 @@
 	outb_p(0, MCA_ADAPTER_SETUP_REG);
 
 	/* Enable interrupts and return memory start */
-
-	restore_flags(flags);
+	spin_unlock_irq(&mca_lock);
 
 	for (i = 0; i < MCA_STANDARD_RESOURCES; i++)
 		request_resource(&ioport_resource, mca_standard_resources + i);
@@ -514,8 +522,7 @@
 	if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == NULL) return 0;
 	if(reg < 0 || reg >= 8) return 0;
 
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&mca_lock, flags);
 
 	/* Make sure motherboard setup is off */
 
@@ -566,7 +573,7 @@
 
 	mca_info->slot[slot].pos[reg] = byte;
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&mca_lock, flags);
 
 	return byte;
 } /* mca_read_pos() */
@@ -610,8 +617,7 @@
 	if(mca_info == NULL)
 		return;
 
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&mca_lock, flags);
 
 	/* Make sure motherboard setup is off */
 
@@ -623,7 +629,7 @@
 	outb_p(byte, MCA_POS_REG(reg));
 	outb_p(0, MCA_ADAPTER_SETUP_REG);
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&mca_lock, flags);
 
 	/* Update the global register list, while we have the byte */
 
diff -Nru a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c
--- a/arch/i386/kernel/mtrr.c	Wed Jul 24 14:03:35 2002
+++ b/arch/i386/kernel/mtrr.c	Wed Jul 24 14:03:35 2002
@@ -381,7 +381,7 @@
 static void set_mtrr_prepare_save (struct set_mtrr_context *ctxt)
 {
     /*  Disable interrupts locally  */
-    __save_flags (ctxt->flags); __cli ();
+    local_irq_save(ctxt->flags);
 
     if ( mtrr_if != MTRR_IF_INTEL && mtrr_if != MTRR_IF_CYRIX_ARR )
 	 return;
@@ -428,7 +428,7 @@
 static void set_mtrr_done (struct set_mtrr_context *ctxt)
 {
     if ( mtrr_if != MTRR_IF_INTEL && mtrr_if != MTRR_IF_CYRIX_ARR ) {
-	 __restore_flags (ctxt->flags);
+	 local_irq_restore (ctxt->flags);
 	 return;
     }
 
@@ -452,7 +452,7 @@
 	write_cr4(ctxt->cr4val);
 
     /*  Re-enable interrupts locally (if enabled previously)  */
-    __restore_flags (ctxt->flags);
+    local_irq_restore (ctxt->flags);
 }   /*  End Function set_mtrr_done  */
 
 /*  This function returns the number of variable MTRRs  */
@@ -546,7 +546,7 @@
     arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */
 
     /* Save flags and disable interrupts */
-    __save_flags (flags); __cli ();
+    local_irq_save(flags);
 
     ccr3 = getCx86 (CX86_CCR3);
     setCx86 (CX86_CCR3, (ccr3 & 0x0f) | 0x10);		/* enable MAPEN */
@@ -557,7 +557,7 @@
     setCx86 (CX86_CCR3, ccr3);				/* disable MAPEN */
 
     /* Enable interrupts if it was enabled previously */
-    __restore_flags (flags);
+    local_irq_restore (flags);
     shift = ((unsigned char *) base)[1] & 0x0f;
     *base >>= PAGE_SHIFT;
 
diff -Nru a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
--- a/arch/i386/kernel/nmi.c	Wed Jul 24 14:03:38 2002
+++ b/arch/i386/kernel/nmi.c	Wed Jul 24 14:03:38 2002
@@ -78,7 +78,7 @@
 	printk(KERN_INFO "testing NMI watchdog ... ");
 
 	memcpy(tmp, irq_stat, sizeof(tmp));
-	sti();
+	local_irq_enable();
 	mdelay((10*1000)/nmi_hz); // wait 10 ticks
 
 	for (cpu = 0; cpu < NR_CPUS; cpu++) {
diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c	Wed Jul 24 14:03:35 2002
+++ b/arch/i386/kernel/process.c	Wed Jul 24 14:03:35 2002
@@ -89,11 +89,11 @@
 void default_idle(void)
 {
 	if (current_cpu_data.hlt_works_ok && !hlt_counter) {
-		__cli();
+		local_irq_disable();
 		if (!need_resched())
 			safe_halt();
 		else
-			__sti();
+			local_irq_enable();
 	}
 }
 
@@ -106,7 +106,7 @@
 {
 	int oldval;
 
-	__sti();
+	local_irq_enable();
 
 	/*
 	 * Deal with another CPU just having chosen a thread to
@@ -290,7 +290,7 @@
 {
 	unsigned long flags;
 
-	cli();
+	local_irq_disable();
 
 	/* Write zero to CMOS register number 0x0f, which the BIOS POST
 	   routine will recognize as telling it to do a proper reboot.  (Well
diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
--- a/arch/i386/kernel/smp.c	Wed Jul 24 14:03:36 2002
+++ b/arch/i386/kernel/smp.c	Wed Jul 24 14:03:36 2002
@@ -161,9 +161,7 @@
 	unsigned long cfg;
 	unsigned long flags;
 
-	__save_flags(flags);
-	__cli();
-
+	local_irq_save(flags);
 		
 	/*
 	 * Wait for idle.
@@ -186,7 +184,7 @@
 	 */
 	apic_write_around(APIC_ICR, cfg);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void send_IPI_mask_sequence(int mask, int vector)
@@ -200,8 +198,7 @@
 	 * should be modified to do 1 message per cluster ID - mbligh
 	 */ 
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 
 	for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) {
 		query_mask = 1 << query_cpu;
@@ -229,7 +226,7 @@
 			apic_write_around(APIC_ICR, cfg);
 		}
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void send_IPI_mask(int mask, int vector)
@@ -387,7 +384,7 @@
 	clear_bit(cpu, &flush_cpumask);
 
 out:
-	put_cpu();
+	put_cpu_no_resched();
 }
 
 static void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
@@ -603,7 +600,7 @@
 	 * Remove this CPU:
 	 */
 	clear_bit(smp_processor_id(), &cpu_online_map);
-	__cli();
+	local_irq_disable();
 	disable_local_APIC();
 	if (cpu_data[smp_processor_id()].hlt_works_ok)
 		for(;;) __asm__("hlt");
@@ -618,9 +615,9 @@
 {
 	smp_call_function(stop_this_cpu, NULL, 1, 0);
 
-	__cli();
+	local_irq_disable();
 	disable_local_APIC();
-	__sti();
+	local_irq_enable();
 }
 
 /*
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	Wed Jul 24 14:03:38 2002
+++ b/arch/i386/kernel/smpboot.c	Wed Jul 24 14:03:38 2002
@@ -453,7 +453,7 @@
 		clear_local_APIC();
 	setup_local_APIC();
 
-	__sti();
+	local_irq_enable();
 
 #ifdef CONFIG_MTRR
 	/*
@@ -1060,7 +1060,6 @@
 	boot_cpu_logical_apicid = logical_smp_processor_id();
 	map_cpu_to_boot_apicid(0, boot_cpu_apicid);
 
-	global_irq_holder = NO_PROC_ID;
 	current_thread_info()->cpu = 0;
 	smp_tune_scheduling();
 
diff -Nru a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
--- a/arch/i386/kernel/vm86.c	Wed Jul 24 14:03:36 2002
+++ b/arch/i386/kernel/vm86.c	Wed Jul 24 14:03:36 2002
@@ -571,6 +571,8 @@
 	struct task_struct *tsk;
 	int sig;
 } vm86_irqs[16];
+
+static spinlock_t irqbits_lock = SPIN_LOCK_UNLOCKED;
 static int irqbits;
 
 #define ALLOWED_SIGS ( 1 /* 0 = don't send a signal */ \
@@ -580,9 +582,8 @@
 static void irq_handler(int intno, void *dev_id, struct pt_regs * regs) {
 	int irq_bit;
 	unsigned long flags;
-	
-	save_flags(flags);
-	cli();
+
+	spin_lock_irqsave(&irqbits_lock, flags);	
 	irq_bit = 1 << intno;
 	if ((irqbits & irq_bit) || ! vm86_irqs[intno].tsk)
 		goto out;
@@ -591,14 +592,19 @@
 		send_sig(vm86_irqs[intno].sig, vm86_irqs[intno].tsk, 1);
 	/* else user will poll for IRQs */
 out:
-	restore_flags(flags);
+	spin_unlock_irqrestore(&irqbits_lock, flags);	
 }
 
 static inline void free_vm86_irq(int irqnumber)
 {
+	unsigned long flags;
+
 	free_irq(irqnumber,0);
 	vm86_irqs[irqnumber].tsk = 0;
+
+	spin_lock_irqsave(&irqbits_lock, flags);	
 	irqbits &= ~(1 << irqnumber);
+	spin_unlock_irqrestore(&irqbits_lock, flags);	
 }
 
 static inline int task_valid(struct task_struct *tsk)
@@ -635,11 +641,10 @@
 	
 	if ( (irqnumber<3) || (irqnumber>15) ) return 0;
 	if (vm86_irqs[irqnumber].tsk != current) return 0;
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&irqbits_lock, flags);	
 	bit = irqbits & (1 << irqnumber);
 	irqbits &= ~bit;
-	restore_flags(flags);
+	spin_unlock_irqrestore(&irqbits_lock, flags);	
 	return bit;
 }
 
diff -Nru a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
--- a/arch/i386/mm/fault.c	Wed Jul 24 14:03:35 2002
+++ b/arch/i386/mm/fault.c	Wed Jul 24 14:03:35 2002
@@ -107,27 +107,25 @@
  */
 void bust_spinlocks(int yes)
 {
+	int loglevel_save = console_loglevel;
+
 	spin_lock_init(&timerlist_lock);
 	if (yes) {
 		oops_in_progress = 1;
-#ifdef CONFIG_SMP
-		global_irq_lock = 0;	/* Many serial drivers do __global_cli() */
-#endif
-	} else {
-		int loglevel_save = console_loglevel;
+		return;
+	}
 #ifdef CONFIG_VT
-		unblank_screen();
+	unblank_screen();
 #endif
-		oops_in_progress = 0;
-		/*
-		 * OK, the message is on the console.  Now we call printk()
-		 * without oops_in_progress set so that printk will give klogd
-		 * a poke.  Hold onto your hats...
-		 */
-		console_loglevel = 15;		/* NMI oopser may have shut the console up */
-		printk(" ");
-		console_loglevel = loglevel_save;
-	}
+	oops_in_progress = 0;
+	/*
+	 * OK, the message is on the console.  Now we call printk()
+	 * without oops_in_progress set so that printk will give klogd
+	 * a poke.  Hold onto your hats...
+	 */
+	console_loglevel = 15;		/* NMI oopser may have shut the console up */
+	printk(" ");
+	console_loglevel = loglevel_save;
 }
 
 asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
diff -Nru a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
--- a/arch/i386/mm/ioremap.c	Wed Jul 24 14:03:36 2002
+++ b/arch/i386/mm/ioremap.c	Wed Jul 24 14:03:36 2002
@@ -215,7 +215,7 @@
 	struct vm_struct *p;
 	if (addr <= high_memory) 
 		return; 
-	p = remove_kernel_area(PAGE_MASK & (unsigned long) addr); 
+	p = remove_kernel_area((void *) (PAGE_MASK & (unsigned long) addr));
 	if (!p) { 
 		printk("__iounmap: bad address %p\n", addr);
 		return;
diff -Nru a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c
--- a/arch/i386/pci/direct.c	Wed Jul 24 14:03:36 2002
+++ b/arch/i386/pci/direct.c	Wed Jul 24 14:03:36 2002
@@ -306,7 +306,7 @@
 	unsigned int tmp;
 	unsigned long flags;
 
-	__save_flags(flags); __cli();
+	local_irq_save(flags);
 
 	/*
 	 * Check if configuration type 1 works.
@@ -318,7 +318,7 @@
 		if (inl (0xCF8) == 0x80000000 &&
 		    pci_sanity_check(&pci_direct_conf1)) {
 			outl (tmp, 0xCF8);
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			printk(KERN_INFO "PCI: Using configuration type 1\n");
 			if (!request_region(0xCF8, 8, "PCI conf1"))
 				return NULL;
@@ -336,7 +336,7 @@
 		outb (0x00, 0xCFA);
 		if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 &&
 		    pci_sanity_check(&pci_direct_conf2)) {
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			printk(KERN_INFO "PCI: Using configuration type 2\n");
 			if (!request_region(0xCF8, 4, "PCI conf2"))
 				return NULL;
@@ -344,7 +344,7 @@
 		}
 	}
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	return NULL;
 }
 
diff -Nru a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c
--- a/arch/i386/pci/pcbios.c	Wed Jul 24 14:03:35 2002
+++ b/arch/i386/pci/pcbios.c	Wed Jul 24 14:03:35 2002
@@ -82,7 +82,7 @@
 	unsigned long entry;		/* %edx */
 	unsigned long flags;
 
-	__save_flags(flags); __cli();
+	local_irq_save(flags);
 	__asm__("lcall *(%%edi); cld"
 		: "=a" (return_code),
 		  "=b" (address),
@@ -91,7 +91,7 @@
 		: "0" (service),
 		  "1" (0),
 		  "D" (&bios32_indirect));
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	switch (return_code) {
 		case 0:
@@ -122,7 +122,7 @@
 	if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
 		pci_indirect.address = pcibios_entry + PAGE_OFFSET;
 
-		__save_flags(flags); __cli();
+		local_irq_save(flags);
 		__asm__(
 			"lcall *(%%edi); cld\n\t"
 			"jc 1f\n\t"
@@ -135,7 +135,7 @@
 			: "1" (PCIBIOS_PCI_BIOS_PRESENT),
 			  "D" (&pci_indirect)
 			: "memory");
-		__restore_flags(flags);
+		local_irq_restore(flags);
 
 		status = (eax >> 8) & 0xff;
 		hw_mech = eax & 0xff;
diff -Nru a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
--- a/arch/ia64/hp/sim/simscsi.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ia64/hp/sim/simscsi.c	Wed Jul 24 14:03:38 2002
@@ -144,7 +144,7 @@
 }
 
 int
-simscsi_biosparam (Disk *disk, kdev_t n, int ip[])
+simscsi_biosparam (Disk *disk, struct block_device *n, int ip[])
 {
 	int size = disk->capacity;
 
diff -Nru a/arch/ia64/hp/sim/simscsi.h b/arch/ia64/hp/sim/simscsi.h
--- a/arch/ia64/hp/sim/simscsi.h	Wed Jul 24 14:03:35 2002
+++ b/arch/ia64/hp/sim/simscsi.h	Wed Jul 24 14:03:35 2002
@@ -17,7 +17,7 @@
 extern int simscsi_queuecommand (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int simscsi_abort (Scsi_Cmnd *);
 extern int simscsi_reset (Scsi_Cmnd *, unsigned int);
-extern int simscsi_biosparam (Disk *, kdev_t, int[]);
+extern int simscsi_biosparam (Disk *, struct block_device *, int[]);
 
 #define SIMSCSI {					\
 	detect:			simscsi_detect,		\
diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
--- a/arch/ia64/kernel/irq.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ia64/kernel/irq.c	Wed Jul 24 14:03:37 2002
@@ -284,7 +284,7 @@
 # define SYNC_OTHER_CORES(x) udelay(x+1)
 #else
 /*
- * We have to allow irqs to arrive between __sti and __cli
+ * We have to allow irqs to arrive between local_irq_enable and local_irq_disable
  */
 # ifdef CONFIG_IA64
 #  define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop 0")
@@ -317,9 +317,9 @@
 				show("wait_on_irq");
 				count = ~0;
 			}
-			__sti();
+			local_irq_enable();
 			SYNC_OTHER_CORES(smp_processor_id());
-			__cli();
+			local_irq_disable();
 			if (irqs_running())
 				continue;
 			if (global_irq_lock)
@@ -394,16 +394,16 @@
 	unsigned int flags;
 
 #ifdef CONFIG_IA64
-	__save_flags(flags);
+	local_save_flags(flags);
 	if (flags & IA64_PSR_I) {
-		__cli();
+		local_irq_disable();
 		if (!really_local_irq_count())
 			get_irqlock();
 	}
 #else
-	__save_flags(flags);
+	local_save_flags(flags);
 	if (flags & (1 << EFLAGS_IF_SHIFT)) {
-		__cli();
+		local_irq_disable();
 		if (!really_local_irq_count())
 			get_irqlock();
 	}
@@ -414,7 +414,7 @@
 {
 	if (!really_local_irq_count())
 		release_irqlock(smp_processor_id());
-	__sti();
+	local_irq_enable();
 }
 
 /*
@@ -431,7 +431,7 @@
 	unsigned long flags;
 	int cpu = smp_processor_id();
 
-	__save_flags(flags);
+	local_save_flags(flags);
 #ifdef CONFIG_IA64
 	local_enabled = (flags & IA64_PSR_I) != 0;
 #else
@@ -460,10 +460,10 @@
 		__global_sti();
 		break;
 	case 2:
-		__cli();
+		local_irq_disable();
 		break;
 	case 3:
-		__sti();
+		local_irq_enable();
 		break;
 	default:
 		printk("global_restore_flags: %08lx (%08lx)\n",
@@ -489,7 +489,7 @@
 	status = 1;	/* Force the "do bottom halves" bit */
 
 	if (!(action->flags & SA_INTERRUPT))
-		__sti();
+		local_irq_enable();
 
 	do {
 		status |= action->flags;
@@ -498,7 +498,7 @@
 	} while (action);
 	if (status & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	__cli();
+	local_irq_disable();
 
 	local_irq_exit(irq);
 
diff -Nru a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
--- a/arch/ia64/kernel/smp.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ia64/kernel/smp.c	Wed Jul 24 14:03:39 2002
@@ -91,7 +91,7 @@
 	 */
 	clear_bit(smp_processor_id(), &cpu_online_map);
 	max_xtp();
-	__cli();
+	local_irq_disable();
 	cpu_halt();
 }
 
diff -Nru a/arch/ia64/sn/kernel/llsc4.c b/arch/ia64/sn/kernel/llsc4.c
--- a/arch/ia64/sn/kernel/llsc4.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ia64/sn/kernel/llsc4.c	Wed Jul 24 14:03:36 2002
@@ -1025,7 +1025,7 @@
 	if (mycpu == NR_CPUS-1) {
 		printk("\nTight loop of cpu %d sending ints to cpu 0 (every 100 us)\n", mycpu);
 		udelay(IS_RUNNING_ON_SIMULATOR ? 1000 : 1000000);
-		__cli();
+		local_irq_disable();
 		while (1) {
 			smp_send_reschedule(0);
 			udelay(100);
diff -Nru a/arch/ia64/sn/kernel/sv.c b/arch/ia64/sn/kernel/sv.c
--- a/arch/ia64/sn/kernel/sv.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ia64/sn/kernel/sv.c	Wed Jul 24 14:03:36 2002
@@ -183,7 +183,7 @@
 #ifdef SV_DEBUG_INTERRUPT_STATE
 	{
 	unsigned long flags;
-	__save_flags(flags);
+	local_save_flags(flags);
 
 	if(sv->sv_flags & SV_INTS) {
 		if(SV_TEST_INTERRUPTS_ENABLED(flags)) {
@@ -279,7 +279,7 @@
 #ifdef SV_DEBUG_INTERRUPT_STATE
 	if(sv->sv_flags & SV_INTS) {
 		unsigned long flags;
-		__save_flags(flags);
+		local_save_flags(flags);
 		if(SV_TEST_INTERRUPTS_ENABLED(flags))
 			printk(KERN_ERR "sv_signal: SV_INTS and "
 			"interrupts enabled! (flags: 0x%lx)\n", flags);
@@ -296,7 +296,7 @@
 #ifdef SV_DEBUG_INTERRUPT_STATE
 	if(sv->sv_flags & SV_INTS) {
 		unsigned long flags;
-		__save_flags(flags);
+		local_save_flags(flags);
 		if(SV_TEST_INTERRUPTS_ENABLED(flags))
 			printk(KERN_ERR "sv_broadcast: SV_INTS and "
 			       "interrupts enabled! (flags: 0x%lx)\n", flags);
@@ -475,7 +475,7 @@
 	printk("ITW: thread %d started.\n", id);
 
 	while(1) {
-		__save_flags(flags2);
+		local_save_flags(flags2);
 		if(jiffies % 3) {
 			printk("ITW %2d %5d: irqsaving          (%lx)\n", id, it, flags2);
 			spin_lock_irqsave(&int_test_spin, flags);
@@ -484,11 +484,11 @@
 			spin_lock_irq(&int_test_spin);
 		}
 
-		__save_flags(flags2);
+		local_save_flags(flags2);
 		printk("ITW %2d %5d: locked, sv_waiting (%lx).\n", id, it, flags2);
 		sv_wait(&int_test_sv, 0, 0);
 
-		__save_flags(flags2);
+		local_save_flags(flags2);
 		printk("ITW %2d %5d: wait finished      (%lx), pausing\n", id, it, flags2);
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(jiffies & 0xf);
diff -Nru a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
--- a/arch/m68k/amiga/config.c	Wed Jul 24 14:03:35 2002
+++ b/arch/m68k/amiga/config.c	Wed Jul 24 14:03:35 2002
@@ -20,6 +20,7 @@
 #include <linux/console.h>
 #include <linux/rtc.h>
 #include <linux/init.h>
+#include <linux/vt_kern.h>
 #ifdef CONFIG_ZORRO
 #include <linux/zorro.h>
 #endif
@@ -110,9 +111,9 @@
 #endif
 
 static struct console amiga_console_driver = {
-	name:		"debug",
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
+	.name =		"debug",
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
 };
 
 #ifdef CONFIG_MAGIC_SYSRQ
@@ -127,8 +128,6 @@
 	"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";	/* 0x70 - 0x7f */
 #endif
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
-
 
     /*
      *  Motherboard Resources present in all Amiga models
@@ -137,10 +136,10 @@
 static struct {
     struct resource _ciab, _ciaa, _custom, _kickstart;
 } mb_resources = {
-    _ciab:	{ "CIA B", 0x00bfd000, 0x00bfdfff },
-    _ciaa:	{ "CIA A", 0x00bfe000, 0x00bfefff },
-    _custom:	{ "Custom I/O", 0x00dff000, 0x00dfffff },
-    _kickstart:	{ "Kickstart ROM", 0x00f80000, 0x00ffffff }
+    ._ciab =		{ "CIA B", 0x00bfd000, 0x00bfdfff },
+    ._ciaa =		{ "CIA A", 0x00bfe000, 0x00bfefff },
+    ._custom =		{ "Custom I/O", 0x00dff000, 0x00dfffff },
+    ._kickstart =	{ "Kickstart ROM", 0x00f80000, 0x00ffffff }
 };
 
 static struct resource rtc_resource = {
@@ -389,10 +388,11 @@
     request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]);
 
   mach_sched_init      = amiga_sched_init;
+#ifdef CONFIG_VT
   mach_keyb_init       = amiga_keyb_init;
   mach_kbdrate         = amiga_kbdrate;
   mach_kbd_translate   = amiga_kbd_translate;
-  SYSRQ_KEY            = 0xff;
+#endif
   mach_init_IRQ        = amiga_init_IRQ;
   mach_default_handler = &amiga_default_handler;
   mach_request_irq     = amiga_request_irq;
@@ -432,8 +432,11 @@
 #ifdef CONFIG_DUMMY_CONSOLE
   conswitchp           = &dummy_con;
 #endif
+#ifdef CONFIG_VT
   kd_mksound           = amiga_mksound;
+#endif
 #ifdef CONFIG_MAGIC_SYSRQ
+  SYSRQ_KEY            = 0xff;
   mach_sysrq_key = 0x5f;	     /* HELP */
   mach_sysrq_shift_state = 0x03; /* SHIFT+ALTGR */
   mach_sysrq_shift_mask = 0xff;  /* all modifiers except CapsLock */
diff -Nru a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
--- a/arch/m68k/apollo/config.c	Wed Jul 24 14:03:37 2002
+++ b/arch/m68k/apollo/config.c	Wed Jul 24 14:03:37 2002
@@ -5,6 +5,7 @@
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/rtc.h>
+#include <linux/vt_kern.h>
 
 #include <asm/setup.h>
 #include <asm/bootinfo.h>
@@ -41,7 +42,6 @@
 extern void dn_dummy_waitbut(void);
 extern struct fb_info *dn_fb_init(long *);
 extern void dn_dummy_debug_init(void);
-extern void (*kd_mksound)(unsigned int, unsigned int);
 extern void dn_dummy_video_setup(char *,int *);
 extern void dn_process_int(int irq, struct pt_regs *fp);
 #ifdef CONFIG_HEARTBEAT
@@ -165,8 +165,10 @@
 	dn_setup_model();	
 
 	mach_sched_init=dn_sched_init; /* */
+#ifdef CONFIG_VT
 	mach_keyb_init=dn_keyb_init;
 	mach_kbdrate=dn_dummy_kbdrate;
+#endif
 	mach_init_IRQ=dn_init_IRQ;
 	mach_default_handler=NULL;
 	mach_request_irq     = dn_request_irq;
@@ -187,7 +189,9 @@
 #ifdef CONFIG_DUMMY_CONSOLE
         conswitchp           = &dummy_con;
 #endif
+#ifdef CONFIG_VT
 	kd_mksound	     = dn_mksound;
+#endif
 #ifdef CONFIG_HEARTBEAT
   	mach_heartbeat = dn_heartbeat;
 #endif
diff -Nru a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
--- a/arch/m68k/apollo/dn_ints.c	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/apollo/dn_ints.c	Wed Jul 24 14:03:38 2002
@@ -2,6 +2,7 @@
 #include <linux/kernel.h>
 #include <linux/jiffies.h>
 #include <linux/kernel_stat.h>
+#include <linux/timer.h>
 
 #include <asm/system.h>
 #include <asm/irq.h>
@@ -9,14 +10,10 @@
 #include <asm/page.h>
 #include <asm/machdep.h>
 #include <asm/apollohw.h>
+#include <asm/errno.h>
 
 static irq_handler_t dn_irqs[16];
 
-extern void write_keyb_cmd(u_short length, u_char *cmd);
-static char BellOnCommand[] =  { 0xFF, 0x21, 0x81 },
-		    BellOffCommand[] = { 0xFF, 0x21, 0x82 };
-
-extern void dn_serial_print (const char *str);
 void dn_process_int(int irq, struct pt_regs *fp) {
 
 
@@ -120,6 +117,11 @@
 
 }
 
+#ifdef CONFIG_VT
+extern void write_keyb_cmd(u_short length, u_char *cmd);
+static char BellOnCommand[] =  { 0xFF, 0x21, 0x81 },
+		    BellOffCommand[] = { 0xFF, 0x21, 0x82 };
+
 static void dn_nosound (unsigned long ignored) {
 
 	write_keyb_cmd(sizeof(BellOffCommand),BellOffCommand);
@@ -141,6 +143,8 @@
 	else
 		write_keyb_cmd(sizeof(BellOffCommand),BellOffCommand);
 }
+#endif /* CONFIG_VT */
+
 
 void dn_dummy_video_setup(char *options,int *ints) {
 
diff -Nru a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile
--- a/arch/m68k/atari/Makefile	Wed Jul 24 14:03:36 2002
+++ b/arch/m68k/atari/Makefile	Wed Jul 24 14:03:36 2002
@@ -11,10 +11,12 @@
 
 export-objs	:= atari_ksyms.o
 
-obj-y		:= config.o time.o debug.o atakeyb.o ataints.o stdma.o \
-			atasound.o joystick.o stram.o atari_ksyms.o
+obj-y		:= config.o time.o debug.o ataints.o stdma.o \
+			atasound.o stram.o atari_ksyms.o
 
-ifdef CONFIG_PCI
+obj-$(CONFIG_VT)	+= atakeyb.o joystick.o
+
+ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_HADES)	+= hades-pci.o
 endif
 
diff -Nru a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
--- a/arch/m68k/atari/ataints.c	Wed Jul 24 14:03:36 2002
+++ b/arch/m68k/atari/ataints.c	Wed Jul 24 14:03:36 2002
@@ -622,22 +622,22 @@
 		if (vectors[IRQ_SOURCE_TO_VECTOR(i)] == bad_interrupt)
 			continue;
 		if (i < STMFP_SOURCE_BASE)
-			seq_printf(p,, "auto %2d: %10u ",
+			seq_printf(p, "auto %2d: %10u ",
 				       i, kstat.irqs[0][i]);
 		else
-			seq_printf(p,, "vec $%02x: %10u ",
+			seq_printf(p, "vec $%02x: %10u ",
 				       IRQ_SOURCE_TO_VECTOR(i),
 				       kstat.irqs[0][i]);
 
 		if (irq_handler[i].handler != atari_call_irq_list) {
-			seq_printf(p,, "%s\n", irq_param[i].devname);
+			seq_printf(p, "%s\n", irq_param[i].devname);
 		}
 		else {
-			irq_node_t *p;
-			for( p = (irq_node_t *)irq_handler[i].dev_id; p; p = p->next ) {
-				seq_printf(p,, "%s\n", p->devname);
-				if (p->next)
-					seq_puts(p,, "                    " );
+			irq_node_t *n;
+			for( n = (irq_node_t *)irq_handler[i].dev_id; n; n = n->next ) {
+				seq_printf(p, "%s\n", n->devname);
+				if (n->next)
+					seq_puts(p, "                    " );
 			}
 		}
 	}
diff -Nru a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
--- a/arch/m68k/atari/config.c	Wed Jul 24 14:03:36 2002
+++ b/arch/m68k/atari/config.c	Wed Jul 24 14:03:36 2002
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
+#include <linux/vt_kern.h>
 
 #include <asm/bootinfo.h>
 #include <asm/setup.h>
@@ -100,7 +101,6 @@
 	"0.\r\000\000\000\000\000\000\000\000\000\000\000\000\000";	/* 0x70 - 0x7f */
 #endif
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
 
 /* I've moved hwreg_present() and hwreg_present_bywrite() out into
  * mm/hwtest.c, to avoid having multiple copies of the same routine
@@ -254,13 +254,12 @@
                                            to 4GB. */
 
     mach_sched_init      = atari_sched_init;
+#ifdef CONFIG_VT
     mach_keyb_init       = atari_keyb_init;
     mach_kbdrate         = atari_kbdrate;
     mach_kbd_translate   = atari_kbd_translate;
-#ifdef CONFIG_MAGIC_SYSRQ
-    SYSRQ_KEY            = 0xff;
-#endif
     mach_kbd_leds        = atari_kbd_leds;
+#endif
     mach_init_IRQ        = atari_init_IRQ;
     mach_request_irq     = atari_request_irq;
     mach_free_irq        = atari_free_irq;
@@ -278,8 +277,11 @@
     conswitchp	         = &dummy_con;
 #endif
     mach_max_dma_address = 0xffffff;
+#ifdef CONFIG_VT
     kd_mksound		 = atari_mksound;
+#endif
 #ifdef CONFIG_MAGIC_SYSRQ
+    SYSRQ_KEY            = 0xff;
     mach_sysrq_key = 98;          /* HELP */
     mach_sysrq_shift_state = 8;   /* Alt */
     mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */
diff -Nru a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c
--- a/arch/m68k/atari/debug.c	Wed Jul 24 14:03:37 2002
+++ b/arch/m68k/atari/debug.c	Wed Jul 24 14:03:37 2002
@@ -31,9 +31,9 @@
 int atari_SCC_reset_done = 0;
 
 static struct console atari_console_driver = {
-	name:		"debug",
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
+	.name =		"debug",
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
 };
 
 
diff -Nru a/arch/m68k/atari/hades-pci.c b/arch/m68k/atari/hades-pci.c
--- a/arch/m68k/atari/hades-pci.c	Wed Jul 24 14:03:35 2002
+++ b/arch/m68k/atari/hades-pci.c	Wed Jul 24 14:03:35 2002
@@ -334,12 +334,12 @@
 }
 
 static struct pci_ops hades_pci_ops = {
-	read_byte:	hades_read_config_byte
-	read_word:	hades_read_config_word
-	read_dword:	hades_read_config_dword
-	write_byte:	hades_write_config_byte
-	write_word:	hades_write_config_word
-	write_dword:	hades_write_config_dword
+	.read_byte =	hades_read_config_byte,
+	.read_word =	hades_read_config_word,
+	.read_dword =	hades_read_config_dword,
+	.write_byte =	hades_write_config_byte,
+	.write_word =	hades_write_config_word,
+	.write_dword =	hades_write_config_dword
 };
 
 /*
diff -Nru a/arch/m68k/atari/joystick.c b/arch/m68k/atari/joystick.c
--- a/arch/m68k/atari/joystick.c	Wed Jul 24 14:03:35 2002
+++ b/arch/m68k/atari/joystick.c	Wed Jul 24 14:03:35 2002
@@ -22,8 +22,8 @@
 #define MAJOR_NR    JOYSTICK_MAJOR
 
 #define	ANALOG_JOY(n)	(!(n & 0x80))
-#define	DIGITAL_JOY(n)	(n & 0x80)
-#define	DEVICE_NR(n)	(MINOR(n) & 0x7f)
+#define	DIGITAL_JOY(n)	(minor(n) & 0x80)
+#define	DEVICE_NR(n)	(minor(n) & 0x7f)
 
 
 static struct joystick_status joystick[2];
@@ -120,11 +120,11 @@
 }
 
 struct file_operations atari_joystick_fops = {
-	read:		read_joystick,
-	write:		write_joystick,
-	poll:		joystick_poll,
-	open:		open_joystick,
-	release:	release_joystick,
+	.read =		read_joystick,
+	.write =	write_joystick,
+	.poll =		joystick_poll,
+	.open =		open_joystick,
+	.release =	release_joystick,
 };
 
 int __init atari_joystick_init(void)
diff -Nru a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
--- a/arch/m68k/atari/stram.c	Wed Jul 24 14:03:36 2002
+++ b/arch/m68k/atari/stram.c	Wed Jul 24 14:03:36 2002
@@ -1044,8 +1044,8 @@
 
 
 static struct block_device_operations stram_fops = {
-	open:		stram_open,
-	release:	stram_release,
+	.open =		stram_open,
+	.release =	stram_release,
 };
 
 int __init stram_device_init(void)
diff -Nru a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c
--- a/arch/m68k/bvme6000/config.c	Wed Jul 24 14:03:35 2002
+++ b/arch/m68k/bvme6000/config.c	Wed Jul 24 14:03:35 2002
@@ -22,6 +22,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/major.h>
+#include <linux/genhd.h>
 #include <linux/rtc.h>
 
 #include <asm/bootinfo.h>
@@ -49,7 +50,6 @@
 extern unsigned long bvme6000_gettimeoffset (void);
 extern int bvme6000_hwclk (int, struct rtc_time *);
 extern int bvme6000_set_clock_mmss (unsigned long);
-extern void bvme6000_check_partition (struct gendisk *hd, unsigned int dev);
 extern void bvme6000_mksound( unsigned int count, unsigned int ticks );
 extern void bvme6000_reset (void);
 extern void bvme6000_waitbut(void);
@@ -133,8 +133,10 @@
 
     mach_max_dma_address = 0xffffffff;
     mach_sched_init      = bvme6000_sched_init;
+#ifdef CONFIG_VT
     mach_keyb_init       = bvme6000_keyb_init;
     mach_kbdrate         = bvme6000_kbdrate;
+#endif
     mach_init_IRQ        = bvme6000_init_IRQ;
     mach_gettimeoffset   = bvme6000_gettimeoffset;
     mach_hwclk           = bvme6000_hwclk;
diff -Nru a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c
--- a/arch/m68k/bvme6000/rtc.c	Wed Jul 24 14:03:35 2002
+++ b/arch/m68k/bvme6000/rtc.c	Wed Jul 24 14:03:35 2002
@@ -161,9 +161,9 @@
  */
 
 static struct file_operations rtc_fops = {
-	ioctl:		rtc_ioctl,
-	open:		rtc_open,
-	release:	rtc_release,
+	.ioctl =	rtc_ioctl,
+	.open =		rtc_open,
+	.release =	rtc_release,
 };
 
 static struct miscdevice rtc_dev=
diff -Nru a/arch/m68k/config.in b/arch/m68k/config.in
--- a/arch/m68k/config.in	Wed Jul 24 14:03:39 2002
+++ b/arch/m68k/config.in	Wed Jul 24 14:03:39 2002
@@ -374,11 +374,9 @@
    bool '    Support the Bell Technologies HUB6 card' CONFIG_HUB6
 fi
 
-if [ "$CONFIG_VME" = "n" ]; then
-   define_bool CONFIG_VT y
-   if [ "$CONFIG_VT" = "y" ]; then
-      bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
-   fi
+bool 'Virtual terminal' CONFIG_VT
+if [ "$CONFIG_VT" = "y" ]; then
+   bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
 fi
 
 if [ "$CONFIG_ATARI" = "y" ]; then
@@ -391,7 +389,7 @@
       define_bool CONFIG_BUSMOUSE y
    fi
 fi
-if [ "$CONFIG_ATARI" = "y" ]; then
+if [ "$CONFIG_ATARI" = "y" -a "$CONFIG_VT" = "y" ]; then
    tristate 'Atari mouse support' CONFIG_ATARIMOUSE
    if [ "$CONFIG_ATARIMOUSE" != "n" ]; then
       define_bool CONFIG_BUSMOUSE y
@@ -413,16 +411,16 @@
    if [ "$CONFIG_AMIGA_PCMCIA" = "y" ]; then
       tristate 'Hisoft Whippet PCMCIA serial support' CONFIG_WHIPPET_SERIAL
    fi
+   tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
+   fi
 fi
 if [ "$CONFIG_PARPORT" = "n" ]; then
    if [ "$CONFIG_ZORRO" = "y" ]; then
       tristate 'GVP IO-Extender support' CONFIG_GVPIOEXT
       dep_tristate '  GVP IO-Extender parallel printer support' CONFIG_GVPIOEXT_LP $CONFIG_GVPIOEXT
       dep_tristate '  GVP IO-Extender PLIP support' CONFIG_GVPIOEXT_PLIP $CONFIG_GVPIOEXT
-      tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-        tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
-      fi
    fi
 fi
 if [ "$CONFIG_MAC" = "y" ]; then
@@ -465,21 +463,7 @@
    define_bool CONFIG_SUN_MOUSE n
    define_bool CONFIG_SBUS n
 fi
-
-if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_ATARI" = "y" -o \
-     "$CONFIG_MAC" = "y" -o "$CONFIG_HP300" = "y" -o \
-     "$CONFIG_SUN3" = "y" -o "$CONFIG_SUN3X" = "y" ]; then
-   if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \
-        "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_MAC_SCC" = "y" -o \
-        "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \
-        "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" -o \
-        "$CONFIG_HPDCA" = "y" -o "$CONFIG_SUN3X_ZS" = "y" -o \
-        "$CONFIG_SERIAL" = "y" ]; then
-      bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
-   fi
-fi
 if [ "$CONFIG_VME" = "y" ]; then
-   define_bool CONFIG_SERIAL_CONSOLE y
    if [ "$CONFIG_MVME147" = "y" ]; then
       bool 'SCC support for MVME147 serial ports' CONFIG_MVME147_SCC
    fi
@@ -493,10 +477,24 @@
 fi
 if [ "$CONFIG_APOLLO" = "y" ]; then
    bool 'Support for DN serial port (dummy)' CONFIG_DN_SERIAL
-   bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
-
    define_tristate CONFIG_SERIAL $CONFIG_DN_SERIAL
 fi 
+
+if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_ATARI" = "y" -o \
+     "$CONFIG_MAC" = "y" -o "$CONFIG_HP300" = "y" -o \
+     "$CONFIG_SUN3" = "y" -o "$CONFIG_SUN3X" = "y" -o \
+     "$CONFIG_VME" = "y" -o "$CONFIG_APOLLO" = "y" ]; then
+   if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \
+        "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_MAC_SCC" = "y" -o \
+        "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \
+        "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" -o \
+        "$CONFIG_HPDCA" = "y" -o "$CONFIG_SUN3X_ZS" = "y" -o \
+        "$CONFIG_SERIAL" = "y" -o "$CONFIG_MVME147_SCC" = "y" -o \
+	"$CONFIG_SERIAL167" = "y" -o "$CONFIG_MVME162_SCC" = "y" -o \
+	"$CONFIG_BVME6000_SCC" = "y" -o "$CONFIG_DN_SERIAL" = "y" ]; then
+      bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
+   fi
+fi
 bool 'Support for user serial device modules' CONFIG_USERIAL
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
@@ -530,7 +528,7 @@
 
 source fs/Config.in
 
-if [ "$CONFIG_VME" = "n" ]; then
+if [ "$CONFIG_VT" = "y" ]; then
    mainmenu_option next_comment
    comment 'Console drivers'
    source drivers/video/Config.in
diff -Nru a/arch/m68k/fpsp040/skeleton.S b/arch/m68k/fpsp040/skeleton.S
--- a/arch/m68k/fpsp040/skeleton.S	Wed Jul 24 14:03:36 2002
+++ b/arch/m68k/fpsp040/skeleton.S	Wed Jul 24 14:03:36 2002
@@ -381,9 +381,9 @@
 .Lnotkern:
 	SAVE_ALL_INT
 	GET_CURRENT(%d0)
-	tstl	%curptr@(TASK_NEEDRESCHED)
+	tstb	%curptr@(TASK_NEEDRESCHED)
 	jne	ret_from_exception	| deliver signals,
-						| reschedule etc..
+					| reschedule etc..
 	RESTORE_ALL
 
 |
diff -Nru a/arch/m68k/hp300/config.c b/arch/m68k/hp300/config.c
--- a/arch/m68k/hp300/config.c	Wed Jul 24 14:03:35 2002
+++ b/arch/m68k/hp300/config.c	Wed Jul 24 14:03:35 2002
@@ -29,10 +29,9 @@
 
 #ifdef CONFIG_VT
 extern int hp300_keyb_init(void);
-#else
-/* Dummy function for when there is no keyboard. */
-int __init hp300_keyb_init(void)
+static int hp300_kbdrate(struct kbd_repeat *k)
 {
+  return 0;
 }
 #endif
 
@@ -46,15 +45,6 @@
 }
 #endif
 
-static int hp300_kbdrate(struct kbd_repeat *k)
-{
-  return 0;
-}
-
-static void hp300_kbd_leds(unsigned int leds)
-{
-}
-
 static void hp300_get_model(char *model)
 {
   strcpy(model, "HP9000/300");
@@ -63,9 +53,10 @@
 void __init config_hp300(void)
 {
   mach_sched_init      = hp300_sched_init;
+#ifdef CONFIG_VT
   mach_keyb_init       = hp300_keyb_init;
   mach_kbdrate         = hp300_kbdrate;
-  mach_kbd_leds        = hp300_kbd_leds;
+#endif
   mach_init_IRQ        = hp300_init_IRQ;
   mach_request_irq     = hp300_request_irq;
   mach_free_irq        = hp300_free_irq;
diff -Nru a/arch/m68k/hp300/ints.c b/arch/m68k/hp300/ints.c
--- a/arch/m68k/hp300/ints.c	Wed Jul 24 14:03:36 2002
+++ b/arch/m68k/hp300/ints.c	Wed Jul 24 14:03:36 2002
@@ -22,6 +22,7 @@
 #include <asm/system.h>
 #include <asm/traps.h>
 #include <asm/ptrace.h>
+#include <asm/errno.h>
 #include "ints.h"
 
 /* Each ipl has a linked list of interrupt service routines.
@@ -142,7 +143,9 @@
         }
         /* remove the entry after t: */
         t->next->flags = IRQ_FLG_STD;
-        t->next->dev_id = t->next->devname = t->next->handler = NULL;
+        t->next->dev_id = NULL;
+	t->next->devname = NULL;
+	t->next->handler = NULL;
         t->next = t->next->next;
         
 	spin_unlock_irqrestore(&irqlist_lock, flags);
diff -Nru a/arch/m68k/ifpsp060/iskeleton.S b/arch/m68k/ifpsp060/iskeleton.S
--- a/arch/m68k/ifpsp060/iskeleton.S	Wed Jul 24 14:03:36 2002
+++ b/arch/m68k/ifpsp060/iskeleton.S	Wed Jul 24 14:03:36 2002
@@ -75,7 +75,7 @@
 .Lnotkern:
 	SAVE_ALL_INT
 	GET_CURRENT(%d0)
-	tstl	%curptr@(TASK_NEEDRESCHED)
+	tstb	%curptr@(TASK_NEEDRESCHED)
 	jne	ret_from_exception	| deliver signals,
 					| reschedule etc..
 	RESTORE_ALL
diff -Nru a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
--- a/arch/m68k/kernel/entry.S	Wed Jul 24 14:03:35 2002
+++ b/arch/m68k/kernel/entry.S	Wed Jul 24 14:03:35 2002
@@ -68,21 +68,11 @@
 	addql	#4,%sp
 	jra	ret_from_exception
 
-ENTRY(reschedule)
-	| save top of frame
-	movel	%sp,%curptr@(TASK_THREAD+THREAD_ESP0)
-
-	pea	ret_from_exception
-	jmp	schedule
-
-	| After a fork we jump here directly from resume,
-	| so that %d1 contains the previous task
-	| Theoretically only needed on SMP, but let's watch
-	| what happens in schedule_tail() in future...
+	| schedule_tail is only used with CONFIG_SMP
 ENTRY(ret_from_fork)
-	movel	%d1,%sp@-
+#ifdef CONFIG_SMP
 	jsr	schedule_tail
-	addql	#4,%sp
+#endif
 	jra	ret_from_exception
 
 badsys:
@@ -128,38 +118,54 @@
 	| save top of frame
 	movel	%sp,%curptr@(TASK_THREAD+THREAD_ESP0)
 
-	btst	#PT_TRACESYS_BIT,%curptr@(TASK_PTRACE+PT_TRACESYS_OFF)
+	tstb	%curptr@(TASK_SYSCALL_TRACE)
 	jne	do_trace
 	cmpl	#NR_syscalls,%d0
 	jcc	badsys
 	jbsr	@(sys_call_table,%d0:l:4)@(0)
 	movel	%d0,%sp@(PT_D0)		| save the return value
 
+	|oriw	#0x0700,%sr
+	movel	%curptr@(TASK_WORK),%d0
+	jne	syscall_exit_work
+1:	RESTORE_ALL
+
+syscall_exit_work:
+	btst	#5,%sp@(PT_SR)		| check if returning to kernel
+	bnes	1b			| if so, skip resched, signals
+	tstw	%d0
+	jeq	do_signal_return
+	tstb	%d0
+	jne	do_delayed_trace
+
+	pea	resume_userspace
+	jmp	schedule
+
 ret_from_exception:
 	btst	#5,%sp@(PT_SR)		| check if returning to kernel
-	bnes	2f			| if so, skip resched, signals
+	bnes	1f			| if so, skip resched, signals
 	| only allow interrupts when we are really the last one on the
 	| kernel stack, otherwise stack overflow can occur during
 	| heavy interrupt load
 	andw	#ALLOWINT,%sr
-	tstl	%curptr@(TASK_NEEDRESCHED)
-	jne	reschedule
-#if 0
-	cmpl	#task,%curptr		| task[0] cannot have signals
-	jeq	2f
-#endif
-					| check for delayed trace
-	bclr	#PT_DTRACE_BIT,%curptr@(TASK_PTRACE+PT_DTRACE_OFF)
-	jne	do_delayed_trace
-5:
-	tstl	%curptr@(TASK_STATE)	| state
-	jne	reschedule
-
-	tstl	%curptr@(TASK_SIGPENDING)
-	jne	Lsignal_return
-2:	RESTORE_ALL
 
-Lsignal_return:
+resume_userspace:
+	movel	%curptr@(TASK_WORK),%d0
+	lsrl	#8,%d0
+	jne	exit_work
+1:	RESTORE_ALL
+
+exit_work:
+	| save top of frame
+	movel	%sp,%curptr@(TASK_THREAD+THREAD_ESP0)
+	tstb	%d0
+	jeq	do_signal_return
+
+	pea	resume_userspace
+	jmp	schedule
+
+do_signal_return:
+	|andw	#ALLOWINT,%sr
 	subql	#4,%sp			| dummy return address
 	SAVE_SWITCH_STACK
 	pea	%sp@(SWITCH_STACK_SIZE)
@@ -168,7 +174,7 @@
 	addql	#8,%sp
 	RESTORE_SWITCH_STACK
 	addql	#4,%sp
-	RESTORE_ALL
+	jbra	resume_userspace
 
 do_delayed_trace:
 	bclr	#7,%sp@(PT_SR)		| clear trace bit in SR
@@ -178,13 +184,13 @@
 	jbsr	send_sig
 	addql	#8,%sp
 	addql	#4,%sp
-	jra	5b
+	jbra	resume_userspace
 
 
 #if 0
 #if CONFIG_AMIGA
 ami_inthandler:
-	addql	#1,irq_stat+8		| local_irq_count
+	addql	#1,irq_stat+CPUSTAT_LOCAL_IRQ_COUNT
 	SAVE_ALL_INT
 	GET_CURRENT(%d0)
 
@@ -216,14 +222,14 @@
 inthandler:
 	SAVE_ALL_INT
 	GET_CURRENT(%d0)
-	addql	#1,irq_stat+8		| local_irq_count
+	addql	#1,irq_stat+CPUSTAT_LOCAL_IRQ_COUNT
 					|  put exception # in d0
 	bfextu %sp@(PT_VECTOR){#4,#10},%d0
 
 	movel	%sp,%sp@-
 	movel	%d0,%sp@- 		|  put vector # on stack
 #if defined(MACH_Q40_ONLY) && defined(CONFIG_BLK_DEV_FD)
-	btstb	#4,0xff000000	| Q40 floppy needs very special treatment ...
+	btstb	#4,0xff000000		| Q40 floppy needs very special treatment ...
 	jbeq	1f
 	btstb	#3,0xff000004		
 	jbeq	1f
@@ -231,11 +237,11 @@
 	jbra	3f
 1:
 #endif		
-	jbsr	process_int|  process the IRQ
+	jbsr	process_int		|  process the IRQ
 3:     	addql	#8,%sp			|  pop parameters off stack
 
 ret_from_interrupt:
-	subql	#1,irq_stat+8		| local_irq_count
+	subql	#1,irq_stat+CPUSTAT_LOCAL_IRQ_COUNT
 	jeq	1f
 2:
 	RESTORE_ALL
@@ -248,11 +254,8 @@
 	jhi	2b
 #endif
 	/* check if we need to do software interrupts */
-
-	movel	irq_stat,%d0		| softirq_active
-	andl	irq_stat+4,%d0		| softirq_mask
+	tstl	irq_stat+CPUSTAT_SOFTIRQ_PENDING
 	jeq	ret_from_exception
-
 	pea	ret_from_exception
 	jra	do_softirq
 
@@ -460,7 +463,7 @@
 	.long sys_ni_syscall				/* old gtty syscall holder */
 	.long sys_access
 	.long sys_nice
-	.long sys_ni_syscall	/* 35 */		/* old ftime syscall holder */
+	.long sys_ni_syscall	/* 35 */	/* old ftime syscall holder */
 	.long sys_sync
 	.long sys_kill
 	.long sys_rename
@@ -477,7 +480,7 @@
 	.long sys_geteuid16
 	.long sys_getegid16	/* 50 */
 	.long sys_acct
-	.long sys_umount					/* recycled never used phys() */
+	.long sys_umount				/* recycled never used phys() */
 	.long sys_ni_syscall				/* old lock syscall holder */
 	.long sys_ioctl
 	.long sys_fcntl		/* 55 */
@@ -535,10 +538,10 @@
 	.long sys_newlstat
 	.long sys_newfstat
 	.long sys_ni_syscall
-	.long sys_ni_syscall	/* iopl for i386 */ /* 110 */
+	.long sys_ni_syscall	/* 110 */	/* iopl for i386 */
 	.long sys_vhangup
-	.long sys_ni_syscall	/* obsolete idle() syscall */
-	.long sys_ni_syscall	/* vm86old for i386 */
+	.long sys_ni_syscall				/* obsolete idle() syscall */
+	.long sys_ni_syscall				/* vm86old for i386 */
 	.long sys_wait4
 	.long sys_swapoff	/* 115 */
 	.long sys_sysinfo
@@ -548,7 +551,7 @@
 	.long sys_clone		/* 120 */
 	.long sys_setdomainname
 	.long sys_newuname
-	.long sys_cacheflush	/* modify_ldt for i386 */
+	.long sys_cacheflush				/* modify_ldt for i386 */
 	.long sys_adjtimex
 	.long sys_mprotect	/* 125 */
 	.long sys_sigprocmask
@@ -562,7 +565,7 @@
 	.long sys_bdflush
 	.long sys_sysfs		/* 135 */
 	.long sys_personality
-	.long sys_ni_syscall	/* for afs_syscall */
+	.long sys_ni_syscall				/* for afs_syscall */
 	.long sys_setfsuid16
 	.long sys_setfsgid16
 	.long sys_llseek	/* 140 */
@@ -580,7 +583,7 @@
 	.long sys_mlockall
 	.long sys_munlockall
 	.long sys_sched_setparam
-	.long sys_sched_getparam   /* 155 */
+	.long sys_sched_getparam	/* 155 */
 	.long sys_sched_setscheduler
 	.long sys_sched_getscheduler
 	.long sys_sched_yield
@@ -613,8 +616,8 @@
 	.long sys_capset	/* 185 */
 	.long sys_sigaltstack
 	.long sys_sendfile
-	.long sys_ni_syscall	/* streams1 */
-	.long sys_ni_syscall	/* streams2 */
+	.long sys_ni_syscall				/* streams1 */
+	.long sys_ni_syscall				/* streams2 */
 	.long sys_vfork		/* 190 */
 	.long sys_getrlimit
 	.long sys_mmap2
@@ -642,12 +645,25 @@
 	.long sys_setgid
 	.long sys_setfsuid	/* 215 */
 	.long sys_setfsgid
-	.long sys_ni_syscall
+	.long sys_pivot_root
 	.long sys_ni_syscall
 	.long sys_ni_syscall
 	.long sys_getdents64	/* 220 */
 	.long sys_gettid
 	.long sys_tkill
+	.long sys_setxattr
+	.long sys_lsetxattr
+	.long sys_fsetxattr	/* 225 */
+	.long sys_getxattr
+	.long sys_lgetxattr
+	.long sys_fgetxattr
+	.long sys_listxattr
+	.long sys_llistxattr	/* 230 */
+	.long sys_flistxattr
+	.long sys_removexattr
+	.long sys_lremovexattr
+	.long sys_fremovexattr
+	.long sys_futex		/* 235 */
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long sys_ni_syscall
diff -Nru a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S
--- a/arch/m68k/kernel/head.S	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/kernel/head.S	Wed Jul 24 14:03:38 2002
@@ -312,6 +312,9 @@
 #ifdef CONFIG_Q40
 .globl q40_mem_cptr	
 #endif		
+#ifdef CONFIG_HP300
+.globl hp300_phys_ram_base
+#endif
 
 CPUTYPE_040	= 1	/* indicates an 040 */
 CPUTYPE_060	= 2	/* indicates an 060 */
@@ -596,6 +599,64 @@
 __INIT
 ENTRY(__start)
 
+#ifdef CONFIG_HP300
+/* This is a hack.  The HP NetBSD bootloader loads us at an arbitrary
+   address (apparently 0xff002000 in practice) which is not good if we need
+   to be able to map this to VA 0x1000.  We could do it with pagetables but
+   a better solution seems to be to relocate the kernel in physical memory
+   before we start.  
+	
+   So, we copy the entire kernel image (code+data+bss) down to the 16MB
+   boundary that marks the start of RAM.  This is slightly tricky because
+   we must not overwrite the copying code itself. :-)  */
+
+/* 15/5/98.  The start address of physical RAM changes depending on how much
+   RAM is present.  This is actually a blessing in disguise as it provides
+   a way for us to work out the RAM size rather than hardwiring it.  */
+
+	lea	%pc@(_start),%a0
+	movel	%a0,%d6
+	and	#0xffff0000, %d6
+	lea	%pc@(hp300_phys_ram_base),%a0
+	movel	%d6, %a0@
+	movel	%pc@(L(custom)),%a3
+	moveb	#0xfe,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	lea	%pc@(Lcopystart),%a0
+	lea	%pc@(Lcopyend),%a1
+	movel	%d6,%a2			/* Start of physical RAM */
+1:	moveb	%a0@+,%d0
+	moveb	%d0,%a2@+
+	cmpl	%a0,%a1
+	jbne	1b
+	movel	%d6,%a2
+	moveb	#0xfd,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	lea	%pc@(_stext),%a0
+	lea	%pc@(_end),%a1
+	jmp	%a2@
+
+Lcopystart:
+	moveb	#0xf7,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	movel	%d6,%a2	/* Start of kernel */
+	add	#0x1000,%a2
+1:	moveb	%a0@+,%d0
+	moveb	%d0,%a2@+
+	cmpl	%a0,%a1
+	jbne	1b
+	moveb	#0,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	movel	%d6,%a0
+	addl	#Lstart1,%a0
+	jmp	%a0@
+Lcopyend:	
+
+Lstart1:
+	moveb	#0x3f,%d7
+	moveb	%d7,%a3@(0x1ffff)
+#endif /* CONFIG_HP300 */
+
 /*
  * Setup initial stack pointer
  */
@@ -605,6 +666,7 @@
  * Record the CPU and machine type.
  */
 
+#ifndef CONFIG_HP300
 	get_bi_record	BI_MACHTYPE
 	lea	%pc@(m68k_machtype),%a1
 	movel	%a0@,%a1@
@@ -620,6 +682,23 @@
 	get_bi_record	BI_CPUTYPE
 	lea	%pc@(m68k_cputype),%a1
 	movel	%a0@,%a1@
+#else /* CONFIG_HP300 */
+	/* FIXME HP300 doesn't use bootinfo yet */
+	movel	#MACH_HP300,%d4
+	lea	%pc@(m68k_machtype),%a0
+	movel	%d4,%a0@
+	movel	#FPU_68881,%d0
+	lea	%pc@(m68k_fputype),%a0
+	movel	%d0,%a0@
+	movel	#MMU_68030,%d0
+	lea	%pc@(m68k_mmutype),%a0
+	movel	%d0,%a0@
+	movel	#CPU_68030,%d0
+	lea	%pc@(m68k_cputype),%a0
+	movel	%d0,%a0@
+
+	leds(0x1)
+#endif /* CONFIG_HP300 */
 
 #ifdef CONFIG_MAC
 /*
@@ -893,6 +972,9 @@
 
 	putc	'\n'
 	putc	'A'
+#ifdef CONFIG_HP300
+	leds(0x2)
+#endif /* CONFIG_HP300 */
 	dputn	%pc@(L(cputype))
 	dputn	%pc@(m68k_supervisor_cachemode)
 	dputn	%pc@(m68k_pgtable_cachemode)
@@ -1461,8 +1543,8 @@
 /*
  * Setup initial stack pointer
  */
-	lea	init_task_union,%curptr
-	lea	0x2000(%curptr),%sp
+	lea	init_task,%curptr
+	lea	init_thread_union+THREAD_SIZE,%sp
 
 	putc	'K'
 
@@ -1490,6 +1572,7 @@
 
 	movel	ARG1,%d0
 	lea	%pc@(_end),%a0
+#ifndef CONFIG_HP300
 1:	tstw	%a0@(BIR_TAG)
 	jeq	3f
 	cmpw	%a0@(BIR_TAG),%d0
@@ -1503,6 +1586,7 @@
 3:	moveq	#-1,%d0
 	lea	%a0@(BIR_SIZE),%a0
 4:
+#endif /* CONFIG_HP300 */
 func_return	get_bi_record
 
 
@@ -3270,14 +3354,16 @@
 
 	/* Calculate font size */
 
-#if   defined(FONT_8x8)
-	lea	%pc@(font_vga_8x8), %a0
-#elif defined(FONT_8x16)
+#if   defined(FONT_8x8) && defined(CONFIG_FONT_8x8)
+	lea	%pc@(font_vga_8x8),%a0
+#elif defined(FONT_8x16) && defined(CONFIG_FONT_8x16)
 	lea	%pc@(font_vga_8x16),%a0
-#elif defined(FONT_6x11)
+#elif defined(FONT_6x11) && defined(CONFIG_FONT_6x11)
 	lea	%pc@(font_vga_6x11),%a0
-#else	/*   (FONT_8x8) default */
-	lea	%pc@(font_vga_8x8), %a0
+#elif defined(CONFIG_FONT_8x8) /* default */
+	lea	%pc@(font_vga_8x8),%a0
+#else /* no compiled-in font */
+	lea	0,%a0
 #endif
 
 	/*
@@ -3286,6 +3372,8 @@
 	 */
 	lea	%pc@(L(console_font)),%a1
 	movel	%a0,%a1@	/* store pointer to struct fbcon_font_desc in Lconsole_font */
+	tstl	%a0
+	jeq	1f
 
 	/*
 	 *	Calculate global maxs
@@ -3313,7 +3401,7 @@
 	/*
 	 * Initialization is complete
 	 */
-	moveml	%sp@+,%a0-%a4/%d0-%d7
+1:	moveml	%sp@+,%a0-%a4/%d0-%d7
 	rts
 
 L(console_put_stats):
@@ -3399,6 +3487,8 @@
 	lea	%pc@(L(mac_rowbytes)),%a0
 	movel	%a0@,%d5
 	movel	%pc@(L(console_font)),%a0
+	tstl	%a0
+	jeq	1f
 	mulul	%a0@(FBCON_FONT_DESC_HEIGHT),%d5	/* account for # scan lines per character */
 	addal	%d5,%a2
 
@@ -3453,13 +3543,15 @@
 	movel	%d0,%a1@+
 	dbra	%d6,console_scroll_clear_loop
 
-	moveml	%sp@+,%a0-%a4/%d0-%d7
+1:	moveml	%sp@+,%a0-%a4/%d0-%d7
 	rts
 
 
 func_start	console_putc,%a0/%a1/%d0-%d7
 
 	is_not_mac(console_exit)
+	tstl	%pc@(L(console_font))
+	jeq	console_exit
 
 	/* Output character in d7 on console.
 	 */
@@ -3731,7 +3823,12 @@
 __INITDATA
 	.align	4
 
-#if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || defined(CONFIG_HP300)
+#ifdef CONFIG_HP300
+hp300_phys_ram_base:
+#endif
+
+#if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || \
+    defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
 L(custom):
 L(iobase):
 	.long 0
@@ -3822,8 +3919,6 @@
 LSRB0        = 0x10412
 LTHRB0       = 0x10416
 LCPUCTRL     = 0x10100
-L(iobase):
-        .long 0
 #endif
 
 __FINIT
diff -Nru a/arch/m68k/kernel/m68k_defs.c b/arch/m68k/kernel/m68k_defs.c
--- a/arch/m68k/kernel/m68k_defs.c	Wed Jul 24 14:03:35 2002
+++ b/arch/m68k/kernel/m68k_defs.c	Wed Jul 24 14:03:35 2002
@@ -25,8 +25,11 @@
 	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
 	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
 	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
-#error	DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, work.sigpending));
-#error	DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, work.need_resched));
+	DEFINE(TASK_WORK, offsetof(struct task_struct, thread.work));
+	DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, thread.work.need_resched));
+	DEFINE(TASK_SYSCALL_TRACE, offsetof(struct task_struct, thread.work.syscall_trace));
+	DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, thread.work.sigpending));
+	DEFINE(TASK_NOTIFY_RESUME, offsetof(struct task_struct, thread.work.notify_resume));
 	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
 	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
 	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
@@ -65,6 +68,12 @@
 
 	/* offsets into the kernel_stat struct */
 	DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
+
+	/* offsets into the irq_cpustat_t struct */
+	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
+	DEFINE(CPUSTAT_LOCAL_IRQ_COUNT, offsetof(irq_cpustat_t, __local_irq_count));
+	DEFINE(CPUSTAT_LOCAL_BH_COUNT, offsetof(irq_cpustat_t, __local_bh_count));
+	DEFINE(CPUSTAT_SYSCALL_COUNT, offsetof(irq_cpustat_t, __syscall_count));
 
 	/* offsets into the bi_record struct */
 	DEFINE(BIR_TAG, offsetof(struct bi_record, tag));
diff -Nru a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
--- a/arch/m68k/kernel/process.c	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/kernel/process.c	Wed Jul 24 14:03:38 2002
@@ -24,6 +24,7 @@
 #include <linux/user.h>
 #include <linux/a.out.h>
 #include <linux/reboot.h>
+#include <linux/init_task.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -33,7 +34,7 @@
 #include <asm/pgtable.h>
 
 /*
- * Initial task structure. Make this a per-architecture thing,
+ * Initial task/thread structure. Make this a per-architecture thing,
  * because different architectures tend to have different
  * alignment requirements and potentially different initial
  * setup.
@@ -43,14 +44,34 @@
 static struct signal_struct init_signals = INIT_SIGNALS;
 struct mm_struct init_mm = INIT_MM(init_mm);
 
-union task_union init_task_union
-__attribute__((section("init_task"), aligned(THREAD_SIZE)))
-	= { task: INIT_TASK(init_task_union.task) };
+union thread_union init_thread_union
+__attribute__((section(".data.init_task"), aligned(THREAD_SIZE)))
+       = { INIT_THREAD_INFO(init_task) };
+
+/* initial task structure */
+struct task_struct init_task = INIT_TASK(init_task);
+
 
 asmlinkage void ret_from_fork(void);
 
 
 /*
+ * Return saved PC from a blocked thread
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+	extern void scheduling_functions_start_here(void);
+	extern void scheduling_functions_end_here(void);
+	struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
+	/* Check whether the thread is blocked in resume() */
+	if (sw->retpc > (unsigned long)scheduling_functions_start_here &&
+	    sw->retpc < (unsigned long)scheduling_functions_end_here)
+		return ((unsigned long *)sw->a6)[1];
+	else
+		return sw->retpc;
+}
+
+/*
  * The idle loop on an m68k..
  */
 void default_idle(void)
@@ -133,23 +154,26 @@
 	register long retval __asm__ ("d0");
 	register long clone_arg __asm__ ("d1") = flags | CLONE_VM;
 
+	retval = __NR_clone;
 	__asm__ __volatile__
 	  ("clrl %%d2\n\t"
 	   "trap #0\n\t"		/* Linux/m68k system call */
 	   "tstl %0\n\t"		/* child or parent */
 	   "jne 1f\n\t"			/* parent - jump */
 	   "lea %%sp@(%c7),%6\n\t"	/* reload current */
+	   "movel %6@,%6\n\t"
 	   "movel %3,%%sp@-\n\t"	/* push argument */
 	   "jsr %4@\n\t"		/* call fn */
 	   "movel %0,%%d1\n\t"		/* pass exit value */
-	   "movel %2,%0\n\t"		/* exit */
+	   "movel %2,%%d0\n\t"		/* exit */
 	   "trap #0\n"
 	   "1:"
-	   : "=d" (retval)
-	   : "0" (__NR_clone), "i" (__NR_exit),
+	   : "+d" (retval)
+	   : "i" (__NR_clone), "i" (__NR_exit),
 	     "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
 	     "i" (-THREAD_SIZE)
-	   : "d0", "d2");
+	   : "d2");
+
 	pid = retval;
 	}
 
@@ -366,7 +390,7 @@
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
 
-	stack_page = (unsigned long)p;
+	stack_page = (unsigned long)(p->thread_info);
 	fp = ((struct switch_stack *)p->thread.ksp)->a6;
 	do {
 		if (fp < stack_page+sizeof(struct task_struct) ||
diff -Nru a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
--- a/arch/m68k/kernel/ptrace.c	Wed Jul 24 14:03:37 2002
+++ b/arch/m68k/kernel/ptrace.c	Wed Jul 24 14:03:37 2002
@@ -98,12 +98,13 @@
 	/* make sure the single step bit is not set. */
 	tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
 	put_reg(child, PT_SR, tmp);
+	child->thread.work.delayed_trace = 0;
+	child->thread.work.syscall_trace = 0;
 }
 
 asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
 {
 	struct task_struct *child;
-	unsigned long flags;
 	int ret;
 
 	lock_kernel();
@@ -243,14 +244,16 @@
 			ret = -EIO;
 			if ((unsigned long) data > _NSIG)
 				break;
-			if (request == PTRACE_SYSCALL)
-				child->ptrace |= PT_TRACESYS;
-			else
-				child->ptrace &= ~PT_TRACESYS;
+			if (request == PTRACE_SYSCALL) {
+					child->thread.work.syscall_trace = ~0;
+			} else {
+					child->thread.work.syscall_trace = 0;
+			}
 			child->exit_code = data;
 			/* make sure the single step bit is not set. */
 			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
 			put_reg(child, PT_SR, tmp);
+			child->thread.work.delayed_trace = 0;
 			wake_up_process(child);
 			ret = 0;
 			break;
@@ -271,6 +274,7 @@
 	/* make sure the single step bit is not set. */
 			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
 			put_reg(child, PT_SR, tmp);
+			child->thread.work.delayed_trace = 0;
 			wake_up_process(child);
 			break;
 		}
@@ -281,9 +285,10 @@
 			ret = -EIO;
 			if ((unsigned long) data > _NSIG)
 				break;
-			child->ptrace &= ~PT_TRACESYS;
+			child->thread.work.syscall_trace = 0;
 			tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
 			put_reg(child, PT_SR, tmp);
+			child->thread.work.delayed_trace = 1;
 
 			child->exit_code = data;
 	/* give it a chance to run. */
@@ -354,7 +359,7 @@
 			break;
 	}
 out_tsk:
-	free_task_struct(child);
+	put_task_struct(child);
 out:
 	unlock_kernel();
 	return ret;
@@ -362,8 +367,8 @@
 
 asmlinkage void syscall_trace(void)
 {
-	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
-			!= (PT_PTRACED|PT_TRACESYS))
+	if (!current->thread.work.delayed_trace &&
+	    !current->thread.work.syscall_trace)
 		return;
 	current->exit_code = SIGTRAP;
 	current->state = TASK_STOPPED;
diff -Nru a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
--- a/arch/m68k/kernel/setup.c	Wed Jul 24 14:03:39 2002
+++ b/arch/m68k/kernel/setup.c	Wed Jul 24 14:03:39 2002
@@ -34,6 +34,7 @@
 #endif
 #ifdef CONFIG_ATARI
 #include <asm/atarihw.h>
+#include <asm/atari_stram.h>
 #endif
 #ifdef CONFIG_SUN3X
 #include <asm/dvma.h>
@@ -71,11 +72,12 @@
 
 void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata = NULL;
 /* machine dependent keyboard functions */
+#ifdef CONFIG_VT
 int (*mach_keyb_init) (void) __initdata = NULL;
 int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
 void (*mach_kbd_leds) (unsigned int) = NULL;
 int (*mach_kbd_translate)(unsigned char scancode, unsigned char *keycode, char raw_mode) = NULL;
-unsigned int SYSRQ_KEY;
+#endif
 /* machine dependent irq functions */
 void (*mach_init_IRQ) (void) __initdata = NULL;
 void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
@@ -103,13 +105,14 @@
 #endif
 
 #ifdef CONFIG_MAGIC_SYSRQ
+unsigned int SYSRQ_KEY;
 int mach_sysrq_key = -1;
 int mach_sysrq_shift_state = 0;
 int mach_sysrq_shift_mask = 0;
 char *mach_sysrq_xlate = NULL;
 #endif
 
-#if defined(CONFIG_ISA)
+#if defined(CONFIG_ISA) && defined(MULTI_ISA)
 int isa_type;
 int isa_sex;
 #endif
@@ -217,8 +220,20 @@
 	int i;
 	char *p, *q;
 
-	/* The bootinfo is located right after the kernel bss */
-	m68k_parse_bootinfo((const struct bi_record *)&_end);
+	if (!MACH_IS_HP300) {
+		/* The bootinfo is located right after the kernel bss */
+		m68k_parse_bootinfo((const struct bi_record *)&_end);
+	} else {
+		/* FIXME HP300 doesn't use bootinfo yet */
+		extern unsigned long hp300_phys_ram_base;
+		unsigned long hp300_mem_size = 0xffffffff-hp300_phys_ram_base;
+		m68k_cputype = CPU_68030;
+		m68k_fputype = FPU_68882;
+		m68k_memory[0].addr = hp300_phys_ram_base;
+		/* 0.5M fudge factor */
+		m68k_memory[0].size = hp300_mem_size-512*1024;
+		m68k_num_memory++;
+	}
 
 	if (CPU_IS_040)
 		m68k_is040or060 = 4;
@@ -371,7 +386,7 @@
 
 #ifdef CONFIG_ATARI
 	if (MACH_IS_ATARI)
-		atari_stram_reserve_pages(availmem);
+		atari_stram_reserve_pages((void *)availmem);
 #endif
 #ifdef CONFIG_SUN3X
 	if (MACH_IS_SUN3X) {
@@ -387,7 +402,7 @@
 	paging_init();
 
 /* set ISA defs early as possible */
-#if defined(CONFIG_ISA)
+#if defined(CONFIG_ISA) && defined(MULTI_ISA)
 #if defined(CONFIG_Q40) 
 	if (MACH_IS_Q40) {
 	    isa_type = Q40_ISA;
@@ -494,10 +509,10 @@
 {
 }
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	show_cpuinfo,
+	.start =	c_start,
+	.next =		c_next,
+	.stop =		c_stop,
+	.show =		show_cpuinfo,
 };
 
 int get_hardware_list(char *buffer)
@@ -513,7 +528,6 @@
 	strcpy(model, "Unknown m68k");
 
     len += sprintf(buffer+len, "Model:\t\t%s\n", model);
-    len += get_cpuinfo(buffer+len);
     for (mem = 0, i = 0; i < m68k_num_memory; i++)
 	mem += m68k_memory[i].size;
     len += sprintf(buffer+len, "System Memory:\t%ldK\n", mem>>10);
diff -Nru a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
--- a/arch/m68k/kernel/signal.c	Wed Jul 24 14:03:36 2002
+++ b/arch/m68k/kernel/signal.c	Wed Jul 24 14:03:36 2002
@@ -792,10 +792,10 @@
 		regs->stkadj = fsize;
 	}
 
-	err |= __put_user((current->exec_domain
-			   && current->exec_domain->signal_invmap
+	err |= __put_user((current_thread_info()->exec_domain
+			   && current_thread_info()->exec_domain->signal_invmap
 			   && sig < 32
-			   ? current->exec_domain->signal_invmap[sig]
+			   ? current_thread_info()->exec_domain->signal_invmap[sig]
 			   : sig),
 			  &frame->sig);
 
@@ -870,10 +870,10 @@
 		regs->stkadj = fsize;
 	}
 
-	err |= __put_user((current->exec_domain
-			   && current->exec_domain->signal_invmap
+	err |= __put_user((current_thread_info()->exec_domain
+			   && current_thread_info()->exec_domain->signal_invmap
 			   && sig < 32
-			   ? current->exec_domain->signal_invmap[sig]
+			   ? current_thread_info()->exec_domain->signal_invmap[sig]
 			   : sig),
 			  &frame->sig);
 	err |= __put_user(&frame->info, &frame->pinfo);
diff -Nru a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
--- a/arch/m68k/kernel/traps.c	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/kernel/traps.c	Wed Jul 24 14:03:38 2002
@@ -224,7 +224,7 @@
 		unsigned long addr = fp->un.fmt4.effaddr;
 
 		if (fslw & MMU060_MA)
-			addr = (addr + 7) & -8;
+			addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;
 
 		errorcode = 1;
 		if (fslw & MMU060_DESC_ERR) {
@@ -258,16 +258,12 @@
 
 	set_fs(MAKE_MM_SEG(wbs));
 
-	asm volatile (".chip 68040");
-
 	if (iswrite)
-		asm volatile ("ptestw (%0)" : : "a" (addr));
+		asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));
 	else
-		asm volatile ("ptestr (%0)" : : "a" (addr));
+		asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));
 
-	asm volatile ("movec %%mmusr,%0" : "=r" (mmusr));
-
-	asm volatile (".chip 68k");
+	asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));
 
 	set_fs(old_fs); 
 
@@ -455,6 +451,7 @@
 	unsigned char buserr_type = sun3_get_buserr ();
 	unsigned long addr, errorcode;
 	unsigned short ssw = fp->un.fmtb.ssw;
+	extern unsigned long _sun3_map_test_start, _sun3_map_test_end;
 
 #if DEBUG
 	if (ssw & (FC | FB))
@@ -494,6 +491,13 @@
 				printk ("Instruction fault at %#010lx\n",
 					fp->ptregs.pc);
 			if (ssw & DF) {
+				/* was this fault incurred testing bus mappings? */
+				if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) &&
+				   (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) {
+					send_fault_sig(&fp->ptregs);
+					return;
+				}
+
 				printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
 					ssw & RW ? "read" : "write",
 					fp->un.fmtb.daddr,
@@ -820,8 +824,9 @@
 
 static inline int kernel_text_address(unsigned long addr)
 {
+#ifdef CONFIG_MODULES
 	struct module *mod;
-	int retval = 0;
+#endif
 	extern char _stext, _etext;
 
 	if (addr >= (unsigned long) &_stext &&
@@ -833,14 +838,12 @@
 		/* mod_bound tests for addr being inside the vmalloc'ed
 		 * module area. Of course it'd be better to test only
 		 * for the .text subset... */
-		if (mod_bound(addr, 0, mod)) {
-			retval = 1;
-			break;
-		}
+		if (mod_bound(addr, 0, mod))
+			return 1;
 	}
 #endif
 
-	return retval;
+	return 0;
 }
 
 void show_trace(unsigned long *stack)
diff -Nru a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c
--- a/arch/m68k/mac/baboon.c	Wed Jul 24 14:03:36 2002
+++ b/arch/m68k/mac/baboon.c	Wed Jul 24 14:03:36 2002
@@ -19,8 +19,8 @@
 #include <asm/macints.h> 
 #include <asm/mac_baboon.h>
 
-/* #define DEBUG_BABOON /**/
-/* #define DEBUG_IRQS /**/
+/* #define DEBUG_BABOON */
+/* #define DEBUG_IRQS */
 
 int baboon_present,baboon_active;
 volatile struct baboon *baboon;
diff -Nru a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
--- a/arch/m68k/mac/config.c	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/mac/config.c	Wed Jul 24 14:03:38 2002
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 /* keyb */
 #include <linux/init.h>
+#include <linux/vt_kern.h>
 
 #define BOOTINFO_COMPAT_1_0
 #include <asm/setup.h>
@@ -47,6 +48,8 @@
 struct mac_booter_data mac_bi_data = {0,};
 int mac_bisize = sizeof mac_bi_data;
 
+struct mac_hw_present mac_hw_present;
+
 /* New m68k bootinfo stuff and videobase */
 
 extern int m68k_num_memory;
@@ -75,7 +78,6 @@
 extern void psc_init(void);
 extern void baboon_init(void);
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
 extern void mac_mksound(unsigned int, unsigned int);
 
 extern void nubus_sweep_video(void);
@@ -84,8 +86,6 @@
 extern void mac_debug_init(void);
 extern void mac_debugging_long(int, long);
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
-
 extern int mackbd_init_hw(void);
 extern void mackbd_leds(unsigned int leds);
 extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode);
@@ -206,7 +206,7 @@
 	if (!MACH_IS_MAC) {
 	  printk("ERROR: no Mac, but config_mac() called!! \n");
 	}
-	
+
 #ifdef CONFIG_VT
 #ifdef CONFIG_INPUT_ADBHID
 	mach_keyb_init       = mac_hid_init_hw;
@@ -227,8 +227,10 @@
 	mach_keyb_init       = mackbd_init_hw;
 	mach_kbd_leds        = mackbd_leds;
 	mach_kbd_translate   = mackbd_translate;
+#ifdef CONFIG_MAGIC_SYSRQ
 	mach_sysrq_xlate     = mackbd_sysrq_xlate;
 	SYSRQ_KEY = 0x69;
+#endif /* CONFIG_MAGIC_SYSRQ */
 #endif /* CONFIG_INPUT_ADBHID */
 #endif /* CONFIG_VT */
 
@@ -253,12 +255,16 @@
 	mach_reset           = mac_reset;
 	mach_halt            = mac_poweroff;
 	mach_power_off       = mac_poweroff;
+#ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp	         = &dummy_con;
+#endif
 	mach_max_dma_address = 0xffffffff;
 #if 0
 	mach_debug_init	 = mac_debug_init;
 #endif
+#ifdef CONFIG_VT
 	kd_mksound		 = mac_mksound;
+#endif
 #ifdef CONFIG_HEARTBEAT
 #if 0
 	mach_heartbeat = mac_heartbeat;
diff -Nru a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c
--- a/arch/m68k/mac/debug.c	Wed Jul 24 14:03:39 2002
+++ b/arch/m68k/mac/debug.c	Wed Jul 24 14:03:39 2002
@@ -36,7 +36,7 @@
 extern unsigned long mac_videodepth;
 extern unsigned long mac_rowbytes;
 
-extern void mac_serial_print(char *);
+extern void mac_serial_print(const char *);
 
 #define DEBUG_HEADS
 #undef DEBUG_SCREEN
@@ -137,7 +137,7 @@
  * TODO: serial debug code
  */
 
-struct SCC
+struct mac_SCC
  {
   u_char cha_b_ctrl;
   u_char char_dummy1;
@@ -148,7 +148,7 @@
   u_char cha_a_data;
  };
 
-# define scc (*((volatile struct SCC*)mac_bi_data.sccbase))
+# define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase))
 
 /* Flag that serial port is already initialized and used */
 int mac_SCC_init_done = 0;
@@ -159,9 +159,9 @@
 static int scc_port = -1;
 
 static struct console mac_console_driver = {
-	name:		"debug",
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
+	.name =		"debug",
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
 };
 
 /*
@@ -235,20 +235,6 @@
     }
 }
 
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(DEBUG_SERIAL)
-int mac_sccb_console_wait_key(struct console *co)
-{
-    int i;
-    do {
-	for( i = uSEC; i > 0; --i )
-		barrier();
-    } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */
-    for( i = uSEC; i > 0; --i )
-	barrier();
-    return( scc.cha_b_data );
-}
-
-#endif
 
 /* The following two functions do a quick'n'dirty initialization of the MFP or
  * SCC serial ports. They're used by the debugging interface, kgdb, and the
@@ -390,9 +376,6 @@
 	/* Mac printer port */
 	mac_init_scc_port( B9600|CS8, 1 );
 	mac_console_driver.write = mac_sccb_console_write;
-#ifdef CONFIG_SERIAL_CONSOLE
-	mac_console_driver.wait_key = mac_sccb_console_wait_key;
-#endif
 	scc_port = 1;
     }
 #endif
diff -Nru a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
--- a/arch/m68k/mac/macints.c	Wed Jul 24 14:03:39 2002
+++ b/arch/m68k/mac/macints.c	Wed Jul 24 14:03:39 2002
@@ -131,6 +131,7 @@
 #include <asm/mac_via.h>
 #include <asm/mac_psc.h>
 #include <asm/hwtest.h>
+#include <asm/errno.h>
 
 #include <asm/macints.h>
 
diff -Nru a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
--- a/arch/m68k/mac/misc.c	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/mac/misc.c	Wed Jul 24 14:03:38 2002
@@ -229,8 +229,8 @@
 	do {
 		if (++ct > 10) {
 			printk("via_read_time: couldn't get valid time, "
-			       "last read = 0x%08X and 0x%08X\n", last_result.idata,
-			       result.idata);
+			       "last read = 0x%08lx and 0x%08lx\n",
+			       last_result.idata, result.idata);
 			break;
 		}
 
diff -Nru a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
--- a/arch/m68k/mm/fault.c	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/mm/fault.c	Wed Jul 24 14:03:38 2002
@@ -152,22 +152,25 @@
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
+
+ survive:
 	fault = handle_mm_fault(mm, vma, address, write);
 #ifdef DEBUG
  	printk("handle_mm_fault returns %d\n",fault);
 #endif
-	if (fault < 0)
-		goto out_of_memory;
-	if (!fault)
+	switch (fault) {
+	case 1:
+		current->min_flt++;
+		break;
+	case 2:
+		current->maj_flt++;
+		break;
+	case 0:
 		goto bus_err;
+	default:
+		goto out_of_memory;
+	}
 
-	/* There seems to be a missing invalidate somewhere in do_no_page.
-	 * Until I found it, this one cures the problem and makes
-	 * 1.2 run on the 68040 (Martin Apel).
-	 */
-	#warning should be obsolete now...
-	if (CPU_IS_040_OR_060)
-		flush_tlb_page(vma, address);
 	up_read(&mm->mmap_sem);
 	return 0;
 
@@ -176,6 +179,13 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
+	up_read(&mm->mmap_sem);
+	if (current->pid == 1) {
+		yield();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
+	
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
diff -Nru a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c
--- a/arch/m68k/mm/init.c	Wed Jul 24 14:03:37 2002
+++ b/arch/m68k/mm/init.c	Wed Jul 24 14:03:37 2002
@@ -36,17 +36,11 @@
 mmu_gather_t mmu_gathers[NR_CPUS];
 
 /*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving an inode
- * unused etc..
- *
  * ZERO_PAGE is a special page that is used for zero-initialized
  * data and COW.
  */
 
-unsigned long empty_zero_page;
+void *empty_zero_page;
 
 void show_mem(void)
 {
diff -Nru a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c
--- a/arch/m68k/mm/memory.c	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/mm/memory.c	Wed Jul 24 14:03:38 2002
@@ -77,14 +77,14 @@
 	 * virtual address space to be noncacheable.
 	 */
 	if (mask == 0) {
-		unsigned long page;
+		void *page;
 		ptable_desc *new;
 
-		if (!(page = get_free_page (GFP_KERNEL)))
+		if (!(page = (void *)get_free_page(GFP_KERNEL)))
 			return 0;
 
 		flush_tlb_kernel_page(page);
-		nocache_page (page);
+		nocache_page(page);
 
 		new = PD_PTABLE(page);
 		PD_MARKBITS(new) = 0xfe;
@@ -119,7 +119,7 @@
 	if (PD_MARKBITS(dp) == 0xff) {
 		/* all tables in page are free, free page */
 		list_del(dp);
-		cache_page (page);
+		cache_page((void *)page);
 		free_page (page);
 		return 1;
 	} else if (ptable_list.next != dp) {
@@ -185,10 +185,6 @@
 		}
 		voff -= m68k_memory[i].size;
 	} while (++i < m68k_num_memory);
-
-	/* As a special case allow `__pa(high_memory)'.  */
-	if (voff == 0)
-		return m68k_memory[i-1].addr + m68k_memory[i-1].size;
 
 	/* As a special case allow `__pa(high_memory)'.  */
 	if (voff == 0)
diff -Nru a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
--- a/arch/m68k/mm/motorola.c	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/mm/motorola.c	Wed Jul 24 14:03:38 2002
@@ -52,9 +52,9 @@
 	ptablep = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
 
 	clear_page(ptablep);
-	__flush_page_to_ram((unsigned long) ptablep);
-	flush_tlb_kernel_page((unsigned long) ptablep);
-	nocache_page ((unsigned long)ptablep);
+	__flush_page_to_ram(ptablep);
+	flush_tlb_kernel_page(ptablep);
+	nocache_page(ptablep);
 
 	return ptablep;
 }
@@ -87,15 +87,15 @@
 #endif
 	}
 
-	if (((unsigned long)(last_pgtable + PTRS_PER_PMD) & ~PAGE_MASK) == 0) {
+	last_pgtable += PTRS_PER_PMD;
+	if (((unsigned long)last_pgtable & ~PAGE_MASK) == 0) {
 		last_pgtable = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
 
 		clear_page(last_pgtable);
-		__flush_page_to_ram((unsigned long)last_pgtable);
-		flush_tlb_kernel_page((unsigned long)last_pgtable);
-		nocache_page((unsigned long)last_pgtable);
-	} else
-		last_pgtable += PTRS_PER_PMD;
+		__flush_page_to_ram(last_pgtable);
+		flush_tlb_kernel_page(last_pgtable);
+		nocache_page(last_pgtable);
+	}
 
 	return last_pgtable;
 }
@@ -262,8 +262,8 @@
 	 * initialize the bad page table and bad page to point
 	 * to a couple of allocated pages
 	 */
-	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
-	memset((void *)empty_zero_page, 0, PAGE_SIZE);
+	empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
+	memset(empty_zero_page, 0, PAGE_SIZE);
 
 	/*
 	 * Set up SFC/DFC registers
diff -Nru a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
--- a/arch/m68k/mvme147/config.c	Wed Jul 24 14:03:37 2002
+++ b/arch/m68k/mvme147/config.c	Wed Jul 24 14:03:37 2002
@@ -21,6 +21,8 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/major.h>
+#include <linux/genhd.h>
+#include <linux/rtc.h>
 
 #include <asm/bootinfo.h>
 #include <asm/system.h>
@@ -48,7 +50,6 @@
 extern unsigned long mvme147_gettimeoffset (void);
 extern int mvme147_hwclk (int, struct rtc_time *);
 extern int mvme147_set_clock_mmss (unsigned long);
-extern void mvme147_check_partition (struct gendisk *hd, unsigned int dev);
 extern void mvme147_reset (void);
 extern void mvme147_waitbut(void);
 
@@ -101,8 +102,10 @@
 {
 	mach_max_dma_address	= 0x01000000;
 	mach_sched_init		= mvme147_sched_init;
+#ifdef CONFIG_VT
 	mach_keyb_init		= mvme147_keyb_init;
 	mach_kbdrate		= mvme147_kbdrate;
+#endif
 	mach_init_IRQ		= mvme147_init_IRQ;
 	mach_gettimeoffset	= mvme147_gettimeoffset;
 	mach_hwclk		= mvme147_hwclk;
diff -Nru a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
--- a/arch/m68k/mvme16x/config.c	Wed Jul 24 14:03:37 2002
+++ b/arch/m68k/mvme16x/config.c	Wed Jul 24 14:03:37 2002
@@ -22,6 +22,8 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/major.h>
+#include <linux/genhd.h>
+#include <linux/rtc.h>
 
 #include <asm/bootinfo.h>
 #include <asm/system.h>
@@ -52,7 +54,6 @@
 extern unsigned long mvme16x_gettimeoffset (void);
 extern int mvme16x_hwclk (int, struct rtc_time *);
 extern int mvme16x_set_clock_mmss (unsigned long);
-extern void mvme16x_check_partition (struct gendisk *hd, unsigned int dev);
 extern void mvme16x_mksound( unsigned int count, unsigned int ticks );
 extern void mvme16x_reset (void);
 extern void mvme16x_waitbut(void);
@@ -143,13 +144,17 @@
 
     mach_max_dma_address = 0xffffffff;
     mach_sched_init      = mvme16x_sched_init;
+#ifdef CONFIG_VT
     mach_keyb_init       = mvme16x_keyb_init;
     mach_kbdrate         = mvme16x_kbdrate;
+#endif
     mach_init_IRQ        = mvme16x_init_IRQ;
     mach_gettimeoffset   = mvme16x_gettimeoffset;
     mach_hwclk           = mvme16x_hwclk;
     mach_set_clock_mmss	 = mvme16x_set_clock_mmss;
+#ifdef CONFIG_VT
 /*  kd_mksound           = mvme16x_mksound; */
+#endif
     mach_reset		 = mvme16x_reset;
     mach_free_irq	 = mvme16x_free_irq;
     mach_process_int	 = mvme16x_process_int;
diff -Nru a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
--- a/arch/m68k/mvme16x/rtc.c	Wed Jul 24 14:03:39 2002
+++ b/arch/m68k/mvme16x/rtc.c	Wed Jul 24 14:03:39 2002
@@ -150,9 +150,9 @@
  */
 
 static struct file_operations rtc_fops = {
-	ioctl:		rtc_ioctl,
-	open:		rtc_open,
-	release:	rtc_release,
+	.ioctl =	rtc_ioctl,
+	.open =		rtc_open,
+	.release =	rtc_release,
 };
 
 static struct miscdevice rtc_dev=
diff -Nru a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
--- a/arch/m68k/q40/config.c	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/q40/config.c	Wed Jul 24 14:03:38 2002
@@ -23,6 +23,7 @@
 #include <linux/major.h>
 #include <linux/serial_reg.h>
 #include <linux/rtc.h>
+#include <linux/vt_kern.h>
 
 #include <asm/io.h>
 #include <asm/rtc.h>
@@ -61,7 +62,6 @@
 extern void q40_waitbut(void);
 void q40_set_vectors (void);
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
 void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ );
 
 extern char *saved_command_line;
@@ -72,9 +72,9 @@
 extern int ql_ticks;
 
 static struct console q40_console_driver = {
-	name:		"debug",
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
+	.name =		"debug",
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
 };
 
 
@@ -162,42 +162,6 @@
     sprintf(model, "Q40");
 }
 
-/* pasted code to make parport_pc happy */
-extern __inline__ int __get_order(unsigned long size)
-{
-	int order;
-
-	size = (size-1) >> (PAGE_SHIFT-1);
-	order = -1;
-	do {
-		size >>= 1;
-		order++;
-	} while (size);
-	return order;
-}
-void *pci_alloc_consistent(void *hwdev, size_t size,
-			   dma_addr_t *dma_handle)
-{
-	void *ret;
-	int gfp = GFP_ATOMIC;
-
-	ret = (void *)__get_free_pages(gfp, __get_order(size));
-
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*dma_handle = virt_to_bus(ret);
-	}
-	return ret;
-}
-
-void pci_free_consistent(void *hwdev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
-{
-	free_pages((unsigned long)vaddr, __get_order(size));
-}
-/* end pasted code */
-
-
 /* No hardware options on Q40? */
 
 static int q40_get_hardware_list(char *buffer)
@@ -221,8 +185,10 @@
 {
     mach_sched_init      = q40_sched_init;
 
+#ifdef CONFIG_VT
     mach_keyb_init       = q40kbd_init_hw;
     mach_kbd_translate   = q40kbd_translate;
+#endif
     mach_init_IRQ        = q40_init_IRQ;   
     mach_gettimeoffset   = q40_gettimeoffset; 
     mach_hwclk           = q40_hwclk; 
@@ -238,7 +204,9 @@
     mach_default_handler = &q40_sys_default_handler;
     mach_get_model       = q40_get_model;
     mach_get_hardware_list = q40_get_hardware_list;
+#ifdef CONFIG_VT
     kd_mksound             = q40_mksound;
+#endif
 
 #ifdef CONFIG_MAGIC_SYSRQ
     mach_sysrq_key       = 0x54;
@@ -247,7 +215,9 @@
     mach_heartbeat = q40_heartbeat;
 #endif
     mach_halt = q40_halt;
+#ifdef CONFIG_DUMMY_CONSOLE
     conswitchp = &dummy_con;
+#endif
 
     /* disable a few things that SMSQ might have left enabled */
     q40_disable_irqs();
diff -Nru a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
--- a/arch/m68k/sun3/config.c	Wed Jul 24 14:03:38 2002
+++ b/arch/m68k/sun3/config.c	Wed Jul 24 14:03:38 2002
@@ -151,7 +151,9 @@
         mach_default_handler = &sun3_default_handler;
         mach_request_irq     =  sun3_request_irq;
         mach_free_irq        =  sun3_free_irq;
+#ifdef CONFIG_VT
 //	mach_keyb_init       =  sun3_keyb_init;
+#endif
 	enable_irq     	     =  sun3_enable_irq;
         disable_irq  	     =  sun3_disable_irq;
 	mach_process_int     =  sun3_process_int;
@@ -162,7 +164,7 @@
 	mach_hwclk           =  sun3_hwclk;
 	mach_halt	     =  sun3_halt;
 	mach_get_hardware_list = sun3_get_hardware_list;
-#if !defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_FB)
+#if !defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE)
 	conswitchp 	     = &dummy_con;
 #endif
 
@@ -175,8 +177,9 @@
 	
 	sun3_bootmem_alloc(memory_start, memory_end);
 
+#ifdef CONFIG_SUN3X_ZS
 	sun_serial_setup();
-
+#endif
 }
 
 void __init sun3_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
diff -Nru a/arch/m68k/sun3x/config.c b/arch/m68k/sun3x/config.c
--- a/arch/m68k/sun3x/config.c	Wed Jul 24 14:03:35 2002
+++ b/arch/m68k/sun3x/config.c	Wed Jul 24 14:03:35 2002
@@ -61,9 +61,11 @@
 	mach_get_irq_list	 = show_sun3_interrupts;
 	mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */
 
+#ifdef CONFIG_VT
 	mach_keyb_init       = sun3x_keyb_init;
 	mach_kbdrate         = sun3x_kbdrate;
 	mach_kbd_leds        = sun3x_kbd_leds;
+#endif
 
 	mach_default_handler = &sun3_default_handler;
 	mach_sched_init      = sun3x_sched_init;
diff -Nru a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c
--- a/arch/mips/baget/irq.c	Wed Jul 24 14:03:38 2002
+++ b/arch/mips/baget/irq.c	Wed Jul 24 14:03:38 2002
@@ -186,7 +186,7 @@
 	action = *(irq + irq_action);
 	if (action) {
 		if (!(action->flags & SA_INTERRUPT))
-			__sti();
+			local_irq_enable();
 		action = *(irq + irq_action);
 		do_random = 0;
         	do {
@@ -196,7 +196,7 @@
         	} while (action);
 		if (do_random & SA_SAMPLE_RANDOM)
 			add_interrupt_randomness(irq);
-		__cli();
+		local_irq_disable();
 	} else {
 		printk("do_IRQ: Unregistered IRQ (0x%X) occurred\n", irq);
 	}
diff -Nru a/arch/mips/dec/irq.c b/arch/mips/dec/irq.c
--- a/arch/mips/dec/irq.c	Wed Jul 24 14:03:38 2002
+++ b/arch/mips/dec/irq.c	Wed Jul 24 14:03:38 2002
@@ -136,7 +136,7 @@
     action = *(irq + irq_action);
     if (action) {
 	if (!(action->flags & SA_INTERRUPT))
-	    __sti();
+	    local_irq_enable();
 	action = *(irq + irq_action);
 	do_random = 0;
 	do {
@@ -146,7 +146,7 @@
 	} while (action);
 	if (do_random & SA_SAMPLE_RANDOM)
 	    add_interrupt_randomness(irq);
-	__cli();
+	local_irq_disable();
 	unmask_irq(irq);
     }
     irq_exit(cpu, irq);
diff -Nru a/arch/mips/gt64120/momenco_ocelot/irq.c b/arch/mips/gt64120/momenco_ocelot/irq.c
--- a/arch/mips/gt64120/momenco_ocelot/irq.c	Wed Jul 24 14:03:35 2002
+++ b/arch/mips/gt64120/momenco_ocelot/irq.c	Wed Jul 24 14:03:35 2002
@@ -147,7 +147,7 @@
 	 * int-handler is not on bootstrap
 	 */
 	clear_cp0_status(ST0_IM | ST0_BEV);
-	__cli();
+	local_irq_disable();
 
 	/* Sets the first-level interrupt dispatcher. */
 	set_except_vector(0, ocelot_handle_int);
diff -Nru a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
--- a/arch/mips/ite-boards/generic/irq.c	Wed Jul 24 14:03:38 2002
+++ b/arch/mips/ite-boards/generic/irq.c	Wed Jul 24 14:03:38 2002
@@ -271,12 +271,12 @@
 		//mask_irq(1<<irq);
 		//printk("action->handler %x\n", action->handler);
 		disable_it8172_irq(irq);
-		//if (!(action->flags & SA_INTERRUPT)) __sti(); /* reenable ints */
+		//if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); /* reenable ints */
 		do { 
 			action->handler(irq, action->dev_id, regs);
 			action = action->next;
 		} while ( action );
-		//__cli(); /* disable ints */
+		//local_irq_disable(); /* disable ints */
 		if (irq_desc[irq].handler)
 		{
 		}
diff -Nru a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c
--- a/arch/mips/ite-boards/generic/time.c	Wed Jul 24 14:03:37 2002
+++ b/arch/mips/ite-boards/generic/time.c	Wed Jul 24 14:03:37 2002
@@ -168,7 +168,7 @@
 	unsigned long count;
 	unsigned int flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Start counter exactly on falling edge of update flag */
 	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
@@ -184,7 +184,7 @@
 	count = read_32bit_cp0_register(CP0_COUNT);
 
 	/* restore interrupts */
-	__restore_flags(flags);
+	local_irq_restore(flags);
 		
 	return (count / HZ);
 }
diff -Nru a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
--- a/arch/mips/kernel/irq.c	Wed Jul 24 14:03:36 2002
+++ b/arch/mips/kernel/irq.c	Wed Jul 24 14:03:36 2002
@@ -114,7 +114,7 @@
 	status = 1;	/* Force the "do bottom halves" bit */
 
 	if (!(action->flags & SA_INTERRUPT))
-		__sti();
+		local_irq_enable();
 
 	do {
 		status |= action->flags;
@@ -123,7 +123,7 @@
 	} while (action);
 	if (status & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	__cli();
+	local_irq_disable();
 
 	irq_exit(cpu, irq);
 
diff -Nru a/arch/mips/kernel/old-irq.c b/arch/mips/kernel/old-irq.c
--- a/arch/mips/kernel/old-irq.c	Wed Jul 24 14:03:38 2002
+++ b/arch/mips/kernel/old-irq.c	Wed Jul 24 14:03:38 2002
@@ -183,7 +183,7 @@
 		goto out;
 
 	if (!(action->flags & SA_INTERRUPT))
-		__sti();
+		local_irq_enable();
 	action = *(irq + irq_action);
 	do_random = 0;
        	do {
@@ -193,7 +193,7 @@
        	} while (action);
 	if (do_random & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	__cli();
+	local_irq_disable();
 	unmask_irq (irq);
 
 out:
@@ -219,7 +219,7 @@
 	action = *(irq + irq_action);
 	if (action) {
 		if (!(action->flags & SA_INTERRUPT))
-			__sti();
+			local_irq_enable();
 		action = *(irq + irq_action);
 		do_random = 0;
         	do {
@@ -229,7 +229,7 @@
         	} while (action);
 		if (do_random & SA_SAMPLE_RANDOM)
 			add_interrupt_randomness(irq);
-		__cli();
+		local_irq_disable();
 	}
 	irq_exit(cpu, irq);
 
diff -Nru a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
--- a/arch/mips/kernel/ptrace.c	Wed Jul 24 14:03:38 2002
+++ b/arch/mips/kernel/ptrace.c	Wed Jul 24 14:03:38 2002
@@ -174,10 +174,10 @@
 		case FPC_EIR: {	/* implementation / version register */
 			unsigned int flags;
 
-			__save_flags(flags);
+			local_save_flags(flags);
 			enable_cp1();
 			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			break;
 		}
 		default:
diff -Nru a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
--- a/arch/mips/kernel/smp.c	Wed Jul 24 14:03:36 2002
+++ b/arch/mips/kernel/smp.c	Wed Jul 24 14:03:36 2002
@@ -281,9 +281,9 @@
 				printk("Count spun out.  Huh?\n");
 				count = ~0;
 			}
-			__sti();
+			local_irq_enable();
 			SYNC_OTHER_CORES(cpu);
-			__cli();
+			local_irq_disable();
 			if (irqs_running())
 				continue;
 			if (spin_is_locked(&global_irq_lock))
@@ -335,10 +335,10 @@
 {
 	unsigned int flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	if (flags & ST0_IE) {
 		int cpu = smp_processor_id();
-		__cli();
+		local_irq_disable();
 		if (!local_irq_count(cpu))
 			get_irqlock(cpu);
 	}
@@ -350,7 +350,7 @@
 
 	if (!local_irq_count(cpu))
 		release_irqlock(cpu);
-	__sti();
+	local_irq_enable();
 }
 
 /*
@@ -367,7 +367,7 @@
 	unsigned long flags;
 	int cpu = smp_processor_id();
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	local_enabled = (flags & ST0_IE);
 	/* default to local */
 	retval = 2 + local_enabled;
@@ -393,10 +393,10 @@
 			__global_sti();
 			break;
 		case 2:
-			__cli();
+			local_irq_disable();
 			break;
 		case 3:
-			__sti();
+			local_irq_enable();
 			break;
 		default:
 			printk("global_restore_flags: %08lx\n", flags);
diff -Nru a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
--- a/arch/mips/lib/dump_tlb.c	Wed Jul 24 14:03:38 2002
+++ b/arch/mips/lib/dump_tlb.c	Wed Jul 24 14:03:38 2002
@@ -102,7 +102,7 @@
 	unsigned int flags, oldpid;
 	int index;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	oldpid = get_entryhi() & 0xff;
 	BARRIER;
 	set_entryhi((addr & PAGE_MASK) | oldpid);
@@ -111,7 +111,7 @@
 	BARRIER;
 	index = get_index();
 	set_entryhi(oldpid);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	if (index < 0) {
 		printk("No entry for address 0x%08lx in TLB\n", addr);
diff -Nru a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
--- a/arch/mips/lib/r3k_dump_tlb.c	Wed Jul 24 14:03:36 2002
+++ b/arch/mips/lib/r3k_dump_tlb.c	Wed Jul 24 14:03:36 2002
@@ -83,13 +83,13 @@
 	unsigned int flags, oldpid;
 	int index;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	oldpid = get_entryhi() & 0xff;
 	set_entryhi((addr & PAGE_MASK) | oldpid);
 	tlb_probe();
 	index = get_index();
 	set_entryhi(oldpid);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	if (index < 0) {
 		printk("No entry for address 0x%08lx in TLB\n", addr);
diff -Nru a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
--- a/arch/mips/mips-boards/generic/time.c	Wed Jul 24 14:03:38 2002
+++ b/arch/mips/mips-boards/generic/time.c	Wed Jul 24 14:03:38 2002
@@ -189,7 +189,7 @@
 	unsigned long count;
 	unsigned int flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Start counter exactly on falling edge of update flag */
 	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
@@ -205,7 +205,7 @@
 	count = read_32bit_cp0_register(CP0_COUNT);
 
 	/* restore interrupts */
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return (count / HZ);
 }
diff -Nru a/arch/mips/mm/mips32.c b/arch/mips/mm/mips32.c
--- a/arch/mips/mm/mips32.c	Wed Jul 24 14:03:39 2002
+++ b/arch/mips/mm/mips32.c	Wed Jul 24 14:03:39 2002
@@ -161,18 +161,18 @@
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache(); blast_icache(); blast_scache();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void mips32_flush_cache_all_pc(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache(); blast_icache();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void
@@ -198,7 +198,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -208,7 +208,7 @@
 					blast_scache_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -225,9 +225,9 @@
 #ifdef DEBUG_CACHE
 		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		blast_dcache(); blast_icache();
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -279,7 +279,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -309,7 +309,7 @@
 	} else
 		blast_scache_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void mips32_flush_cache_page_pc(struct vm_area_struct *vma,
@@ -331,7 +331,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -360,7 +360,7 @@
 		blast_dcache_page_indexed(page);
 	}
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /* If the addresses passed to these routines are valid, they are
@@ -420,7 +420,7 @@
 	if (size >= dcache_size) {
 		flush_cache_all();
 	} else {
-	        __save_and_cli(flags);
+	        local_irq_save(flags);
 		a = addr & ~(dc_lsize - 1);
 		end = (addr + size) & ~(dc_lsize - 1);
 		while (1) {
@@ -428,7 +428,7 @@
 			if (a == end) break;
 			a += dc_lsize;
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 	bc_wback_inv(addr, size);
 }
@@ -461,7 +461,7 @@
 	if (size >= dcache_size) {
 		flush_cache_all();
 	} else {
-	        __save_and_cli(flags);
+	        local_irq_save(flags);
 		a = addr & ~(dc_lsize - 1);
 		end = (addr + size) & ~(dc_lsize - 1);
 		while (1) {
@@ -469,7 +469,7 @@
 			if (a == end) break;
 			a += dc_lsize;
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 
 	bc_inv(addr, size);
@@ -524,7 +524,7 @@
 	printk("[tlball]");
 #endif
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
 	old_ctx = (get_entryhi() & 0xff);
 	set_entryhi(KSEG0);
@@ -546,7 +546,7 @@
 	}
 	BARRIER;
 	set_entryhi(old_ctx);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 void flush_tlb_mm(struct mm_struct *mm)
@@ -557,11 +557,11 @@
 #ifdef DEBUG_TLB
 		printk("[tlbmm<%d>]", mm->context);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		get_new_mmu_context(mm, asid_cache);
 		if (mm == current->active_mm)
 			set_entryhi(mm->context & 0xff);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -576,7 +576,7 @@
 		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
 		       start, end);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
 		if(size <= mips_cpu.tlbsize/2) {
@@ -611,7 +611,7 @@
 			if (mm == current->active_mm)
 				set_entryhi(mm->context & 0xff);
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -626,7 +626,7 @@
 #endif
 		newpid = (vma->vm_mm->context & 0xff);
 		page &= (PAGE_MASK << 1);
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		oldpid = (get_entryhi() & 0xff);
 		set_entryhi(page | newpid);
 		BARRIER;
@@ -645,7 +645,7 @@
 	finish:
 		BARRIER;
 		set_entryhi(oldpid);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -693,7 +693,7 @@
 	}
 #endif
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	address &= (PAGE_MASK << 1);
 	set_entryhi(address | (pid));
 	pgdp = pgd_offset(vma->vm_mm, address);
@@ -716,7 +716,7 @@
 	BARRIER;
 	set_entryhi(pid);
 	BARRIER;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 void show_regs(struct pt_regs * regs)
@@ -752,7 +752,7 @@
         unsigned long old_pagemask;
         unsigned long old_ctx;
 
-        __save_and_cli(flags);
+        local_irq_save(flags);
         /* Save old context and create impossible VPN2 value */
         old_ctx = (get_entryhi() & 0xff);
         old_pagemask = get_pagemask();
@@ -772,7 +772,7 @@
         BARRIER;    
         set_pagemask (old_pagemask);
         flush_tlb_all();    
-        __restore_flags(flags);
+        local_irq_restore(flags);
 }
 
 /* Detect and size the various caches. */
@@ -895,7 +895,7 @@
 	/* This is such a bitch, you'd think they would make it
 	 * easy to do this.  Away you daemons of stupidity!
 	 */
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Fill each size-multiple cache line with a valid tag. */
 	pow2 = (64 * 1024);
@@ -939,7 +939,7 @@
 			break;
 		pow2 <<= 1;
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	addr -= begin;
 	printk("Secondary cache sized at %dK linesize %d bytes.\n",
 	       (int) (addr >> 10), sc_lsize);
diff -Nru a/arch/mips/mm/r4xx0.c b/arch/mips/mm/r4xx0.c
--- a/arch/mips/mm/r4xx0.c	Wed Jul 24 14:03:37 2002
+++ b/arch/mips/mm/r4xx0.c	Wed Jul 24 14:03:37 2002
@@ -209,7 +209,7 @@
 {
 	unsigned int flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	*(volatile unsigned int *)KSEG1;
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -236,7 +236,7 @@
 		 "I" (PAGE_SIZE),
 		 "i" (Create_Dirty_Excl_D)
 		:"$1","memory");
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
@@ -568,7 +568,7 @@
 	unsigned long reg1, reg2, reg3, reg4;
 	unsigned int flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
 		".set\tnoat\n\t"
@@ -627,7 +627,7 @@
 		:"0" (to), "1" (from),
 		 "I" (PAGE_SIZE),
 		 "i" (Create_Dirty_Excl_D));
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
@@ -911,81 +911,81 @@
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16(); blast_icache16(); blast_scache16();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s32d16i16(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16(); blast_icache16(); blast_scache32();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s64d16i16(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16(); blast_icache16(); blast_scache64();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s128d16i16(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16(); blast_icache16(); blast_scache128();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s32d32i32(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache32(); blast_icache32(); blast_scache32();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s64d32i32(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache32(); blast_icache32(); blast_scache64();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s128d32i32(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache32(); blast_icache32(); blast_scache128();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_d16i16(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16(); blast_icache16();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_d32i32(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache32(); blast_icache32();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void
@@ -1011,7 +1011,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1021,7 +1021,7 @@
 					blast_scache16_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -1049,7 +1049,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1059,7 +1059,7 @@
 					blast_scache32_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -1086,7 +1086,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1096,7 +1096,7 @@
 					blast_scache64_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -1123,7 +1123,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1133,7 +1133,7 @@
 					blast_scache128_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -1160,7 +1160,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1170,7 +1170,7 @@
 					blast_scache32_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -1197,7 +1197,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1207,7 +1207,7 @@
 					blast_scache64_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -1234,7 +1234,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1244,7 +1244,7 @@
 					blast_scache128_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -1261,9 +1261,9 @@
 #ifdef DEBUG_CACHE
 		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		blast_dcache16(); blast_icache16();
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -1279,9 +1279,9 @@
 #ifdef DEBUG_CACHE
 		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		blast_dcache32(); blast_icache32();
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -1399,7 +1399,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1429,7 +1429,7 @@
 	} else
 		blast_scache16_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
@@ -1451,7 +1451,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1480,7 +1480,7 @@
 	} else
 		blast_scache32_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
@@ -1502,7 +1502,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1531,7 +1531,7 @@
 	} else
 		blast_scache64_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
@@ -1553,7 +1553,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1583,7 +1583,7 @@
 	} else
 		blast_scache128_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
@@ -1605,7 +1605,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1635,7 +1635,7 @@
 	} else
 		blast_scache32_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
@@ -1657,7 +1657,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1687,7 +1687,7 @@
 	} else
 		blast_scache64_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma,
@@ -1709,7 +1709,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1738,7 +1738,7 @@
 	} else
 		blast_scache128_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
@@ -1760,7 +1760,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1789,7 +1789,7 @@
 		blast_dcache16_page_indexed(page);
 	}
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
@@ -1811,7 +1811,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1841,7 +1841,7 @@
 		blast_dcache32_page_indexed(page);
 	}
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
@@ -1863,7 +1863,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1893,7 +1893,7 @@
 		blast_dcache32_page_indexed(page ^ dcache_waybit);
 	}
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /* If the addresses passed to these routines are valid, they are
@@ -1939,9 +1939,9 @@
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);			/* For R4600 v1.7 bug.  */
+	local_irq_save(flags);			/* For R4600 v1.7 bug.  */
 	blast_dcache32_page((unsigned long)page_address(page));
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void
@@ -1993,7 +1993,7 @@
 		flush_cache_all();
 	} else {
 		/* Workaround for R4600 bug.  See comment above. */
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		*(volatile unsigned long *)KSEG1;
 
 		a = addr & ~(dc_lsize - 1);
@@ -2003,7 +2003,7 @@
 			if (a == end) break;
 			a += dc_lsize;
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 	bc_wback_inv(addr, size);
 }
@@ -2037,7 +2037,7 @@
 		flush_cache_all();
 	} else {
 		/* Workaround for R4600 bug.  See comment above. */
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		*(volatile unsigned long *)KSEG1;
 
 		a = addr & ~(dc_lsize - 1);
@@ -2047,7 +2047,7 @@
 			if (a == end) break;
 			a += dc_lsize;
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 
 	bc_inv(addr, size);
@@ -2094,7 +2094,7 @@
 {
 	unsigned int flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Clear internal cache refill buffer */
 	*(volatile unsigned int *)KSEG1;
@@ -2102,7 +2102,7 @@
 	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
 	protected_flush_icache_line(addr & ~(ic_lsize - 1));
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 #undef DEBUG_TLB
@@ -2118,7 +2118,7 @@
 	printk("[tlball]");
 #endif
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
 	old_ctx = (get_entryhi() & 0xff);
 	set_entryhi(KSEG0);
@@ -2138,7 +2138,7 @@
 	}
 	BARRIER;
 	set_entryhi(old_ctx);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 void flush_tlb_mm(struct mm_struct *mm)
@@ -2149,11 +2149,11 @@
 #ifdef DEBUG_TLB
 		printk("[tlbmm<%d>]", mm->context);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		get_new_mmu_context(mm, asid_cache);
 		if (mm == current->active_mm)
 			set_entryhi(mm->context & 0xff);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -2170,7 +2170,7 @@
 		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
 		       start, end);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
 		if(size <= mips_cpu.tlbsize/2) {
@@ -2204,7 +2204,7 @@
 			if (mm == current->active_mm)
 				set_entryhi(mm->context & 0xff);
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -2219,7 +2219,7 @@
 #endif
 		newpid = (vma->vm_mm->context & 0xff);
 		page &= (PAGE_MASK << 1);
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		oldpid = (get_entryhi() & 0xff);
 		set_entryhi(page | newpid);
 		BARRIER;
@@ -2237,7 +2237,7 @@
 	finish:
 		BARRIER;
 		set_entryhi(oldpid);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -2286,7 +2286,7 @@
 	}
 #endif
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	address &= (PAGE_MASK << 1);
 	set_entryhi(address | (pid));
 	pgdp = pgd_offset(vma->vm_mm, address);
@@ -2309,7 +2309,7 @@
 	BARRIER;
 	set_entryhi(pid);
 	BARRIER;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 #if 0
@@ -2322,7 +2322,7 @@
 	pte_t *ptep;
 	int idx;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	address &= (PAGE_MASK << 1);
 	set_entryhi(address | (get_entryhi() & 0xff));
 	pgdp = pgd_offset(vma->vm_mm, address);
@@ -2338,7 +2338,7 @@
 	else
 		tlb_write_indexed();
 	BARRIER;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 #endif
 
@@ -2375,7 +2375,7 @@
         unsigned long old_pagemask;
         unsigned long old_ctx;
 
-        __save_and_cli(flags);
+        local_irq_save(flags);
         /* Save old context and create impossible VPN2 value */
         old_ctx = (get_entryhi() & 0xff);
         old_pagemask = get_pagemask();
@@ -2395,7 +2395,7 @@
         BARRIER;    
         set_pagemask (old_pagemask);
         flush_tlb_all();    
-        __restore_flags(flags);
+        local_irq_restore(flags);
 }
 
 /* Detect and size the various r4k caches. */
@@ -2469,7 +2469,7 @@
 	/* This is such a bitch, you'd think they would make it
 	 * easy to do this.  Away you daemons of stupidity!
 	 */
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Fill each size-multiple cache line with a valid tag. */
 	pow2 = (64 * 1024);
@@ -2513,7 +2513,7 @@
 			break;
 		pow2 <<= 1;
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	addr -= begin;
 	printk("Secondary cache sized at %dK linesize %d bytes.\n",
 	       (int) (addr >> 10), sc_lsize);
diff -Nru a/arch/mips/mm/r5432.c b/arch/mips/mm/r5432.c
--- a/arch/mips/mm/r5432.c	Wed Jul 24 14:03:38 2002
+++ b/arch/mips/mm/r5432.c	Wed Jul 24 14:03:38 2002
@@ -554,7 +554,7 @@
 	printk("[tlball]");
 #endif
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
 	old_ctx = (get_entryhi() & 0xff);
 	set_entryhi(KSEG0);
@@ -574,7 +574,7 @@
 	}
 	BARRIER;
 	set_entryhi(old_ctx);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 void flush_tlb_mm(struct mm_struct *mm)
@@ -585,11 +585,11 @@
 #ifdef DEBUG_TLB
 		printk("[tlbmm<%d>]", mm->context);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		get_new_mmu_context(mm, asid_cache);
 		if (mm == current->active_mm)
 			set_entryhi(mm->context & 0xff);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -604,7 +604,7 @@
 		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
 		       start, end);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
 		if(size <= NTLB_ENTRIES_HALF) {
@@ -638,7 +638,7 @@
 			if (mm == current->active_mm)
 				set_entryhi(mm->context & 0xff);
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -653,7 +653,7 @@
 #endif
 		newpid = (vma->vm_mm->context & 0xff);
 		page &= (PAGE_MASK << 1);
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		oldpid = (get_entryhi() & 0xff);
 		set_entryhi(page | newpid);
 		BARRIER;
@@ -671,7 +671,7 @@
 	finish:
 		BARRIER;
 		set_entryhi(oldpid);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -720,7 +720,7 @@
 	}
 #endif
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	address &= (PAGE_MASK << 1);
 	set_entryhi(address | (pid));
 	pgdp = pgd_offset(vma->vm_mm, address);
@@ -743,7 +743,7 @@
 	BARRIER;
 	set_entryhi(pid);
 	BARRIER;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 void show_regs(struct pt_regs * regs)
@@ -779,7 +779,7 @@
         unsigned long old_pagemask;
         unsigned long old_ctx;
 
-        __save_and_cli(flags);
+        local_irq_save(flags);
         /* Save old context and create impossible VPN2 value */
         old_ctx = (get_entryhi() & 0xff);
         old_pagemask = get_pagemask();
@@ -799,7 +799,7 @@
         BARRIER;    
         set_pagemask (old_pagemask);
         flush_tlb_all();    
-        __restore_flags(flags);
+        local_irq_restore(flags);
 }
 
 /* Detect and size the various r4k caches. */
diff -Nru a/arch/mips/mm/rm7k.c b/arch/mips/mm/rm7k.c
--- a/arch/mips/mm/rm7k.c	Wed Jul 24 14:03:35 2002
+++ b/arch/mips/mm/rm7k.c	Wed Jul 24 14:03:35 2002
@@ -310,7 +310,7 @@
 	unsigned long old_ctx;
 	int entry;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
 	old_ctx = get_entryhi() & 0xff;
 	set_entryhi(KSEG0);
@@ -330,7 +330,7 @@
 	}
 	BARRIER;
 	set_entryhi(old_ctx);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 void flush_tlb_mm(struct mm_struct *mm)
@@ -338,11 +338,11 @@
 	if(mm->context != 0) {
 		unsigned long flags;
 
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		get_new_mmu_context(mm, asid_cache);
 		if (mm == current->mm)
 			set_entryhi(mm->context & 0xff);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -353,7 +353,7 @@
 		unsigned long flags;
 		int size;
 
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
 		if (size <= (ntlb_entries() / 2)) {
@@ -387,7 +387,7 @@
 			if(mm == current->mm)
 				set_entryhi(mm->context & 0xff);
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -399,7 +399,7 @@
 
 		newpid = (vma->vm_mm->context & 0xff);
 		page &= (PAGE_MASK << 1);
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		oldpid = (get_entryhi() & 0xff);
 		set_entryhi(page | newpid);
 		BARRIER;
@@ -417,7 +417,7 @@
 	finish:
 		BARRIER;
 		set_entryhi(oldpid);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -460,7 +460,7 @@
 
 	pid = get_entryhi() & 0xff;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	address &= (PAGE_MASK << 1);
 	set_entryhi(address | (pid));
 	pgdp = pgd_offset(vma->vm_mm, address);
@@ -483,7 +483,7 @@
 	BARRIER;
 	set_entryhi(pid);
 	BARRIER;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 void show_regs(struct pt_regs * regs)
@@ -519,7 +519,7 @@
         unsigned long old_pagemask;
         unsigned long old_ctx;
 
-        __save_and_cli(flags);
+        local_irq_save(flags);
         /* Save old context and create impossible VPN2 value */
         old_ctx = (get_entryhi() & 0xff);
         old_pagemask = get_pagemask();
@@ -539,7 +539,7 @@
         BARRIER;    
         set_pagemask (old_pagemask);
         flush_tlb_all();    
-        __restore_flags(flags);
+        local_irq_restore(flags);
 }
 
 /* Used for loading TLB entries before trap_init() has started, when we
@@ -557,7 +557,7 @@
         unsigned long old_pagemask;
         unsigned long old_ctx;
 
-        __save_and_cli(flags);
+        local_irq_save(flags);
         /* Save old context and create impossible VPN2 value */
         old_ctx = (get_entryhi() & 0xff);
         old_pagemask = get_pagemask();
@@ -582,7 +582,7 @@
         BARRIER;    
         set_pagemask (old_pagemask);
  out:
-        __restore_flags(flags);
+        local_irq_restore(flags);
 	return ret;
 }
 
diff -Nru a/arch/mips/mm/sb1.c b/arch/mips/mm/sb1.c
--- a/arch/mips/mm/sb1.c	Wed Jul 24 14:03:35 2002
+++ b/arch/mips/mm/sb1.c	Wed Jul 24 14:03:35 2002
@@ -67,7 +67,7 @@
 	unsigned long old_ctx;
 	int entry;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
 	old_ctx = (get_entryhi() & 0xff);
 	set_entrylo0(0);
@@ -78,7 +78,7 @@
 		tlb_write_indexed();
 	}
 	set_entryhi(old_ctx);
-	__restore_flags(flags);	
+	local_irq_restore(flags);	
 }
 
 
diff -Nru a/arch/mips/philips/nino/irq.c b/arch/mips/philips/nino/irq.c
--- a/arch/mips/philips/nino/irq.c	Wed Jul 24 14:03:35 2002
+++ b/arch/mips/philips/nino/irq.c	Wed Jul 24 14:03:35 2002
@@ -177,7 +177,7 @@
     action = *(irq + irq_action);
     if (action) {
 	if (!(action->flags & SA_INTERRUPT))
-	    __sti();
+	    local_irq_enable();
 	do_random = 0;
 	do {
 	    do_random |= action->flags;
@@ -187,7 +187,7 @@
 	if (do_random & SA_SAMPLE_RANDOM)
 	    add_interrupt_randomness(irq);
 	unmask_irq(irq);
-	__cli();
+	local_irq_disable();
     } else {
             IntClear1 = ~0;
             IntClear3 = ~0;
diff -Nru a/arch/mips/sgi/kernel/indy_sc.c b/arch/mips/sgi/kernel/indy_sc.c
--- a/arch/mips/sgi/kernel/indy_sc.c	Wed Jul 24 14:03:39 2002
+++ b/arch/mips/sgi/kernel/indy_sc.c	Wed Jul 24 14:03:39 2002
@@ -75,7 +75,7 @@
 	first_line = SC_INDEX(addr);
 	last_line = SC_INDEX(addr + size - 1);
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	if (first_line <= last_line) {
 		indy_sc_wipe(first_line, last_line);
 		goto out;
@@ -84,7 +84,7 @@
 	indy_sc_wipe(first_line, SC_SIZE - SC_LINE);
 	indy_sc_wipe(0, last_line);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void indy_sc_enable(void)
diff -Nru a/arch/mips64/kernel/ptrace.c b/arch/mips64/kernel/ptrace.c
--- a/arch/mips64/kernel/ptrace.c	Wed Jul 24 14:03:36 2002
+++ b/arch/mips64/kernel/ptrace.c	Wed Jul 24 14:03:36 2002
@@ -158,10 +158,10 @@
 			break;
 		case FPC_EIR: { /* implementation / version register */
 			unsigned int flags;
-			__save_flags(flags);
+			local_save_flags(flags);
 			set_cp0_status(ST0_CU1, ST0_CU1);
 			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			break;
 		}
 		default:
@@ -418,10 +418,10 @@
 			break;
 		case FPC_EIR: { /* implementation / version register */
 			unsigned int flags;
-			__save_flags(flags);
+			local_save_flags(flags);
 			set_cp0_status(ST0_CU1, ST0_CU1);
 			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			break;
 		}
 		default:
diff -Nru a/arch/mips64/lib/dump_tlb.c b/arch/mips64/lib/dump_tlb.c
--- a/arch/mips64/lib/dump_tlb.c	Wed Jul 24 14:03:39 2002
+++ b/arch/mips64/lib/dump_tlb.c	Wed Jul 24 14:03:39 2002
@@ -101,7 +101,7 @@
 	unsigned int flags, oldpid;
 	int index;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	oldpid = get_entryhi() & 0xff;
 	BARRIER;
 	set_entryhi((addr & PAGE_MASK) | oldpid);
@@ -110,7 +110,7 @@
 	BARRIER;
 	index = get_index();
 	set_entryhi(oldpid);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	if (index < 0) {
 		printk("No entry for address 0x%08lx in TLB\n", addr);
diff -Nru a/arch/mips64/mips-boards/generic/time.c b/arch/mips64/mips-boards/generic/time.c
--- a/arch/mips64/mips-boards/generic/time.c	Wed Jul 24 14:03:36 2002
+++ b/arch/mips64/mips-boards/generic/time.c	Wed Jul 24 14:03:36 2002
@@ -188,7 +188,7 @@
 	unsigned long count;
 	unsigned int flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Start counter exactly on falling edge of update flag */
 	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
@@ -204,7 +204,7 @@
 	count = read_32bit_cp0_register(CP0_COUNT);
 
 	/* restore interrupts */
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return (count / HZ);
 }
diff -Nru a/arch/mips64/mm/andes.c b/arch/mips64/mm/andes.c
--- a/arch/mips64/mm/andes.c	Wed Jul 24 14:03:35 2002
+++ b/arch/mips64/mm/andes.c	Wed Jul 24 14:03:35 2002
@@ -143,7 +143,7 @@
 	printk("[tlball]");
 #endif
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
 	old_ctx = get_entryhi() & 0xff;
 	set_entryhi(CKSEG0);
@@ -159,7 +159,7 @@
 		entry++;
 	}
 	set_entryhi(old_ctx);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void andes_flush_tlb_mm(struct mm_struct *mm)
@@ -170,11 +170,11 @@
 #ifdef DEBUG_TLB
 		printk("[tlbmm<%d>]", mm->context);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		get_new_cpu_mmu_context(mm, smp_processor_id());
 		if(mm == current->mm)
 			set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -192,7 +192,7 @@
 		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
 		       start, end);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
 		if(size <= NTLB_ENTRIES_HALF) {
@@ -223,7 +223,7 @@
 				set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 
 									0xff);
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -239,7 +239,7 @@
 #endif
 		newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff);
 		page &= (PAGE_MASK << 1);
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		oldpid = (get_entryhi() & 0xff);
 		set_entryhi(page | newpid);
 		tlb_probe();
@@ -253,7 +253,7 @@
 
 	finish:
 		set_entryhi(oldpid);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -275,7 +275,7 @@
 	if (current->active_mm != vma->vm_mm)
 		return;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	pid = get_entryhi() & 0xff;
 
 	if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) ||
@@ -301,7 +301,7 @@
 		tlb_write_indexed();
 	}
 	set_entryhi(pid);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void andes_show_regs(struct pt_regs *regs)
diff -Nru a/arch/mips64/mm/r4xx0.c b/arch/mips64/mm/r4xx0.c
--- a/arch/mips64/mm/r4xx0.c	Wed Jul 24 14:03:35 2002
+++ b/arch/mips64/mm/r4xx0.c	Wed Jul 24 14:03:35 2002
@@ -194,7 +194,7 @@
 {
 	unsigned int flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	*(volatile unsigned int *)KSEG1;
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -217,7 +217,7 @@
 		:"=r" (page)
 		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
 		:"$1", "memory");
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
@@ -473,7 +473,7 @@
 	unsigned long dummy1, dummy2, reg1, reg2;
 	unsigned int flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
 		".set\tnoat\n\t"
@@ -512,7 +512,7 @@
 		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
 		:"0" (to), "1" (from), "I" (PAGE_SIZE),
 		 "i" (Create_Dirty_Excl_D));
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
@@ -699,81 +699,81 @@
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16(); blast_icache16(); blast_scache16();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s32d16i16(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16(); blast_icache16(); blast_scache32();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s64d16i16(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16(); blast_icache16(); blast_scache64();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s128d16i16(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16(); blast_icache16(); blast_scache128();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s32d32i32(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache32(); blast_icache32(); blast_scache32();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s64d32i32(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache32(); blast_icache32(); blast_scache64();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_s128d32i32(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache32(); blast_icache32(); blast_scache128();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_d16i16(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16(); blast_icache16();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void r4k_flush_cache_all_d32i32(void)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache32(); blast_icache32();
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_range_s16d16i16(struct vm_area_struct *vma,
@@ -799,7 +799,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -809,7 +809,7 @@
 					blast_scache16_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -837,7 +837,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -847,7 +847,7 @@
 					blast_scache32_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -875,7 +875,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -885,7 +885,7 @@
 					blast_scache64_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -913,7 +913,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -923,7 +923,7 @@
 					blast_scache128_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -951,7 +951,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -961,7 +961,7 @@
 					blast_scache32_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -989,7 +989,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -999,7 +999,7 @@
 					blast_scache64_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -1027,7 +1027,7 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
+			local_irq_save(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1037,7 +1037,7 @@
 					blast_scache128_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -1054,9 +1054,9 @@
 #ifdef DEBUG_CACHE
 		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		blast_dcache16(); blast_icache16();
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -1072,9 +1072,9 @@
 #ifdef DEBUG_CACHE
 		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		blast_dcache32(); blast_icache32();
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -1192,7 +1192,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1221,7 +1221,7 @@
 	} else
 		blast_scache16_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
@@ -1243,7 +1243,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1271,7 +1271,7 @@
 	} else
 		blast_scache32_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
@@ -1293,7 +1293,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1322,7 +1322,7 @@
 	} else
 		blast_scache64_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
@@ -1344,7 +1344,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1374,7 +1374,7 @@
 	} else
 		blast_scache128_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
@@ -1396,7 +1396,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1427,7 +1427,7 @@
 	} else
 		blast_scache32_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
@@ -1449,7 +1449,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1480,7 +1480,7 @@
 	} else
 		blast_scache64_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma,
@@ -1502,7 +1502,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1531,7 +1531,7 @@
 	} else
 		blast_scache128_page(page);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
@@ -1553,7 +1553,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1581,7 +1581,7 @@
 		blast_dcache16_page_indexed(page);
 	}
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
@@ -1603,7 +1603,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1633,7 +1633,7 @@
 		blast_dcache32_page_indexed(page);
 	}
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
@@ -1655,7 +1655,7 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1685,7 +1685,7 @@
 		blast_dcache32_page_indexed(page ^ dcache_waybit);
 	}
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_page_to_ram_s16(struct page *page)
@@ -1712,18 +1712,18 @@
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache16_page((unsigned long)page_address(page));
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_page_to_ram_d32(struct page *page)
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	blast_dcache32_page((unsigned long)page_address(page));
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
@@ -1746,7 +1746,7 @@
 		flush_cache_l1();
 	} else {
 		/* Workaround for R4600 bug.  See comment above. */
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		*(volatile unsigned long *)KSEG1;
 
 		a = addr & ~((unsigned long)dc_lsize - 1);
@@ -1756,7 +1756,7 @@
 			if (a == end) break;
 			a += dc_lsize;
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 	bc_wback_inv(addr, size);
 }
@@ -1788,7 +1788,7 @@
 		flush_cache_l1();
 	} else {
 		/* Workaround for R4600 bug.  See comment above. */
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		*(volatile unsigned long *)KSEG1;
 
 		a = addr & ~((unsigned long)dc_lsize - 1);
@@ -1798,7 +1798,7 @@
 			if (a == end) break;
 			a += dc_lsize;
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 
 	bc_inv(addr, size);
@@ -1844,7 +1844,7 @@
 {
 	unsigned int flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Clear internal cache refill buffer */
 	*(volatile unsigned int *)KSEG1;
@@ -1852,7 +1852,7 @@
 	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
 	protected_flush_icache_line(addr & ~(ic_lsize - 1));
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 #undef DEBUG_TLB
@@ -1871,7 +1871,7 @@
 	printk("[tlball]");
 #endif
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
 	old_ctx = (get_entryhi() & 0xff);
 	set_entryhi(KSEG0);
@@ -1891,7 +1891,7 @@
 	}
 	BARRIER;
 	set_entryhi(old_ctx);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void r4k_flush_tlb_mm(struct mm_struct *mm)
@@ -1902,11 +1902,11 @@
 #ifdef DEBUG_TLB
 		printk("[tlbmm<%d>]", mm->context);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		get_new_cpu_mmu_context(mm, smp_processor_id());
 		if(mm == current->mm)
 			set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -1923,7 +1923,7 @@
 		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
 		       start, end);
 #endif
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
 		if(size <= NTLB_ENTRIES_HALF) {
@@ -1958,7 +1958,7 @@
 				set_entryhi(CPU_CONTEXT(smp_processor_id(), 
 								mm) & 0xff);
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -1973,7 +1973,7 @@
 #endif
 		newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff);
 		page &= (PAGE_MASK << 1);
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		oldpid = (get_entryhi() & 0xff);
 		set_entryhi(page | newpid);
 		BARRIER;
@@ -1991,7 +1991,7 @@
 	finish:
 		BARRIER;
 		set_entryhi(oldpid);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -2018,7 +2018,7 @@
 	if (current->active_mm != vma->vm_mm)
 		return;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	pid = (get_entryhi() & 0xff);
 
 #ifdef DEBUG_TLB
@@ -2052,7 +2052,7 @@
 	BARRIER;
 	set_entryhi(pid);
 	BARRIER;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 #if 0
@@ -2065,7 +2065,7 @@
 	pte_t *ptep;
 	int idx;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	address &= (PAGE_MASK << 1);
 	set_entryhi(address | (get_entryhi() & 0xff));
 	pgdp = pgd_offset(vma->vm_mm, address);
@@ -2081,7 +2081,7 @@
 	else
 		tlb_write_indexed();
 	BARRIER;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 #endif
 
@@ -2171,7 +2171,7 @@
 	/* This is such a bitch, you'd think they would make it
 	 * easy to do this.  Away you daemons of stupidity!
 	 */
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	/* Fill each size-multiple cache line with a valid tag. */
 	pow2 = (64 * 1024);
@@ -2207,7 +2207,7 @@
 			break;
 		pow2 <<= 1;
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	addr -= begin;
 	printk("Secondary cache sized at %dK linesize %d\n",
 	       (int) (addr >> 10), sc_lsize);
diff -Nru a/arch/mips64/sgi-ip22/ip22-int.c b/arch/mips64/sgi-ip22/ip22-int.c
--- a/arch/mips64/sgi-ip22/ip22-int.c	Wed Jul 24 14:03:36 2002
+++ b/arch/mips64/sgi-ip22/ip22-int.c	Wed Jul 24 14:03:36 2002
@@ -306,7 +306,7 @@
 	action = *(irq + irq_action);
 	if (action) {
 		if (!(action->flags & SA_INTERRUPT))
-			__sti();
+			local_irq_enable();
 		action = *(irq + irq_action);
 		do_random = 0;
 		do {
@@ -316,7 +316,7 @@
 		} while (action);
 		if (do_random & SA_SAMPLE_RANDOM)
 			add_interrupt_randomness(irq);
-		__cli();
+		local_irq_disable();
 	}
 	irq_exit(cpu, irq);
 
diff -Nru a/arch/mips64/sgi-ip22/ip22-sc.c b/arch/mips64/sgi-ip22/ip22-sc.c
--- a/arch/mips64/sgi-ip22/ip22-sc.c	Wed Jul 24 14:03:39 2002
+++ b/arch/mips64/sgi-ip22/ip22-sc.c	Wed Jul 24 14:03:39 2002
@@ -58,7 +58,7 @@
 	first_line = SC_INDEX(addr);
 	last_line = SC_INDEX(addr + size - 1);
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	if (first_line <= last_line) {
 		indy_sc_wipe(first_line, last_line);
 		goto out;
@@ -67,7 +67,7 @@
 	indy_sc_wipe(first_line, SC_SIZE - SC_LINE);
 	indy_sc_wipe(0, last_line);
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void inline indy_sc_enable(void)
diff -Nru a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
--- a/arch/mips64/sgi-ip27/ip27-irq.c	Wed Jul 24 14:03:38 2002
+++ b/arch/mips64/sgi-ip27/ip27-irq.c	Wed Jul 24 14:03:38 2002
@@ -175,7 +175,7 @@
 	action = *(irq + irq_action);
 	if (action) {
 		if (!(action->flags & SA_INTERRUPT))
-			__sti();
+			local_irq_enable();
 		do_random = 0;
         	do {
 			do_random |= action->flags;
@@ -184,7 +184,7 @@
         	} while (action);
 		if (do_random & SA_SAMPLE_RANDOM)
 			add_interrupt_randomness(irq);
-		__cli();
+		local_irq_disable();
 	}
 	irq_exit(thiscpu, irq);
 
@@ -506,9 +506,9 @@
 				show("wait_on_irq");
 				count = ~0;
 			}
-			__sti();
+			local_irq_enable();
 			SYNC_OTHER_CORES(cpu);
-			__cli();
+			local_irq_disable();
 			if (irqs_running())
 				continue;
 			if (spin_is_locked(&global_irq_lock))
@@ -555,10 +555,10 @@
 {
 	unsigned int flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	if (flags & ST0_IE) {
 		int cpu = smp_processor_id();
-		__cli();
+		local_irq_disable();
 		if (!local_irq_count(cpu))
 			get_irqlock(cpu);
 	}
@@ -570,7 +570,7 @@
 
 	if (!local_irq_count(cpu))
 		release_irqlock(cpu);
-	__sti();
+	local_irq_enable();
 }
 
 /*
@@ -587,7 +587,7 @@
 	unsigned long flags;
 	int cpu = smp_processor_id();
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	local_enabled = (flags & ST0_IE);
 	/* default to local */
 	retval = 2 + local_enabled;
@@ -612,10 +612,10 @@
 			__global_sti();
 			break;
 		case 2:
-			__cli();
+			local_irq_disable();
 			break;
 		case 3:
-			__sti();
+			local_irq_enable();
 			break;
 		default:
 			printk("global_restore_flags: %08lx\n", flags);
diff -Nru a/arch/ppc/Config.help b/arch/ppc/Config.help
--- a/arch/ppc/Config.help	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc/Config.help	Wed Jul 24 14:03:36 2002
@@ -241,12 +241,6 @@
   and strongly recommended if you are compiling a kernel for an Apple
   machine.
 
-CONFIG_FB_COMPAT_XPMAC
-  If you use the Xpmac X server (common with mklinux), you'll need to
-  say Y here to use X. You should consider changing to XFree86 which
-  includes a server that supports the frame buffer device directly
-  (XF68_FBDev).
-
 CONFIG_SCSI
   If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
   any other SCSI device under Linux, say Y and make sure that you know
diff -Nru a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c
--- a/arch/ppc/amiga/config.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc/amiga/config.c	Wed Jul 24 14:03:37 2002
@@ -952,8 +952,9 @@
     AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick");
     AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot");
     if (AMIGAHW_PRESENT(ZORRO))
-	len += sprintf(buffer+len, "\tZorro%s AutoConfig: %d Expansion Device%s\n",
-		       AMIGAHW_PRESENT(ZORRO3) ? " III" : "",
+	len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion "
+				   "Device%s\n",
+		       AMIGAHW_PRESENT(ZORRO3) ? "I" : "",
 		       zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
 
 #undef AMIGAHW_ANNOUNCE
diff -Nru a/arch/ppc/config.in b/arch/ppc/config.in
--- a/arch/ppc/config.in	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc/config.in	Wed Jul 24 14:03:35 2002
@@ -263,7 +263,6 @@
 comment 'General setup'
 
 bool 'High memory support' CONFIG_HIGHMEM
-dep_bool '  Support for PTEs in high memory' CONFIG_HIGHPTE $CONFIG_HIGHMEM
 bool 'Prompt for advanced kernel configuration options' CONFIG_ADVANCED_OPTIONS
 if [ "$CONFIG_ADVANCED_OPTIONS" = "y" ]; then
    if [ "$CONFIG_HIGHMEM" = "y" ]; then
@@ -478,9 +477,6 @@
    bool 'VGA text console' CONFIG_VGA_CONSOLE
 fi
 source drivers/video/Config.in
-if [ "$CONFIG_FB" = "y" -a "$CONFIG_ALL_PPC" = "y" ]; then
-   bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC
-fi
 endmenu
 
 
diff -Nru a/arch/ppc/kernel/iSeries_head.S b/arch/ppc/kernel/iSeries_head.S
--- a/arch/ppc/kernel/iSeries_head.S	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc/kernel/iSeries_head.S	Wed Jul 24 14:03:37 2002
@@ -1103,7 +1103,7 @@
 
    /* enable and check for decrementers/lpEvents */
    mr	r3,r31
-   bl	__restore_flags
+   bl	local_irq_restore
 
    /* Restore r3, r4 and LR */
    lwz    r3,44(r1)
@@ -1292,7 +1292,7 @@
 
    /* enable and check for decrementers/lpEvents */
    mr	  r3,r31
-   bl	__restore_flags
+   bl	local_irq_restore
 
    lwz    r3,40(r1)
    mtlr   r3
diff -Nru a/arch/ppc/kernel/iSeries_misc.S b/arch/ppc/kernel/iSeries_misc.S
--- a/arch/ppc/kernel/iSeries_misc.S	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc/kernel/iSeries_misc.S	Wed Jul 24 14:03:35 2002
@@ -61,16 +61,16 @@
 	mtmsr	r5		/* restore MSR_EE */
 	blr
 
-/* void __save_flags(unsigned long *flags) */
-_GLOBAL(__save_flags_ptr)
+/* void local_save_flags(unsigned long *flags) */
+_GLOBAL(local_save_flags_ptr)
 	mfspr	r4,SPRG1	/* Get Paca pointer */
 	lbz	r4,PACAPROCENABLED(r4)
 	stw	r4,0(r3)
 	blr
-_GLOBAL(__save_flags_ptr_end)
+_GLOBAL(local_save_flags_ptr_end)
 
-/* void __restore_flags(unsigned long flags) */	
-_GLOBAL(__restore_flags)
+/* void local_irq_restore(unsigned long flags) */	
+_GLOBAL(local_irq_restore)
 	cmpi	0,r3,0		/* Are we enabling? */
 	beq	0f		/* No - then skip interrupt checks */
 
@@ -104,19 +104,19 @@
 	mfspr	r4,SPRG1
 	stb	r3,PACAPROCENABLED(r4)
 	blr
-_GLOBAL(__restore_flags_end)
+_GLOBAL(local_irq_restore_end)
 	
-_GLOBAL(__cli)
+_GLOBAL(local_irq_disable)
 	mfspr	r4,SPRG1
 	li	r3,0
 	stb	r3,PACAPROCENABLED(r4)
 	blr			/* Done */
-_GLOBAL(__cli_end)
+_GLOBAL(local_irq_disable_end)
 
-_GLOBAL(__sti)
+_GLOBAL(local_irq_enable)
 	li	r3,1
-	b	__restore_flags
-_GLOBAL(__sti_end)
+	b	local_irq_restore
+_GLOBAL(local_irq_enable_end)
 
 /*
  * We were about to enable interrupts but we have to simulate
diff -Nru a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
--- a/arch/ppc/kernel/idle.c	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc/kernel/idle.c	Wed Jul 24 14:03:35 2002
@@ -120,7 +120,7 @@
 	 * Disable interrupts to prevent a lost wakeup
 	 * when going to sleep.  This is necessary even with
 	 * RTLinux since we are not guaranteed an interrupt
-	 * didn't come in and is waiting for a __sti() before
+	 * didn't come in and is waiting for a local_irq_enable() before
 	 * emulating one.  This way, we really do hard disable.
 	 * 
 	 * We assume that we're sti-ed when we come in here.  We
@@ -163,8 +163,8 @@
 	u64 tb;
 
 	/* Poll for I/O events */
-	__cli();
-	__sti();
+	local_irq_disable();
+	local_irq_enable();
 	
 	paca = (struct Paca *)mfspr(SPRG1);
 	if ( paca->xLpPaca.xSharedProc ) {
@@ -181,8 +181,8 @@
 		 * Disabling/enabling will check for LpEvents, IPIs
 		 * and decrementers
 		 */
-		__cli();
-		__sti();
+		local_irq_disable();
+		local_irq_enable();
 
 		++yield_count;
 
@@ -193,14 +193,14 @@
 		HvCall_yieldProcessor( HvCall_YieldTimed, tb );
 
 		/* Check here for any of the above pending or timeout expired*/
-		__cli();
+		local_irq_disable();
 		/*
 		 * The decrementer stops during the yield.  Just force
 		 * a fake decrementer now and the timer_interrupt
 		 * code will straighten it all out
 		 */
 		paca->xLpPaca.xDecrInt = 1;
-		__sti();
+		local_irq_enable();
 	}
 }
 #endif /* CONFIG_PPC_ISERIES */
diff -Nru a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
--- a/arch/ppc/kernel/irq.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc/kernel/irq.c	Wed Jul 24 14:03:37 2002
@@ -422,7 +422,7 @@
 	int status = 0;
 
 	if (!(action->flags & SA_INTERRUPT))
-		__sti();
+		local_irq_enable();
 
 	do {
 		status |= action->flags;
@@ -431,7 +431,7 @@
 	} while (action);
 	if (status & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	__cli();
+	local_irq_disable();
 }
 
 /*
@@ -637,15 +637,15 @@
 				show("wait_on_irq");
 				count = ~0;
 			}
-			__sti();
+			local_irq_enable();
 			/* 
-			 * We have to allow irqs to arrive between __sti and __cli
+			 * We have to allow irqs to arrive between local_irq_enable and local_irq_disable
 			 * Some cpus apparently won't cause the interrupt
 			 * for several instructions. We hope that isync will
 			 * catch this --Troy
 			 */
 			__asm__ __volatile__ ("isync");
-			__cli();
+			local_irq_disable();
 			if (irqs_running())
 				continue;
 			if (global_irq_lock)
@@ -736,10 +736,10 @@
 {
 	unsigned long flags;
 	
-	__save_flags(flags);
+	local_save_flags(flags);
 	if (flags & (1 << 15)) {
 		int cpu = smp_processor_id();
-		__cli();
+		local_irq_disable();
 		if (!local_irq_count(cpu))
 			get_irqlock(cpu);
 	}
@@ -751,7 +751,7 @@
 
 	if (!local_irq_count(cpu))
 		release_irqlock(cpu);
-	__sti();
+	local_irq_enable();
 }
 
 /*
@@ -767,7 +767,7 @@
 	int local_enabled;
 	unsigned long flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	local_enabled = (flags >> 15) & 1;
 	/* default to local */
 	retval = 2 + local_enabled;
@@ -817,10 +817,10 @@
 		__global_sti();
 		break;
 	case 2:
-		__cli();
+		local_irq_disable();
 		break;
 	case 3:
-		__sti();
+		local_irq_enable();
 		break;
 	default:
 	{
diff -Nru a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
--- a/arch/ppc/kernel/misc.S	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc/kernel/misc.S	Wed Jul 24 14:03:37 2002
@@ -207,8 +207,8 @@
 	bctr
 
 #ifndef CONFIG_PPC_ISERIES	/* iSeries version is in iSeries_misc.S */
-/* void __save_flags_ptr(unsigned long *flags) */
-_GLOBAL(__save_flags_ptr)
+/* void local_save_flags_ptr(unsigned long *flags) */
+_GLOBAL(local_save_flags_ptr)
 	mfmsr	r4
 	stw	r4,0(r3)
 	blr
@@ -234,10 +234,10 @@
 	nop
 	nop
 	nop
-_GLOBAL(__save_flags_ptr_end)
+_GLOBAL(local_save_flags_ptr_end)
 
-/* void __restore_flags(unsigned long flags) */	
-_GLOBAL(__restore_flags)
+/* void local_irq_restore(unsigned long flags) */	
+_GLOBAL(local_irq_restore)
 /*
  * Just set/clear the MSR_EE bit through restore/flags but do not
  * change anything else.  This is needed by the RT system and makes
@@ -275,9 +275,9 @@
 	nop
 	nop
 	nop
-_GLOBAL(__restore_flags_end)
+_GLOBAL(local_irq_restore_end)
 
-_GLOBAL(__cli)
+_GLOBAL(local_irq_disable)
 	mfmsr	r0		/* Get current interrupt state */
 	rlwinm	r3,r0,16+1,32-1,31	/* Extract old value of 'EE' */
 	rlwinm	r0,r0,0,17,15	/* clear MSR_EE in r0 */
@@ -304,9 +304,9 @@
 	nop
 	nop
 	nop
-_GLOBAL(__cli_end)
+_GLOBAL(local_irq_disable_end)
 
-_GLOBAL(__sti)
+_GLOBAL(local_irq_enable)
 	mfmsr	r3		/* Get current state */
 	ori	r3,r3,MSR_EE	/* Turn on 'EE' bit */
 	SYNC			/* Some chip revs have problems here... */
@@ -333,7 +333,7 @@
 	nop
 	nop
 	nop
-_GLOBAL(__sti_end)
+_GLOBAL(local_irq_enable_end)
 #endif /* CONFIG_PPC_ISERIES */
 
 /*
diff -Nru a/arch/ppc/kernel/ppc4xx_setup.c b/arch/ppc/kernel/ppc4xx_setup.c
--- a/arch/ppc/kernel/ppc4xx_setup.c	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc/kernel/ppc4xx_setup.c	Wed Jul 24 14:03:35 2002
@@ -177,7 +177,7 @@
 ppc4xx_power_off(void)
 {
 	printk("System Halted\n");
-	__cli();
+	local_irq_disable();
 	while (1) ;
 }
 
@@ -185,7 +185,7 @@
 ppc4xx_halt(void)
 {
 	printk("System Halted\n");
-	__cli();
+	local_irq_disable();
 	while (1) ;
 }
 
diff -Nru a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
--- a/arch/ppc/kernel/ppc_ksyms.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc/kernel/ppc_ksyms.c	Wed Jul 24 14:03:39 2002
@@ -298,14 +298,14 @@
 
 EXPORT_SYMBOL(__delay);
 #ifndef INLINE_IRQS
-EXPORT_SYMBOL(__sti);
-EXPORT_SYMBOL(__sti_end);
-EXPORT_SYMBOL(__cli);
-EXPORT_SYMBOL(__cli_end);
-EXPORT_SYMBOL(__save_flags_ptr);
-EXPORT_SYMBOL(__save_flags_ptr_end);
-EXPORT_SYMBOL(__restore_flags);
-EXPORT_SYMBOL(__restore_flags_end);
+EXPORT_SYMBOL(local_irq_enable);
+EXPORT_SYMBOL(local_irq_enable_end);
+EXPORT_SYMBOL(local_irq_disable);
+EXPORT_SYMBOL(local_irq_disable_end);
+EXPORT_SYMBOL(local_save_flags_ptr);
+EXPORT_SYMBOL(local_save_flags_ptr_end);
+EXPORT_SYMBOL(local_irq_restore);
+EXPORT_SYMBOL(local_irq_restore_end);
 #endif
 EXPORT_SYMBOL(timer_interrupt);
 EXPORT_SYMBOL(irq_desc);
diff -Nru a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
--- a/arch/ppc/kernel/process.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc/kernel/process.c	Wed Jul 24 14:03:38 2002
@@ -202,8 +202,8 @@
 	struct thread_struct *new_thread, *old_thread;
 	unsigned long s;
 	
-	__save_flags(s);
-	__cli();
+	local_save_flags(s);
+	local_irq_disable();
 #if CHECK_STACK
 	check_stack(prev);
 	check_stack(new);
@@ -246,7 +246,7 @@
 	new_thread = &new->thread;
 	old_thread = &current->thread;
 	_switch(old_thread, new_thread);
-	__restore_flags(s);
+	local_irq_restore(s);
 }
 
 void show_regs(struct pt_regs * regs)
diff -Nru a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
--- a/arch/ppc/kernel/smp.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc/kernel/smp.c	Wed Jul 24 14:03:39 2002
@@ -164,7 +164,7 @@
 
 static void stop_this_cpu(void *dummy)
 {
-	__cli();
+	local_irq_disable();
 	while (1)
 		;
 }
@@ -488,9 +488,9 @@
 	/* FIXME: This doesn't work with hotplug CPUs --RR */
 	if (!smp_tb_synchronized && num_online_cpus() == 2) {
 		unsigned long flags;
-		__save_and_cli(flags);	
+		local_irq_save(flags);	
 		smp_software_tb_sync(0);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 }
 
@@ -514,7 +514,7 @@
 	if (!smp_tb_synchronized && num_online_cpus() == 2) {
 		smp_software_tb_sync(cpu);
 	}
-	__sti();
+	local_irq_enable();
 }
 
 /* intel needs this */
diff -Nru a/arch/ppc/platforms/adir_setup.c b/arch/ppc/platforms/adir_setup.c
--- a/arch/ppc/platforms/adir_setup.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc/platforms/adir_setup.c	Wed Jul 24 14:03:37 2002
@@ -133,7 +133,7 @@
 static void
 adir_restart(char *cmd)
 {
-	__cli();
+	local_irq_disable();
 	/* SRR0 has system reset vector, SRR1 has default MSR value */
 	/* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
 	__asm__ __volatile__
diff -Nru a/arch/ppc/platforms/ev64260_setup.c b/arch/ppc/platforms/ev64260_setup.c
--- a/arch/ppc/platforms/ev64260_setup.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc/platforms/ev64260_setup.c	Wed Jul 24 14:03:36 2002
@@ -286,7 +286,7 @@
 static void
 ev64260_reset_board(void)
 {
-	__cli();
+	local_irq_disable();
 
 	/* Set exception prefix high - to the firmware */
 	_nmask_and_or_msr(0, MSR_IP);
@@ -310,7 +310,7 @@
 static void
 ev64260_halt(void)
 {
-	__cli();
+	local_irq_disable();
 	while (1);
 	/* NOTREACHED */
 }
diff -Nru a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c
--- a/arch/ppc/platforms/gemini_setup.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc/platforms/gemini_setup.c	Wed Jul 24 14:03:38 2002
@@ -305,7 +305,7 @@
 void
 gemini_restart(char *cmd)
 {
-	__cli();
+	local_irq_disable();
 	/* make a clean restart, not via the MPIC */
 	_gemini_reboot();
 	for(;;);
diff -Nru a/arch/ppc/platforms/iSeries_pic.c b/arch/ppc/platforms/iSeries_pic.c
--- a/arch/ppc/platforms/iSeries_pic.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc/platforms/iSeries_pic.c	Wed Jul 24 14:03:38 2002
@@ -65,10 +65,10 @@
 
 	lpq = paca->lpQueuePtr;
 	if ( lpq ) {
-		__save_flags( flags );
-		__cli();
+		local_save_flags( flags );
+		local_irq_disable();
 		lpEvent_count += ItLpQueue_process( lpq, regs );
-		__restore_flags( flags );
+		local_irq_restore( flags );
 	}
 
         hardirq_exit( cpu );
diff -Nru a/arch/ppc/platforms/k2_setup.c b/arch/ppc/platforms/k2_setup.c
--- a/arch/ppc/platforms/k2_setup.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc/platforms/k2_setup.c	Wed Jul 24 14:03:38 2002
@@ -205,7 +205,7 @@
 static void
 k2_restart(char *cmd)
 {
-	__cli();
+	local_irq_disable();
 	/* SRR0 has system reset vector, SRR1 has default MSR value */
 	/* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
 	__asm__ __volatile__
diff -Nru a/arch/ppc/platforms/lopec_setup.c b/arch/ppc/platforms/lopec_setup.c
--- a/arch/ppc/platforms/lopec_setup.c	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc/platforms/lopec_setup.c	Wed Jul 24 14:03:35 2002
@@ -84,7 +84,7 @@
 	reg |= 0x80;
 	*((unsigned char *) LOPEC_SYSSTAT1) = reg;
 
-	__cli();
+	local_irq_disable();
 	while(1);
 #undef LOPEC_SYSSTAT1
 }
@@ -92,7 +92,7 @@
 static void
 lopec_halt(void)
 {
-	__cli();
+	local_irq_disable();
 	while(1);
 }
 
diff -Nru a/arch/ppc/platforms/mcpn765_setup.c b/arch/ppc/platforms/mcpn765_setup.c
--- a/arch/ppc/platforms/mcpn765_setup.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc/platforms/mcpn765_setup.c	Wed Jul 24 14:03:36 2002
@@ -226,7 +226,7 @@
 static void
 mcpn765_reset_board(void)
 {
-	__cli();
+	local_irq_disable();
 
 	/* Set exception prefix high - to the firmware */
 	_nmask_and_or_msr(0, MSR_IP);
@@ -257,7 +257,7 @@
 static void
 mcpn765_halt(void)
 {
-	__cli();
+	local_irq_disable();
 	while (1);
 	/* NOTREACHED */
 }
diff -Nru a/arch/ppc/platforms/menf1_setup.c b/arch/ppc/platforms/menf1_setup.c
--- a/arch/ppc/platforms/menf1_setup.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc/platforms/menf1_setup.c	Wed Jul 24 14:03:39 2002
@@ -93,7 +93,7 @@
        int     picr1;
        struct pci_dev *pdev;
 
-	__cli();
+	local_irq_disable();
 
 	/*
 	 * Firmware doesn't like re-entry using Map B (CHRP), so make sure the
@@ -130,7 +130,7 @@
 static void
 menf1_halt(void)
 {
-	__cli();
+	local_irq_disable();
 	while (1);
 }
 
diff -Nru a/arch/ppc/platforms/mvme5100_setup.c b/arch/ppc/platforms/mvme5100_setup.c
--- a/arch/ppc/platforms/mvme5100_setup.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc/platforms/mvme5100_setup.c	Wed Jul 24 14:03:37 2002
@@ -199,7 +199,7 @@
 static void
 mvme5100_reset_board(void)
 {
-	__cli();
+	local_irq_disable();
 
 	/* Set exception prefix high - to the firmware */
 	_nmask_and_or_msr(0, MSR_IP);
@@ -223,7 +223,7 @@
 static void
 mvme5100_halt(void)
 {
-	__cli();
+	local_irq_disable();
 	while (1);
 }
 
diff -Nru a/arch/ppc/platforms/pcore_setup.c b/arch/ppc/platforms/pcore_setup.c
--- a/arch/ppc/platforms/pcore_setup.c	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc/platforms/pcore_setup.c	Wed Jul 24 14:03:35 2002
@@ -138,7 +138,7 @@
 static void
 pcore_restart(char *cmd)
 {
-	__cli();
+	local_irq_disable();
 	/* Hard reset */
 	writeb(0x11, 0xfe000332);
 	while(1);
@@ -147,7 +147,7 @@
 static void
 pcore_halt(void)
 {
-	__cli();
+	local_irq_disable();
 	/* Turn off user LEDs */
 	writeb(0x00, 0xfe000300);
 	while (1);
diff -Nru a/arch/ppc/platforms/powerpmc250.c b/arch/ppc/platforms/powerpmc250.c
--- a/arch/ppc/platforms/powerpmc250.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc/platforms/powerpmc250.c	Wed Jul 24 14:03:36 2002
@@ -174,7 +174,7 @@
 static void
 powerpmc250_restart(char *cmd)
 {
-	__cli();
+	local_irq_disable();
 	/* Hard reset */
 	writeb(0x11, 0xfe000332);
 	while(1);
@@ -183,7 +183,7 @@
 static void
 powerpmc250_halt(void)
 {
-	__cli();
+	local_irq_disable();
 	while (1);
 }
 
diff -Nru a/arch/ppc/platforms/pplus_setup.c b/arch/ppc/platforms/pplus_setup.c
--- a/arch/ppc/platforms/pplus_setup.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc/platforms/pplus_setup.c	Wed Jul 24 14:03:39 2002
@@ -155,7 +155,7 @@
 {
 	unsigned long i = 10000;
 
-	__cli();
+	local_irq_disable();
 
 	/* set VIA IDE controller into native mode */
 	pplus_set_VIA_IDE_native();
@@ -176,7 +176,7 @@
 pplus_halt(void)
 {
 	unsigned long flags;
-	__cli();
+	local_irq_disable();
 	/* set exception prefix high - to the prom */
 	save_flags( flags );
 	restore_flags( flags|MSR_IP );
diff -Nru a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
--- a/arch/ppc/platforms/prep_setup.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc/platforms/prep_setup.c	Wed Jul 24 14:03:39 2002
@@ -473,7 +473,7 @@
 
 		if (request_irq(0, prep_calibrate_decr_handler, 0, "timer", NULL) != 0)
 			panic("Could not allocate timer IRQ!");
-		__sti();
+		local_irq_enable();
 		/* wait for calibrate */
 		while ( calibrate_steps )
 			;
@@ -565,7 +565,7 @@
 {
 	unsigned long i = 10000;
 
-	__cli();
+	local_irq_disable();
 
 	/* set exception prefix high - to the prom */
 	_nmask_and_or_msr(0, MSR_IP);
@@ -583,7 +583,7 @@
 prep_halt(void)
 {
 	unsigned long flags;
-	__cli();
+	local_irq_disable();
 	/* set exception prefix high - to the prom */
 	save_flags( flags );
 	restore_flags( flags|MSR_IP );
@@ -650,7 +650,7 @@
 {
 	if ( _prep_type == _PREP_IBM) {
 		unsigned long flags;
-		__cli();
+		local_irq_disable();
 		/* set exception prefix high - to the prom */
 		save_flags( flags );
 		restore_flags( flags|MSR_IP );
diff -Nru a/arch/ppc/platforms/prpmc750_setup.c b/arch/ppc/platforms/prpmc750_setup.c
--- a/arch/ppc/platforms/prpmc750_setup.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc/platforms/prpmc750_setup.c	Wed Jul 24 14:03:37 2002
@@ -184,7 +184,7 @@
 static void
 prpmc750_restart(char *cmd)
 {
-	__cli();
+	local_irq_disable();
 	writeb(PRPMC750_MODRST_MASK, PRPMC750_MODRST_REG);
 	while(1);
 }
@@ -192,7 +192,7 @@
 static void
 prpmc750_halt(void)
 {
-	__cli();
+	local_irq_disable();
 	while (1);
 }
 
diff -Nru a/arch/ppc/platforms/prpmc800_setup.c b/arch/ppc/platforms/prpmc800_setup.c
--- a/arch/ppc/platforms/prpmc800_setup.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc/platforms/prpmc800_setup.c	Wed Jul 24 14:03:38 2002
@@ -178,7 +178,7 @@
 static void
 prpmc800_restart(char *cmd)
 {
-	__cli();
+	local_irq_disable();
 	writeb(HARRIER_RSTOUT_MASK, HARRIER_MISC_CSR_REG);
 	while(1);
 }
@@ -186,7 +186,7 @@
 static void
 prpmc800_halt(void)
 {
-	__cli();
+	local_irq_disable();
 	while (1);
 }
 
diff -Nru a/arch/ppc/platforms/sandpoint_setup.c b/arch/ppc/platforms/sandpoint_setup.c
--- a/arch/ppc/platforms/sandpoint_setup.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc/platforms/sandpoint_setup.c	Wed Jul 24 14:03:39 2002
@@ -390,7 +390,7 @@
 static void
 sandpoint_restart(char *cmd)
 {
-	__cli();
+	local_irq_disable();
 
 	/* Set exception prefix high - to the firmware */
 	_nmask_and_or_msr(0, MSR_IP);
@@ -404,7 +404,7 @@
 static void
 sandpoint_power_off(void)
 {
-	__cli();
+	local_irq_disable();
 	for(;;);  /* No way to shut power off with software */
 	/* NOTREACHED */
 }
diff -Nru a/arch/ppc/platforms/spruce_setup.c b/arch/ppc/platforms/spruce_setup.c
--- a/arch/ppc/platforms/spruce_setup.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc/platforms/spruce_setup.c	Wed Jul 24 14:03:36 2002
@@ -158,7 +158,7 @@
 static void
 spruce_restart(char *cmd)
 {
-	__cli();
+	local_irq_disable();
 
 	/* SRR0 has system reset vector, SRR1 has default MSR value */
 	/* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
diff -Nru a/arch/ppc/platforms/zx4500_setup.c b/arch/ppc/platforms/zx4500_setup.c
--- a/arch/ppc/platforms/zx4500_setup.c	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc/platforms/zx4500_setup.c	Wed Jul 24 14:03:35 2002
@@ -191,7 +191,7 @@
 static void
 zx4500_restart(char *cmd)
 {
-	__cli();
+	local_irq_disable();
 
 	out_8((volatile u_char *)ZX4500_CPLD_RESET, ZX4500_CPLD_RESET_XBUS);
 	for (;;);
@@ -203,7 +203,7 @@
 static void
 zx4500_power_off(void)
 {
-	__cli();
+	local_irq_disable();
 	for(;;);  /* No way to shut power off with software */
 	/* NOTREACHED */
 }
diff -Nru a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
--- a/arch/ppc/xmon/xmon.c	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc/xmon/xmon.c	Wed Jul 24 14:03:35 2002
@@ -243,11 +243,11 @@
 xmon_irq(int irq, void *d, struct pt_regs *regs)
 {
 	unsigned long flags;
-	__save_flags(flags);
-	__cli();
+	local_save_flags(flags);
+	local_irq_disable();
 	printf("Keyboard interrupt\n");
 	xmon(regs);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 int
diff -Nru a/arch/ppc64/Config.help b/arch/ppc64/Config.help
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc64/Config.help	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,299 @@
+CONFIG_SMP
+  This enables support for systems with more than one CPU. If you have
+  a system with only one CPU, say N. If you have a system with more
+  than one CPU, say Y.  Note that the kernel does not currently
+  support SMP machines with 603/603e/603ev or PPC750 ("G3") processors
+  since they have inadequate hardware support for multiprocessor
+  operation.
+
+  If you say N here, the kernel will run on single and multiprocessor
+  machines, but will use only one CPU of a multiprocessor machine. If
+  you say Y here, the kernel will run on single-processor machines.
+  On a single-processor machine, the kernel will run faster if you say
+  N here.
+
+  If you don't know what to do here, say N.
+
+CONFIG_PREEMPT
+  This option reduces the latency of the kernel when reacting to
+  real-time or interactive events by allowing a low priority process to
+  be preempted even if it is in kernel mode executing a system call.
+  Unfortunately the kernel code has some race conditions if both
+  CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
+  currently disabled if you are building an SMP kernel.
+
+  Say Y here if you are building a kernel for a desktop, embedded
+  or real-time system.  Say N if you are unsure.
+
+CONFIG_IDE
+  If you say Y here, your kernel will be able to manage low cost mass
+  storage units such as ATA/(E)IDE and ATAPI units. The most common
+  cases are IDE hard drives and ATAPI CD-ROM drives.
+
+  If your system is pure SCSI and doesn't use these interfaces, you
+  can say N here.
+
+  Integrated Disk Electronics (IDE aka ATA-1) is a connecting standard
+  for mass storage units such as hard disks. It was designed by
+  Western Digital and Compaq Computer in 1984.  Quite a number of
+  disks use the IDE interface.
+
+  Fast-IDE is ATA-2 (also named Fast ATA), Enhanced IDE (EIDE) is
+  ATA-3. It provides support for larger disks (up to 8.4GB by means of
+  the LBA standard), more disks (4 instead of 2) and for other mass
+  storage units such as tapes and cdrom. UDMA/33 (aka UltraDMA/33) is
+  ATA-4 and provides faster (and more CPU friendly) transfer modes
+  than previous PIO (Programmed processor Input/Output) from previous
+  ATA/IDE standards by means of fast DMA controllers.
+
+  ATA Packet Interface (ATAPI) is a protocol used by EIDE tape and
+  CD-ROM drives, similar in many respects to the SCSI protocol.
+
+  SMART IDE (Self Monitoring, Analysis and Reporting Technology) was
+  designed in order to prevent data corruption and disk crash by
+  detecting pre hardware failure conditions (heat, access time, and
+  the like...). Disks built since June 1995 may follow this standard.
+  The kernel itself don't manage this; however there are quite a
+  number of user programs such as smart that can query the status of
+  SMART parameters disk.
+
+  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),
+  say M here and read <file:Documentation/modules.txt>. The module
+  will be called ide.o.
+
+  For further information, please read <file:Documentation/ide.txt>.
+
+  If unsure, say Y.
+
+CONFIG_ISA
+  Find out whether you have ISA slots on your motherboard.  ISA is the
+  name of a bus system, i.e. the way the CPU talks to the other stuff
+  inside your box.  If you have an Apple machine, say N here; if you
+  have an IBM RS/6000 or pSeries machine or a PReP machine, say Y.  If
+  you have an embedded board, consult your board documentation.
+
+CONFIG_PCI
+  Find out whether your system includes a PCI bus. PCI is the name of
+  a bus system, i.e. the way the CPU talks to the other stuff inside
+  your box.  If you say Y here, the kernel will include drivers and
+  infrastructure code to support PCI bus devices.
+
+CONFIG_HOTPLUG
+  Say Y here if you want to plug devices into your computer while
+  the system is running, and be able to use them quickly.  In many
+  cases, the devices can likewise be unplugged at any time too.
+
+  One well known example of this is PCMCIA- or PC-cards, credit-card
+  size devices such as network cards, modems or hard drives which are
+  plugged into slots found on all modern laptop computers.  Another
+  example, used on modern desktops as well as laptops, is USB.
+
+  Enable HOTPLUG and KMOD, and build a modular kernel.  Get agent
+  software (at <http://linux-hotplug.sourceforge.net/>) and install it.
+  Then your kernel will automatically call out to a user mode "policy
+  agent" (/sbin/hotplug) to load modules and set up software needed
+  to use devices as you hotplug them.
+
+CONFIG_PCMCIA
+  Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
+  computer.  These are credit-card size devices such as network cards,
+  modems or hard drives often used with laptops computers.  There are
+  actually two varieties of these cards: the older 16 bit PCMCIA cards
+  and the newer 32 bit CardBus cards.  If you want to use CardBus
+  cards, you need to say Y here and also to "CardBus support" below.
+
+  To use your PC-cards, you will need supporting software from David
+  Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
+  for location).  Please also read the PCMCIA-HOWTO, available from
+  <http://www.linuxdoc.org/docs.html#howto>.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  When compiled this way, there will be modules called pcmcia_core.o
+  and ds.o.  If you want to compile it as a module, say M here and
+  read <file:Documentation/modules.txt>.
+
+CONFIG_KCORE_ELF
+  If you enabled support for /proc file system then the file
+  /proc/kcore will contain the kernel core image in ELF format. This
+  can be used in gdb:
+
+  $ cd /usr/src/linux ; gdb vmlinux /proc/kcore
+
+  This is especially useful if you have compiled the kernel with the
+  "-g" option to preserve debugging information. It is mainly used
+  for examining kernel data structures on the live kernel.
+
+CONFIG_BINFMT_ELF
+  ELF (Executable and Linkable Format) is a format for libraries and
+  executables used across different architectures and operating
+  systems.
+
+CONFIG_BINFMT_MISC
+  If you say Y here, it will be possible to plug wrapper-driven binary
+  formats into the kernel. You will like this especially when you use
+  programs that need an interpreter to run like Java, Python or
+  Emacs-Lisp.  It's also useful if you often run DOS executables under
+  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
+  <http://www.linuxdoc.org/docs.html#howto>).  Once you have
+  registered such a binary class with the kernel, you can start one of
+  those programs simply by typing in its name at a shell prompt; Linux
+  will automatically feed it to the correct interpreter.
+
+  You can do other nice things, too. Read the file
+  <file:Documentation/binfmt_misc.txt> to learn how to use this
+  feature, and <file:Documentation/java.txt> for information about how
+  to include Java support.
+
+  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
+  use this part of the kernel.
+
+  You may say M here for module support and later load the module when
+  you have use for it; the module is called binfmt_misc.o. If you
+  don't know what to answer at this point, say Y.
+
+CONFIG_VGA_CONSOLE
+  Saying Y here will allow you to use Linux in text mode through a
+  display that complies with the generic VGA standard.  This can be
+  useful on PReP systems and IBM RS/6000 or pSeries machines but is of
+  limited usefulness on Apple machines.
+
+  Say N here if you have an Apple machine.
+
+CONFIG_IRQ_ALL_CPUS
+  This option gives the kernel permission to distribute IRQs across
+  multiple CPUs.  Saying N here will route all IRQs to the first
+  CPU.  Generally saying Y is safe, although some problems have been
+  reported with SMP Power Macintoshes with this option enabled.
+
+CONFIG_FB
+  The frame buffer device provides an abstraction for the graphics
+  hardware. It represents the frame buffer of some video hardware and
+  allows application software to access the graphics hardware through
+  a well-defined interface, so the software doesn't need to know
+  anything about the low-level (hardware register) stuff.
+
+  Frame buffer devices work identically across the different
+  architectures supported by Linux and make the implementation of
+  application programs easier and more portable; at this point, an X
+  server exists which uses the frame buffer device exclusively.
+  On several non-X86 architectures, the frame buffer device is the
+  only way to use the graphics hardware.
+
+  The device is accessed through special device nodes, usually located
+  in the /dev directory, i.e. /dev/fb*.
+
+  You need an utility program called fbset to make full use of frame
+  buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
+  and the Framebuffer-HOWTO at
+  <http://www.tahallah.demon.co.uk/programming/prog.html> for more
+  information.
+
+  Saying Y here is recommended if your machine has graphics hardware,
+  and strongly recommended if you are compiling a kernel for an Apple
+  machine.
+
+CONFIG_SCSI
+  If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
+  any other SCSI device under Linux, say Y and make sure that you know
+  the name of your SCSI host adapter (the card inside your computer
+  that "speaks" the SCSI protocol, also called SCSI controller),
+  because you will be asked for it.
+
+  You also need to say Y here if you want support for the parallel
+  port version of the 100 MB IOMEGA ZIP drive.
+
+  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 scsi_mod.o.  If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt> and
+  <file:Documentation/scsi.txt>.  However, do not compile this as a
+  module if your root file system (the one containing the directory /)
+  is located on a SCSI device.
+
+CONFIG_NETDEVICES
+  You can say N here if you don't intend to connect your Linux box to
+  any other computer at all or if all your connections will be over a
+  telephone line with a modem either via UUCP (UUCP is a protocol to
+  forward mail and news between unix hosts over telephone lines; read
+  the UUCP-HOWTO, available from
+  <http://www.linuxdoc.org/docs.html#howto>) or dialing up a shell
+  account or a BBS, even using term (term is a program which gives you
+  almost full Internet connectivity if you have a regular dial up
+  shell account on some Internet connected Unix computer. Read
+  <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>).
+
+  You'll have to say Y if your computer contains a network card that
+  you want to use under Linux (make sure you know its name because you
+  will be asked for it and read the Ethernet-HOWTO (especially if you
+  plan to use more than one network card under Linux)) or if you want
+  to use SLIP (Serial Line Internet Protocol is the protocol used to
+  send Internet traffic over telephone lines or null modem cables) or
+  CSLIP (compressed SLIP) or PPP (Point to Point Protocol, a better
+  and newer replacement for SLIP) or PLIP (Parallel Line Internet
+  Protocol is mainly used to create a mini network by connecting the
+  parallel ports of two local machines) or AX.25/KISS (protocol for
+  sending Internet traffic over amateur radio links).
+
+  Make sure to read the NET-3-HOWTO. Eventually, you will have to read
+  Olaf Kirch's excellent and free book "Network Administrator's
+  Guide", to be found in <http://www.linuxdoc.org/docs.html#guide>. If
+  unsure, say Y.
+
+CONFIG_SERIAL_CONSOLE
+  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
+  kernel messages and warnings and which allows logins in single user
+  mode). This could be useful if some terminal or printer is connected
+  to that serial port.
+
+  Even if you say Y here, the currently visible virtual console
+  (/dev/tty0) will still be used as the system console by default, but
+  you can alter that using a kernel command line option such as
+  "console=ttyS1". (Try "man bootparam" or see the documentation of
+  your boot loader (lilo or loadlin) about how to pass options to the
+  kernel at boot time.)
+
+  If you don't have a graphics card installed and you say Y here, the
+  kernel will automatically use the first serial line, /dev/ttyS0, as
+  system console.
+
+  If unsure, say N.
+
+CONFIG_MOUSE
+  This is for machines with a mouse which is neither a serial nor a
+  USB nor a bus mouse.  Examples are PS/2 mice (including the track
+  balls on some laptops) and some digitizer pads.  Say Y here if you
+  have a CHRP machine (such as an IBM RS/6000 or pSeries machine) with
+  a PS/2-style mouse.
+
+  Note that the answer to this question won't directly affect the
+  kernel: saying N will just cause the configurator to skip all
+  the questions about non-serial mice. If unsure, say Y.
+
+CONFIG_MAGIC_SYSRQ
+  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 <file:Documentation/sysrq.txt>. Don't say Y
+  unless you really know what this hack does.
+
+CONFIG_PROC_DEVICETREE
+  This option adds a device-tree directory under /proc which contains
+  an image of the device tree that the kernel copies from Open
+  Firmware. If unsure, say Y here.
+
+CONFIG_CMDLINE
+  On some platforms, there is currently no way for the boot loader to
+  pass arguments to the kernel. For these platforms, you can supply
+  some command-line options at build time by entering them here.  In
+  most cases you will need to specify the root device here.
+
+CONFIG_XMON
+  Include in-kernel hooks for the xmon kernel monitor/debugger.
+  Unless you are intending to debug the kernel, say N here.
diff -Nru a/arch/ppc64/Makefile b/arch/ppc64/Makefile
--- a/arch/ppc64/Makefile	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/Makefile	Wed Jul 24 14:03:36 2002
@@ -15,11 +15,12 @@
 
 KERNELLOAD	=0xc000000000000000
 
+LDFLAGS		:= -m elf64ppc
 LDFLAGS_vmlinux	= -T arch/ppc64/vmlinux.lds -Bstatic \
 		-e $(KERNELLOAD) -Ttext $(KERNELLOAD)
 CFLAGS		:= $(CFLAGS) -fsigned-char -msoft-float -pipe \
 		-Wno-uninitialized -mminimal-toc -mtraceback=full \
-		-Wa,-mpower4 -finline-limit-2000
+		-Wa,-mpower4 -finline-limit-2000 -mcpu=630
 CPP		= $(CC) -E $(CFLAGS)
 
 
@@ -65,6 +66,3 @@
 	@$(MAKEBOOT) clean
 
 archmrproper:
-
-prepare:
-	$(MAKEBOOT) dep
diff -Nru a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
--- a/arch/ppc64/boot/Makefile	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc64/boot/Makefile	Wed Jul 24 14:03:37 2002
@@ -120,7 +120,3 @@
 
 clean:
 	rm -f piggyback note addnote $(OBJS) zImage zImage.initrd vmlinux.gz no_initrd.o imagesize.c addSystemMap vmlinux.sm addRamDisk vmlinux.initrd vmlinux.sminitrd 
-
-dep:
-	$(CPP) $(CPPFLAGS) -M *.S *.c > .depend
-
diff -Nru a/arch/ppc64/config.in b/arch/ppc64/config.in
--- a/arch/ppc64/config.in	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/config.in	Wed Jul 24 14:03:36 2002
@@ -23,12 +23,18 @@
   bool '  Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS
   if [ "$CONFIG_PPC_PSERIES" = "y" ]; then
     bool '  Hardware multithreading' CONFIG_HMT
+    bool '  Discontiguous Memory Support' CONFIG_DISCONTIGMEM
+    if [ "$CONFIG_DISCONTIGMEM" = "y" ]; then
+      bool '    NUMA support' CONFIG_NUMA
+    fi
   fi
 fi
 define_bool CONFIG_PREEMPT n
 
 if [ "$CONFIG_PPC_ISERIES" = "y" ]; then
    define_bool CONFIG_MSCHUNKS y
+else
+   tristate '  Firmware flash interface' CONFIG_RTAS_FLASH
 fi
 
 endmenu
diff -Nru a/arch/ppc64/defconfig b/arch/ppc64/defconfig
--- a/arch/ppc64/defconfig	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc64/defconfig	Wed Jul 24 14:03:37 2002
@@ -37,7 +37,9 @@
 CONFIG_SMP=y
 CONFIG_IRQ_ALL_CPUS=y
 # CONFIG_HMT is not set
+# CONFIG_DISCONTIGMEM is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_RTAS_FLASH is not set
 
 #
 # General setup
@@ -60,6 +62,7 @@
 #
 # CONFIG_PARPORT is not set
 CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -83,6 +86,7 @@
 # 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=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
@@ -188,9 +192,6 @@
 # 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_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_DPT_I2O is not set
@@ -225,7 +226,6 @@
 # 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_SYM53C416 is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
@@ -238,6 +238,10 @@
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_BOOT is not set
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -364,7 +368,7 @@
 # CONFIG_WAN is not set
 
 #
-# "Tulip" family network device support
+# Tulip family network device support
 #
 # CONFIG_NET_TULIP is not set
 
@@ -397,7 +401,6 @@
 #
 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_CYBER2000 is not set
@@ -409,6 +412,7 @@
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_S3TRIO is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_RIVA is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
@@ -422,6 +426,8 @@
 # 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
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -440,20 +446,40 @@
 # Input device support
 #
 # CONFIG_INPUT is not set
+
+#
+# Userland interfaces
+#
 # CONFIG_INPUT_KEYBDEV is not set
 # 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_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Input I/O drivers
+#
 # 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_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_Q40KBD is not set
+# CONFIG_SERIO_PARKBD is not set
+
+#
+# Input Device Drivers
+#
 CONFIG_VIOPATH=y
 
 #
@@ -478,17 +504,15 @@
 # Mice
 #
 # CONFIG_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
@@ -509,6 +533,8 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_REISERFS_FS=y
diff -Nru a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c
--- a/arch/ppc64/kernel/LparData.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/kernel/LparData.c	Wed Jul 24 14:03:36 2002
@@ -13,7 +13,6 @@
 #include <linux/threads.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
-#include <asm/init.h>
 #include <asm/naca.h>
 #include <asm/abs_addr.h>
 #include <asm/bitops.h>
@@ -25,6 +24,7 @@
 #include <asm/iSeries/LparMap.h>
 #include <asm/iSeries/ItVpdAreas.h>
 #include <asm/iSeries/ItIplParmsReal.h>
+#include <asm/iSeries/ItExtVpdPanel.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/IoHriProcessorVpd.h>
 #include <asm/iSeries/ItSpCommArea.h>
@@ -144,6 +144,8 @@
 
 struct ItIplParmsReal xItIplParmsReal = {};
 
+struct ItExtVpdPanel xItExtVpdPanel = {};
+
 #define maxPhysicalProcessors 32
 
 struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
@@ -185,7 +187,8 @@
 	{0},		/* DMA lengths */
 	{0},		/* DMA tokens */
 	{		/* VPD lengths */
-		0,0,0,0,		/*  0 -  3 */
+	        0,0,0,		        /*  0 - 2 */
+		sizeof(xItExtVpdPanel), /*       3 Extended VPD   */
 		sizeof(struct paca_struct),	/*       4 length of Paca  */
 		0,			/*       5 */
 		sizeof(struct ItIplParmsReal),/* 6 length of IPL parms */
@@ -202,7 +205,8 @@
 		0,0			/* 24 - 25 */
 		},
 	{			/* VPD addresses */
-		0,0,0,0,		/*	 0 -  3 */
+		0,0,0,  		/*	 0 -  2 */
+		&xItExtVpdPanel,        /*       3 Extended VPD */
 		&paca[0],		/*       4 first Paca */
 		0,			/*       5 */
 		&xItIplParmsReal,	/*	 6 IPL parms */
@@ -244,6 +248,7 @@
 
 	return mem;
 }
+
 
 
 
diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/Makefile	Wed Jul 24 14:03:39 2002
@@ -32,6 +32,8 @@
 obj-y += rtasd.o nvram.o
 endif
 
+obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
+
 obj-$(CONFIG_SMP) += smp.o
 
 obj-y += prom.o lmb.o rtas.o rtas-proc.o chrp_setup.o i8259.o
@@ -43,6 +45,11 @@
 #
 
 head.o: head.S ppc_defs.h
+misc.o: misc.S ppc_defs.h
+entry.o: entry.S ppc_defs.h
+hvCall.o: hvCall.S ppc_defs.h
+pSeries_hvCall.o: pSeries_hvCall.S ppc_defs.h
+sys32.o: sys32.S ppc_defs.h
 
 ppc_defs.h: mk_defs.c ppc_defs.head \
 		$(TOPDIR)/include/asm/mmu.h \
diff -Nru a/arch/ppc64/kernel/XmPciLpEvent.c b/arch/ppc64/kernel/XmPciLpEvent.c
--- a/arch/ppc64/kernel/XmPciLpEvent.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/XmPciLpEvent.c	Wed Jul 24 14:03:38 2002
@@ -26,10 +26,13 @@
 
 enum XmPciLpEvent_Subtype {
 	XmPciLpEvent_BusCreated	   = 0,		// PHB has been created
-	XmPciLpEvent_BusFailed	   = 1,		// PHB has failed
-	XmPciLpEvent_BusRecovered  = 12,	// PHB has been recovered
+	XmPciLpEvent_BusError	   = 1,		// PHB has failed
+	XmPciLpEvent_BusFailed	   = 2,		// Msg to Seconday, Primary failed bus
 	XmPciLpEvent_NodeFailed	   = 4,		// Multi-adapter bridge has failed
 	XmPciLpEvent_NodeRecovered = 5,		// Multi-adapter bridge has recovered
+	XmPciLpEvent_BusRecovered  = 12,	// PHB has been recovered
+	XmPciLpEvent_UnQuiesceBus  = 18,	// Secondary bus unqiescing
+	XmPciLpEvent_BridgeError   = 21,	// Bridge Error
 	XmPciLpEvent_SlotInterrupt = 22		// Slot interrupt
 };
 
@@ -116,13 +119,16 @@
 	case XmPciLpEvent_BusCreated:
 		printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", eventParm->eventData.busCreated.busNumber);
 		break;
+	case XmPciLpEvent_BusError:
 	case XmPciLpEvent_BusFailed:
 		printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", eventParm->eventData.busFailed.busNumber);
 		break;
 	case XmPciLpEvent_BusRecovered:
+	case XmPciLpEvent_UnQuiesceBus:
 		printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", eventParm->eventData.busRecovered.busNumber);
 		break;
 	case XmPciLpEvent_NodeFailed:
+	case XmPciLpEvent_BridgeError:
 		printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", eventParm->eventData.nodeFailed.busNumber, eventParm->eventData.nodeFailed.subBusNumber, eventParm->eventData.nodeFailed.deviceId);
 		break;
 	case XmPciLpEvent_NodeRecovered:
diff -Nru a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c
--- a/arch/ppc64/kernel/align.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/align.c	Wed Jul 24 14:03:38 2002
@@ -238,7 +238,7 @@
 	dsisr = regs->dsisr;
 
 	/* Power4 doesn't set DSISR for an alignment interrupt */
-	if (__is_processor(PV_POWER4))
+	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
 		dsisr = make_dsisr( *((unsigned *)regs->nip) );
 
 	/* extract the operation and registers from the dsisr */
diff -Nru a/arch/ppc64/kernel/binfmt_elf32.c b/arch/ppc64/kernel/binfmt_elf32.c
--- a/arch/ppc64/kernel/binfmt_elf32.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/kernel/binfmt_elf32.c	Wed Jul 24 14:03:36 2002
@@ -62,6 +62,16 @@
 	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
 };
 
+#include <linux/time.h>
+
+#define jiffies_to_timeval jiffies_to_timeval32
+static __inline__ void
+jiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value)
+{
+	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
+	value->tv_sec = jiffies / HZ;
+}
+
 extern void start_thread32(struct pt_regs *, unsigned long, unsigned long);
 #undef start_thread
 #define start_thread start_thread32
diff -Nru a/arch/ppc64/kernel/chrp_setup.c b/arch/ppc64/kernel/chrp_setup.c
--- a/arch/ppc64/kernel/chrp_setup.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/kernel/chrp_setup.c	Wed Jul 24 14:03:36 2002
@@ -57,7 +57,6 @@
 #include <asm/machdep.h>
 #include <asm/irq.h>
 #include <asm/keyboard.h>
-#include <asm/init.h>
 #include <asm/naca.h>
 #include <asm/time.h>
 
@@ -98,16 +97,10 @@
 kdev_t boot_dev;
 unsigned long  virtPython0Facilities = 0;  // python0 facility area (memory mapped io) (64-bit format) VIRTUAL address.
 
-extern HPTE *Hash, *Hash_end;
-extern unsigned long Hash_size, Hash_mask;
-extern int probingmem;
 extern unsigned long loops_per_jiffy;
 
-#ifdef CONFIG_BLK_DEV_RAM
-extern int rd_doload;		/* 1 = load ramdisk, 0 = don't load */
-extern int rd_prompt;		/* 1 = prompt for ramdisk, 0 = don't prompt */
-extern int rd_image_start;	/* starting block # of image */
-#endif
+extern unsigned long ppc_proc_freq;
+extern unsigned long ppc_tb_freq;
 
 void 
 chrp_get_cpuinfo(struct seq_file *m)
@@ -115,6 +108,8 @@
 	struct device_node *root;
 	const char *model = "";
 
+	seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
+
 	root = find_path_device("/");
 	if (root)
 		model = get_property(root, "model", NULL);
@@ -304,7 +299,7 @@
 	ppc_md.progress("Linux ppc64\n", 0x0);
 }
 
-void __chrp
+void
 chrp_progress(char *s, unsigned short hex)
 {
 	struct device_node *root;
@@ -361,9 +356,6 @@
 }
 
 extern void setup_default_decr(void);
-
-extern unsigned long ppc_proc_freq;
-extern unsigned long ppc_tb_freq;
 
 void __init pSeries_calibrate_decr(void)
 {
diff -Nru a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
--- a/arch/ppc64/kernel/eeh.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/eeh.c	Wed Jul 24 14:03:38 2002
@@ -59,15 +59,14 @@
 	return ((IO_UNMAPPED_REGION_ID << 60) | (phb << 48UL) | ((bus & 0xff) << 40UL) | (devfn << 32UL) | (offset & 0xffffffff));
 }
 
-
-
-int eeh_get_state(unsigned long ea) {
+int eeh_get_state(unsigned long ea)
+{
 	return 0;
 }
 
-
 /* Check for an eeh failure at the given token address.
- * The given value has been read and it should be 1's (0xff, 0xffff or 0xffffffff).
+ * The given value has been read and it should be 1's (0xff, 0xffff or
+ * 0xffffffff).
  *
  * Probe to determine if an error actually occurred.  If not return val.
  * Otherwise panic.
@@ -113,7 +112,8 @@
 	return val;	/* good case */
 }
 
-void eeh_init(void) {
+void eeh_init(void)
+{
 	extern char cmd_line[];	/* Very early cmd line parse.  Cheap, but works. */
 	char *eeh_force_off = strstr(cmd_line, "eeh-force-off");
 	char *eeh_force_on = strstr(cmd_line, "eeh-force-on");
@@ -121,7 +121,7 @@
 	ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
 	ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
 	ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
-	if (ibm_set_eeh_option != RTAS_UNKNOWN_SERVICE && naca->platform == PLATFORM_PSERIES_LPAR)
+	if (ibm_set_eeh_option != RTAS_UNKNOWN_SERVICE)
 		eeh_implemented = 1;
 
 	if (eeh_force_off > eeh_force_on) {
@@ -334,6 +334,7 @@
 {
 	return eeh_parm(str, 0);
 }
+
 static int __init eehon_parm(char *str)
 {
 	return eeh_parm(str, 1);
diff -Nru a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
--- a/arch/ppc64/kernel/entry.S	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc64/kernel/entry.S	Wed Jul 24 14:03:35 2002
@@ -64,7 +64,8 @@
 #ifdef SHOW_SYSCALLS_TASK
 	LOADBASE(r31,show_syscalls_task)
 	ld	r31,show_syscalls_task@l(r31)
-	cmp	0,r13,r31
+	ld	r10,PACACURRENT(r13)
+	cmp	0,r10,r31
 	bne	1f
 #endif
 	LOADADDR(r3,7f)
@@ -78,7 +79,7 @@
 	LOADADDR(r3,77f)
 	ld	r4,GPR8(r1)
 	ld	r5,GPR9(r1)
-	mr	r6,r13
+	ld	r6, PACACURRENT(r13)
 	bl	.printk
 	ld	r0,GPR0(r1)
 	ld	r3,GPR3(r1)
@@ -129,7 +130,8 @@
 20:	std	r3,RESULT(r1)	/* Save result */
 #ifdef SHOW_SYSCALLS
 #ifdef SHOW_SYSCALLS_TASK
-	cmp	0,r13,r31
+	ld	r10, PACACURRENT(13)
+	cmp	0,r10,r31
 	bne	91f
 #endif
 	mr	r4,r3
@@ -289,9 +291,8 @@
 	std	r23,_CCR(r1)
 	std	r1,KSP(r3)	/* Set old stack pointer */
 
-	mfspr	r5,SPRG3	/* Get paca */
-	addi	r13,r4,-THREAD	/* Convert THREAD to 'current' */
-	std	r13,PACACURRENT(r5)	/* Set new 'current' */
+	addi	r6,r4,-THREAD	/* Convert THREAD to 'current' */
+	std	r6,PACACURRENT(r13)	/* Set new 'current' */
 
 #ifdef CONFIG_PPC_ISERIES
 #error fixme
@@ -335,6 +336,7 @@
 	CHECKANYINT(r3,r4)
 	beq+	4f	/* skip do_IRQ if no interrupts */
 
+#warning FIX ISERIES
 	mfspr	r5,SPRG3
 	li	r3,0
 	stb	r3,PACAPROCENABLED(r5)	/* ensure we are disabled */
@@ -353,7 +355,7 @@
 	li	r4,0
 	ori	r4,r4,MSR_EE|MSR_RI
 	andc	r10,r10,r4	/* clear MSR_EE and MSR_RI */
-	mtmsrd	r10		/* Update machine state */
+	mtmsrd	r10,1		/* Update machine state */
 
 #ifdef CONFIG_PPC_ISERIES
 #error fix iSeries soft disable
@@ -370,9 +372,15 @@
 	bne	do_work
 
 	addi	r0,r1,INT_FRAME_SIZE	/* size of frame */
-	std	r0,THREAD+KSP(r13)	/* save kernel stack pointer */
-	mfspr   r4,SPRG3		/* current task's PACA */
-	std	r1,PACAKSAVE(r4)	/* save exception stack pointer */
+	ld	r4,PACACURRENT(r13)
+	std	r0,THREAD+KSP(r4)	/* save kernel stack pointer */
+	std	r1,PACAKSAVE(r13)	/* save exception stack pointer */
+
+	/*
+	 * r13 is our per cpu area, only restore it if we are returning to
+	 * userspace
+	 */
+	REST_GPR(13,r1)
 
 restore:
 	ld	r3,_CTR(r1)
@@ -389,29 +397,37 @@
 	stdcx.	r0,0,r1		/* to clear the reservation */
 
 #ifdef DO_SOFT_DISABLE
+	/* XXX do this in do_work, r13 isnt valid here */
 	ld	r0,SOFTE(r1)
 	stb	r0,PACAPROCENABLED(r13)
 #endif
 
 	ld	r0,_MSR(r1)
 	mtspr	SRR1,r0
+
 	ld	r2,_CCR(r1)
 	mtcrf	0xFF,r2
 	ld	r2,_NIP(r1)
 	mtspr	SRR0,r2
-	REST_GPR(13,r1)
+
 	ld	r0,GPR0(r1)
 	ld	r2,GPR2(r1)
 	ld	r3,GPR3(r1)
 	ld	r4,GPR4(r1)
 	ld	r1,GPR1(r1)
 
+	/*
+	 *  What if we took an exception and stole this segment, we may
+	 * fault on the above addresses and globber SRR0/1. Should check RI
+	 * bit and repeat - Anton
+	 */
 	rfid
 
+/* Note: this must change if we start using the  TIF_NOTIFY_RESUME bit */
 do_work:
 	/* Enable interrupts */
 	ori	r10,r10,MSR_EE|MSR_RI
-	mtmsrd	r10
+	mtmsrd	r10,1
 
 	andi.	r0,r3,_TIF_NEED_RESCHED
 	beq	1f
@@ -419,15 +435,12 @@
 	b	recheck
 
 1:	andi.	r0,r3,_TIF_SIGPENDING
-	beq	2f
+	beq	recheck
 	li	r3,0
 	addi	r4,r1,STACK_FRAME_OVERHEAD
 	bl	.do_signal
 	b	recheck
 
-2:	/* nobody uses the TIF_NOTIFY_RESUME bit yet */
-	b	recheck
-
 /*
  * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
  * called with the MMU off.
@@ -446,7 +459,7 @@
 	 * RTAS might touch to the stack.  (r0, r3-r13 are caller saved)
    	 */
 	SAVE_GPR(2, r1)			/* Save the TOC */
-	SAVE_GPR(13, r1)		/* Save current */
+	SAVE_GPR(13, r1)		/* Save paca */
 	SAVE_8GPRS(14, r1)		/* Save the non-volatiles */
 	SAVE_10GPRS(22, r1)		/* ditto */
 
@@ -465,14 +478,13 @@
 	mfsrr1	r10
 	std	r10,_SRR1(r1)
 
-	/* Unfortunatly, the stack pointer and the MSR are also clobbered,
-	 * so they are saved in the PACA (SPRG3) which allows us to restore
+	/* Unfortunately, the stack pointer and the MSR are also clobbered,
+	 * so they are saved in the PACA which allows us to restore
 	 * our original state after RTAS returns.
          */
-	mfspr	r4,SPRG3		/* Get PACA */
-	std	r1,PACAR1(r4)
+	std	r1,PACAR1(r13)
 	mfmsr	r6
-        std	r6,PACASAVEDMSR(r4)
+        std	r6,PACASAVEDMSR(r13)
 
 	/* Setup our real return addr */	
 	SET_REG_TO_LABEL(r4,.rtas_return_loc)
@@ -516,13 +528,11 @@
 _STATIC(rtas_restore_regs)
 	/* relocation is on at this point */
 	REST_GPR(2, r1)			/* Restore the TOC */
-	REST_GPR(13, r1)		/* Restore current */
+	REST_GPR(13, r1)		/* Restore paca */
 	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
 	REST_10GPRS(22, r1)		/* ditto */
 
-	/* put back current in r13 */
-        mfspr	r4,SPRG3
-	ld	r13,PACACURRENT(r4)
+	mfspr	r13,SPRG3
 
 	ld	r4,_CCR(r1)
 	mtcr	r4
@@ -555,7 +565,7 @@
 	 * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
    	 */
 	SAVE_8GPRS(2, r1)		/* Save the TOC & incoming param(s) */
-	SAVE_GPR(13, r1)		/* Save current */
+	SAVE_GPR(13, r1)		/* Save paca */
 	SAVE_8GPRS(14, r1)		/* Save the non-volatiles */
 	SAVE_10GPRS(22, r1)		/* ditto */
 
@@ -600,7 +610,7 @@
         isync
 
 	REST_8GPRS(2, r1)		/* Restore the TOC & param(s) */
-	REST_GPR(13, r1)		/* Restore current */
+	REST_GPR(13, r1)		/* Restore paca */
 	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
 	REST_10GPRS(22, r1)		/* ditto */
 	blrl				/* Entering PROM here... */
@@ -611,7 +621,7 @@
         isync
 
 	REST_GPR(2, r1)			/* Restore the TOC */
-	REST_GPR(13, r1)		/* Restore current */
+	REST_GPR(13, r1)		/* Restore paca */
 	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
 	REST_10GPRS(22, r1)		/* ditto */
 
diff -Nru a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
--- a/arch/ppc64/kernel/head.S	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/head.S	Wed Jul 24 14:03:38 2002
@@ -37,6 +37,12 @@
 #endif
 
 /*
+ * hcall interface to pSeries LPAR
+ */
+#define HSC .long 0x44000022
+#define H_SET_ASR		0x30
+
+/*
  * We layout physical memory as follows:
  * 0x0000 - 0x00ff : Secondary processor spin code
  * 0x0100 - 0x2fff : pSeries Interrupt prologs
@@ -152,7 +158,7 @@
  */
 
 /*
- * This is the start of the interrupt handlers for Pseries
+ * This is the start of the interrupt handlers for pSeries
  * This code runs with relocation off.
  */
 #define EX_SRR0		0
@@ -193,7 +199,7 @@
 	rfid
 
 /*
- * This is the start of the interrupt handlers for i_series
+ * This is the start of the interrupt handlers for iSeries
  * This code runs with relocation on.
  */
 #define EXCEPTION_PROLOG_ISERIES(n)	                                      \
@@ -269,7 +275,7 @@
 	SAVE_8GPRS(2, r1);              /* save r2 - r13 in stackframe */ \
 	SAVE_4GPRS(10, r1);                                               \
 	ld      r2,PACATOC(r20);	                                  \
-	ld      r13,PACACURRENT(r20)
+	mr	r13,r20
 
 /*
  * Note: code which follows this uses cr0.eq (set if from kernel),
@@ -427,8 +433,8 @@
 
 	.globl SystemReset_Iseries
 SystemReset_Iseries:
-	mfspr	25,SPRG3		/* Get paca address */
-	lhz	r24,PACAPACAINDEX(r25)	/* Get processor # */
+	mfspr	r13,SPRG3		/* Get paca address */
+	lhz	r24,PACAPACAINDEX(r13)	/* Get processor # */
 	cmpi	0,r24,0			/* Are we processor 0? */
 	beq	.__start_initialization_iSeries	/* Start up the first processor */
 	mfspr	r4,CTRLF
@@ -439,7 +445,7 @@
 1:
 	HMT_LOW
 #ifdef CONFIG_SMP
-	lbz	r23,PACAPROCSTART(r25)	/* Test if this processor
+	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor
 					 * should start */
 	sync
 	LOADADDR(r3,current_set)
@@ -469,7 +475,7 @@
 #endif /* CONFIG_SMP */
 	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
 	sc				/* Invoke the hypervisor via a system call */
-	mfspr	r25,SPRG3		/* Put r25 back ???? */
+	mfspr	r13,SPRG3		/* Put r13 back ???? */
 	b	1b			/* If SMP not configured, secondaries
 					 * loop forever */
 
@@ -575,7 +581,8 @@
 	bl	.do_stab_SI
 	b	1f
 
-2:	bl	.do_hash_page_DSI 	/* Try to handle as hpte fault */
+2:	li	r5,0x300
+	bl	.do_hash_page_DSI 	/* Try to handle as hpte fault */
 1:
 	ld      r4,_DAR(r1)
 	ld      r5,_DSISR(r1)
@@ -627,9 +634,8 @@
 	bl	.do_stab_SI
 	b	1f
 
-2:	andis.	r0,r23,0x4000		/* no pte found? */
-	beq	1f			/* if so, try to put a PTE */
-	mr	r3,r22			/* into the hash table */
+2:	mr	r3,r22
+	li	r5,0x400
 	bl	.do_hash_page_ISI	/* Try to handle as hpte fault */
 1:
 	mr	r4,r22
@@ -660,7 +666,7 @@
 #else
 	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
 #endif
-	li	r6,0x380
+	li	r6,0x480
 	bl      .save_remaining_regs
 	bl      .do_page_fault
 	b       .ret_from_except
@@ -682,33 +688,41 @@
 	/*                                                                */
 	/*  The call to do_irq will preserve the value of r14 - r31       */
 	/*                                                                */
-	mfspr	r20,SPRG3 		    /* get paca                   */
-	lbz     r21,PACAHRDWINTCOUNT(r20)    /* get hardware interrupt cnt */
+/*
+ * 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(r20)   /*                            */
+	stb     r21,PACAHRDWINTCOUNT(r13)   /*                            */
 	bne     2f                          /*                            */
 
 	mr      r14,r1                      /* preserve current r1        */
-	ld      r1,PACAHRDWINTSTACK(r20)    /*                            */
+	ld      r1,PACAHRDWINTSTACK(r13)    /*                            */
 	std     r14,0(r1)                   /* set the back chain         */
 	bl      .do_IRQ
-	lbz     r22,PACAHRDWINTCOUNT(r20)   /* get hardware interrupt cnt */
+	lbz     r22,PACAHRDWINTCOUNT(r13)   /* get hardware interrupt cnt */
 	cmp     0,r22,r21                   /* debug test                 */
 	bne     3f
 	subi    r21,r21,1
-	stb     r21,PACAHRDWINTCOUNT(r20)   /*                            */
+	stb     r21,PACAHRDWINTCOUNT(r13)   /*                            */
 	mr      r1,r14                      /*                            */
 	b       .ret_from_except
+#endif
 
 2:
 	bl      .do_IRQ
 
-	lbz     r22,PACAHRDWINTCOUNT(r20)   /* get hardware interrupt cnt */
+#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(r20)   /*                            */
+	stb     r21,PACAHRDWINTCOUNT(r13)   /*                            */
+#endif
 
 	b       .ret_from_except
 
@@ -804,6 +818,7 @@
 	/*
 	 * r3 contains the faulting address
 	 * r4 contains the required access permissions
+	 * r5 contains the trap number
 	 *
 	 * at return r3 = 0 for success
 	 */
@@ -852,11 +867,13 @@
 	ld	r22,8(r21)	/* get SRR1 */
 	andi.	r22,r22,MSR_PR	/* check if from user */
 	bne+	stab_bolted_user_return  /* from user, send the error on up */
+#if 0
 	li	r3,0
 #ifdef CONFIG_XMON
 	bl	.xmon
 #endif
 1:	b	1b
+#endif
 2:
 	/* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
 	mfspr	r21,DAR
@@ -1021,7 +1038,18 @@
 #ifndef CONFIG_PPC_ISERIES
 	ori	r20,r20,256    /* map kernel region with large ptes */
 #endif
-	
+
+	/*
+	 * XXX we should handle this in the exception exit path in 2.5,
+	 * we need to make this path quick - Anton
+	 */
+	/* Invalidate the old entry */
+	slbmfee	r21,r22
+	lis	r23,-2049
+	ori	r23,r23,65535
+	and	r21,r21,r23
+	slbie	r21
+
 	/* Put together the esid portion of the entry. */
 	mfspr	r21,DAR        /* Get the new esid                     */
 	rldicl  r21,r21,36,28  /* Permits a full 36b of ESID           */
@@ -1099,30 +1127,33 @@
 	 * Indicate that r1 contains the kernel stack and
 	 * get the Kernel TOC and CURRENT pointers from the paca
 	 */
-	mfspr	r23,SPRG3		/* Get PACA */
-	std	r22,PACAKSAVE(r23)	/* r1 is now kernel sp */
-	ld	r2,PACATOC(r23)		/* Get Kernel TOC pointer */
+	std	r22,PACAKSAVE(r13)	/* r1 is now kernel sp */
+	ld	r2,PACATOC(r13)		/* Get Kernel TOC pointer */
 
 	/*
 	 * If from user state, update THREAD.regs
 	 */
 	beq	2f			/* Modify THREAD.regs if from user */
 	addi	r24,r1,STACK_FRAME_OVERHEAD
-	std	r24,THREAD+PT_REGS(r13)
+	ld	r22, PACACURRENT(r13)
+	std	r24,THREAD+PT_REGS(r22)
 2:
 	SET_REG_TO_CONST(r22, MSR_KERNEL)
 
 #ifdef DO_SOFT_DISABLE
-	stb	r20,PACAPROCENABLED(r23) /* possibly soft enable */
+#warning FIX ISERIES
+	stb	r20,PACAPROCENABLED(r13) /* possibly soft enable */
 	ori	r22,r22,MSR_EE		/* always hard enable */
 #else
 	rldimi	r22,r20,15,48		/* Insert desired EE value */
 #endif
 
-	mtmsrd  r22
+	mtmsrd  r22,1
 	blr
 
-
+/*
+ * Kernel profiling with soft disable on iSeries
+ */
 do_profile:
 	ld	r22,8(r21)		/* Get SRR1 */
 	andi.	r22,r22,MSR_PR		/* Test if in kernel */
@@ -1158,20 +1189,20 @@
 
 	/* Set up a paca value for this processor. */
 	LOADADDR(r24, paca) 		 /* Get base vaddr of paca array  */
-	mulli	r25,r3,PACA_SIZE	 /* Calculate vaddr of right paca */
-	add	r25,r25,r24              /* for this processor.           */
+	mulli	r13,r3,PACA_SIZE	 /* Calculate vaddr of right paca */
+	add	r13,r13,r24              /* for this processor.           */
 
-	mtspr	SPRG3,r25		 /* Save vaddr of paca in SPRG3   */
+	mtspr	SPRG3,r13		 /* Save vaddr of paca in SPRG3   */
 	mr	r24,r3			 /* __secondary_start needs cpu#  */
 
 1:
 	HMT_LOW
-	lbz	r23,PACAPROCSTART(r25)	 /* Test if this processor should */
+	lbz	r23,PACAPROCSTART(r13)	 /* Test if this processor should */
 					 /* start.                        */
 	sync
 
         /* Create a temp kernel stack for use before relocation is on.    */
-        mr      r1,r25
+        mr      r1,r13
         addi    r1,r1,PACAGUARD
         addi    r1,r1,0x1000
         subi    r1,r1,STACK_FRAME_OVERHEAD
@@ -1400,7 +1431,8 @@
 #endif /* CONFIG_SMP */
 	/* enable use of FP after return */
 	ori	r23,r23,MSR_FP|MSR_FE0|MSR_FE1
-	addi	r5,r13,THREAD		/* Get THREAD */
+	ld	r4, PACACURRENT(r13)
+	addi	r5,r4,THREAD		/* Get THREAD */
 	lfd	fr0,THREAD_FPSCR-4(r5)
 	mtfsf	0xff,fr0
 	REST_32FPRS(0, r5)
@@ -1420,8 +1452,7 @@
 	ori	r3,r3,MSR_FP
 	std	r3,_MSR(r1)		/* enable use of FP after return */
 	LOADADDR(r3,86f)
-	mfspr	r4,SPRG3		/* Get PACA */
-	ld	r4,PACACURRENT(r4)	/* current */
+	ld	r4,PACACURRENT(r13)	/* current */
 	ld	r5,_NIP(r1)
 	b	.ret_from_except
 86:	.string	"floating point used in kernel (task=%p, pc=%x)\n"
@@ -1470,7 +1501,7 @@
  * On entry the following are set:
  *   r1    = stack pointer.  vaddr for iSeries, raddr (temp stack) for pSeries
  *   r24   = cpu# (in Linux terms)
- *   r25   = paca virtual address
+ *   r13   = paca virtual address
  *   SPRG3 = paca virtual address
  */
 _GLOBAL(__secondary_start)
@@ -1482,10 +1513,10 @@
 	addi    r2,r2,0x4000
 	addi    r2,r2,0x4000
 
-	std	r2,PACATOC(r25)
+	std	r2,PACATOC(r13)
 	li	r6,0
-	std	r6,PACAKSAVE(r25)
-	stb	r6,PACAPROCENABLED(r25)
+	std	r6,PACAKSAVE(r13)
+	stb	r6,PACAPROCENABLED(r13)
 
 #ifndef CONFIG_PPC_ISERIES
 	/* Initialize the page table pointer register. */
@@ -1494,12 +1525,9 @@
 	mtspr	SDR1,r6			/* set the htab location  */
 #endif
 	/* Initialize the first segment table (or SLB) entry                */
-	ld	r3,PACASTABVIRT(r25)    /* get addr of segment table        */
+	ld	r3,PACASTABVIRT(r13)    /* get addr of segment table        */
 	bl	.stab_initialize
 
-	/* load current into r13 */
-	ld	r13,PACACURRENT(r25)
-
 	/* Initialize the kernel stack.  Just a repeat for iSeries.         */
 	LOADADDR(r3,current_set)
 	sldi	r28,r24,3		/* get current_set[cpu#] */
@@ -1507,7 +1535,7 @@
 	addi	r1,r1,THREAD_SIZE
 	subi	r1,r1,STACK_FRAME_OVERHEAD
 
-	ld	r3,PACASTABREAL(r25)    /* get raddr of segment table       */
+	ld	r3,PACASTABREAL(r13)    /* get raddr of segment table       */
 	ori	r4,r3,1			/* turn on valid bit                */
 
 #ifdef CONFIG_PPC_ISERIES
@@ -1517,7 +1545,17 @@
 	ori	r3,r3,4			/* 0x8000000000000004 */
 	sc				/* HvCall_setASR */
 #else
+	/* set the ASR */
+	addi  r3,0,0x4000     /* r3 = ptr to naca */
+	lhz   r3,PLATFORM(r3) /* r3 = platform flags */
+	cmpldi r3,PLATFORM_PSERIES_LPAR
+	bne   98f
+	li	r3,H_SET_ASR  /* hcall = H_SET_ASR */
+	HSC     			    /* Invoking hcall */
+	b     99f
+98:             /* This is not a hypervisor machine */
 	mtasr	r4			/* set the stab location            */
+99:
 #endif
 	li	r7,0
 	mtlr	r7
@@ -1640,23 +1678,49 @@
 
 	/* Get the pointer to the segment table which is used by           */
 	/* stab_initialize                                                 */
-	li	r27,0x4000
-	ld	r6,PACA(r27)            /* Get the base paca pointer       */
-	sub	r6,r6,r26		/* convert to physical addr         */
-	mtspr	SPRG3,r6		/* PPPBBB: Temp... -Peter */
-	ld	r3,PACASTABREAL(r6)
+	LOADADDR(r27, boot_cpuid)
+	sub	r27,r27,r26
+	lwz	r27,0(r27)
+
+	LOADADDR(r24, paca) 		 /* Get base vaddr of paca array  */
+	mulli	r13,r27,PACA_SIZE	 /* Calculate vaddr of right paca */
+	add	r13,r13,r24              /* for this processor.           */
+	sub	r13,r13,r26		/* convert to physical addr         */
+
+	mtspr	SPRG3,r13		/* PPPBBB: Temp... -Peter */
+	li	r3,0x5000
+	std	r3,PACASTABREAL(r13)
+	LOADADDR(r24, __start_stab)
+	std	r24,PACASTABVIRT(r13)
 	ori	r4,r3,1			/* turn on valid bit                */
+	
+	/* set the ASR */
+	addi  r3,0,0x4000     /* r3 = ptr to naca */
+	lhz   r3,PLATFORM(r3) /* r3 = platform flags */
+	cmpldi r3,PLATFORM_PSERIES_LPAR
+	bne   98f
+	li	r3,H_SET_ASR  /* hcall = H_SET_ASR */
+	HSC     			    /* Invoking hcall */
+	b     99f
+98:                 /* This is not a hypervisor machine */
 	mtasr	r4			/* set the stab location            */
+99:
+	mfspr	r6,SPRG3
+	ld	r3,PACASTABREAL(r6)     /* restore r3 for stab_initialize */
 
 	/* Initialize an initial memory mapping and turn on relocation.   */
 	bl	.stab_initialize
 	bl	.htab_initialize
 
-	LOADADDR(r6,_SDR1)
+	addi  r3,0,0x4000     /* r3 = ptr to naca */
+	lhz   r3,PLATFORM(r3) /* r3 = platform flags */
+	cmpldi r3,PLATFORM_PSERIES
+	bne    98f
+	LOADADDR(r6,_SDR1)		/* Only if NOT LPAR */
 	sub	r6,r6,r26
 	ld	r6,0(r6)		/* get the value of _SDR1 */
 	mtspr	SDR1,r6			/* set the htab location  */
-
+98: 
 	LOADADDR(r3,.start_here_common)
 	SET_REG_TO_CONST(r4, MSR_KERNEL)
 	mtspr	SRR0,r3
@@ -1705,18 +1769,21 @@
 	addi	r8,r8,0x4000
 	std	r8,0(r9)		/* set the value of the naca ptr  */
 
-	LOADADDR(r4,naca)               /* Get naca ptr address           */
-	ld	r4,0(r4)                /* Get the location of the naca   */
-	ld	r4,PACA(r4)             /* Get the base paca pointer      */
-	mtspr	SPRG3,r4
+	LOADADDR(r26, boot_cpuid)
+	lwz	r26,0(r26)
+
+	LOADADDR(r24, paca) 		 /* Get base vaddr of paca array  */
+	mulli	r13,r26,PACA_SIZE	 /* Calculate vaddr of right paca */
+	add	r13,r13,r24              /* for this processor.           */
+	mtspr	SPRG3,r13
 
 	/* ptr to current */
-	LOADADDR(r13,init_task)
-	std	r13,PACACURRENT(r4)
+	LOADADDR(r4,init_task)
+	std	r4,PACACURRENT(r13)
 
-	std	r2,PACATOC(r4)
+	std	r2,PACATOC(r13)
 	li	r5,0
-	std	r0,PACAKSAVE(r4)
+	std	r0,PACAKSAVE(r13)
 
 	/* ptr to hardware interrupt stack for processor 0                */
 	LOADADDR(r3, hardware_int_paca0)
@@ -1725,10 +1792,10 @@
 	subi    r5,r5,STACK_FRAME_OVERHEAD
 
 	add     r3,r3,r5
-	std     r3,PACAHRDWINTSTACK(r4)
+	std     r3,PACAHRDWINTSTACK(r13)
 
 	li      r3,0
-	stb     r3,PACAHRDWINTCOUNT(r4)
+	stb     r3,PACAHRDWINTCOUNT(r13)
 
 	/* Restore the parms passed in from the bootloader. */
 	mr	r3,r31
@@ -1742,6 +1809,7 @@
 	/* Load up the kernel context */
 5:
 #ifdef DO_SOFT_DISABLE
+#warning FIX ISERIES
 	mfspr	r4,SPRG3
 	li	r5,0
 	stb	r5,PACAPROCENABLED(r4)	/* Soft Disabled */
@@ -1849,10 +1917,10 @@
 hardware_int_paca0:
 	.space	8*4096
 
-/* 1 page segment table per cpu (max 48, cpu0 allocated at 0x5000) */
+/* 1 page segment table per cpu (max 48) */
 	.globl	stab_array
 stab_array:
-        .space	4096 * (48 - 1)
+        .space	4096 * 48
 	
 /*
  * This space gets a copy of optional info passed to us by the bootstrap
diff -Nru a/arch/ppc64/kernel/htab.c b/arch/ppc64/kernel/htab.c
--- a/arch/ppc64/kernel/htab.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/htab.c	Wed Jul 24 14:03:38 2002
@@ -35,7 +35,6 @@
 #include <asm/mmu_context.h>
 #include <asm/page.h>
 #include <asm/types.h>
-#include <asm/init.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/naca.h>
@@ -45,9 +44,8 @@
 #include <asm/lmb.h>
 #include <asm/abs_addr.h>
 #include <asm/tlbflush.h>
-#ifdef CONFIG_PPC_EEH
 #include <asm/eeh.h>
-#endif
+#include <asm/tlb.h>
 
 /*
  * Note:  pte   --> Linux PTE
@@ -141,7 +139,7 @@
 	mask = pteg_count-1;
 
 	/* XXX we currently map kernel text rw, should fix this */
-	if (__is_processor(PV_POWER4) && _naca->physicalMemorySize > 256*MB) {
+	if (cpu_has_largepage() && _naca->physicalMemorySize > 256*MB) {
 		create_pte_mapping((unsigned long)KERNELBASE, 
 				   KERNELBASE + 256*MB, mode_rw, mask, 0);
 		create_pte_mapping((unsigned long)KERNELBASE + 256*MB, 
@@ -196,7 +194,7 @@
  * to be valid via Linux page tables, return 1. If handled return 0
  */
 int __hash_page(unsigned long ea, unsigned long access, unsigned long vsid,
-		pte_t *ptep)
+		pte_t *ptep, unsigned long trap)
 {
 	unsigned long va, vpn;
 	unsigned long newpp, prpn;
@@ -212,7 +210,7 @@
 	 * If no pte found or not present, send the problem up to
 	 * do_page_fault
 	 */
-	if (!ptep || !pte_present(*ptep))
+	if (unlikely(!ptep || !pte_present(*ptep)))
 		return 1;
 
 	/* 
@@ -220,7 +218,7 @@
 	 * prevented then send the problem up to do_page_fault.
 	 */
 	access |= _PAGE_PRESENT;
-	if (access & ~(pte_val(*ptep)))
+	if (unlikely(access & ~(pte_val(*ptep))))
 		return 1;
 
 	/*
@@ -245,8 +243,26 @@
 
 	newpp = computeHptePP(pte_val(new_pte));
 
+#define PPC64_HWNOEXEC (1 << 2)
+
+	/* We do lazy icache flushing on cpus that support it */
+	if (unlikely(cpu_has_noexecute() && pfn_valid(pte_pfn(new_pte)))) {
+		struct page *page = pte_page(new_pte);
+
+		/* page is dirty */
+		if (!PageReserved(page) &&
+		    !test_bit(PG_arch_1, &page->flags)) {
+			if (trap == 0x400) {
+				__flush_dcache_icache(page_address(page));
+				set_bit(PG_arch_1, &page->flags);
+			} else {
+				newpp |= PPC64_HWNOEXEC;
+			}
+		}
+	}
+
 	/* Check if pte already has an hpte (case 2) */
-	if (pte_val(old_pte) & _PAGE_HASHPTE) {
+	if (unlikely(pte_val(old_pte) & _PAGE_HASHPTE)) {
 		/* There MIGHT be an HPTE for this pte */
 		unsigned long hash, slot, secondary;
 
@@ -266,7 +282,7 @@
 				*ptep = new_pte;
 	}
 
-	if (!(pte_val(old_pte) & _PAGE_HASHPTE)) {
+	if (likely(!(pte_val(old_pte) & _PAGE_HASHPTE))) {
 		/* XXX fix large pte flag */
 		unsigned long hash = hpt_hash(vpn, 0);
 		unsigned long hpte_group;
@@ -318,7 +334,7 @@
 	return 0;
 }
 
-int hash_page(unsigned long ea, unsigned long access)
+int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
 {
 	void *pgdir;
 	unsigned long vsid;
@@ -346,13 +362,11 @@
 		mm = &init_mm;
 		vsid = get_kernel_vsid(ea);
 		break;
-#ifdef CONFIG_PPC_EEH
 	case IO_UNMAPPED_REGION_ID:
 		udbg_printf("EEH Error ea = 0x%lx\n", ea);
 		PPCDBG_ENTER_DEBUGGER();
 		panic("EEH Error ea = 0x%lx\n", ea);
 		break;
-#endif
 	case KERNEL_REGION_ID:
 		/*
 		 * As htab_initialize is now, we shouldn't ever get here since
@@ -379,7 +393,7 @@
 	 */
 	spin_lock(&mm->page_table_lock);
 	ptep = find_linux_pte(pgdir, ea);
-	ret = __hash_page(ea, access, vsid, ptep);
+	ret = __hash_page(ea, access, vsid, ptep, trap);
 	spin_unlock(&mm->page_table_lock);
 
 	return ret;
@@ -419,12 +433,11 @@
 		ppc_md.flush_hash_range(context, number, local);
 	} else {
 		int i;
-		struct tlb_batch_data *ptes =
-			&tlb_batch_array[smp_processor_id()][0];
+		struct ppc64_tlb_batch *batch =
+			&ppc64_tlb_batch[smp_processor_id()];
 
-		for (i = 0; i < number; i++) {
-			flush_hash_page(context, ptes->addr, ptes->pte, local);
-			ptes++;
-		}
+		for (i = 0; i < number; i++)
+			flush_hash_page(context, batch->addr[i], batch->pte[i],
+					local);
 	}
 }
diff -Nru a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c
--- a/arch/ppc64/kernel/iSeries_pci.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/iSeries_pci.c	Wed Jul 24 14:03:39 2002
@@ -21,7 +21,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/kernel.h>
 #include <linux/list.h> 
 #include <linux/string.h>
diff -Nru a/arch/ppc64/kernel/iSeries_pci_reset.c b/arch/ppc64/kernel/iSeries_pci_reset.c
--- a/arch/ppc64/kernel/iSeries_pci_reset.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/iSeries_pci_reset.c	Wed Jul 24 14:03:39 2002
@@ -32,7 +32,6 @@
 #include <linux/irq.h>
 
 #include <asm/io.h>
-#include <asm/init.h>
 #include <asm/iSeries/HvCallPci.h>
 #include <asm/iSeries/HvTypes.h>
 #include <asm/iSeries/mf.h>
diff -Nru a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
--- a/arch/ppc64/kernel/iSeries_setup.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/iSeries_setup.c	Wed Jul 24 14:03:39 2002
@@ -258,7 +258,7 @@
 {
 	unsigned long i;
 	unsigned long mem_blocks = 0;
-	if ( __is_processor( PV_POWER4 ) )
+	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
 		mem_blocks = iSeries_process_Regatta_mainstore_vpd( mb_array, max_entries );
 	else
 		mem_blocks = iSeries_process_Condor_mainstore_vpd( mb_array, max_entries );
diff -Nru a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
--- a/arch/ppc64/kernel/irq.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/irq.c	Wed Jul 24 14:03:38 2002
@@ -1,6 +1,4 @@
 /*
- * 
- *
  *  arch/ppc/kernel/irq.c
  *
  *  Derived from arch/i386/kernel/irq.c
@@ -25,7 +23,6 @@
  * should be easier.
  */
 
-
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/threads.h>
@@ -81,7 +78,7 @@
  * this needs to be removed.
  * -- Cort
  */
-#define IRQ_KMALLOC_ENTRIES 8
+#define IRQ_KMALLOC_ENTRIES 16
 static int cache_bitmask = 0;
 static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES];
 extern int mem_init_done;
@@ -168,6 +165,20 @@
 	return 0;
 }
 
+#ifdef CONFIG_SMP
+
+inline void synchronize_irq(unsigned int irq)
+{
+	while (irq_desc[irq].status & IRQ_INPROGRESS) {
+		barrier();
+		cpu_relax();
+	}
+}
+
+#endif /* CONFIG_SMP */
+
+/* XXX Make this into free_irq() - Anton */
+
 /* This could be promoted to a real free_irq() ... */
 static int
 do_free_irq(int irq, void* dev_id)
@@ -195,11 +206,8 @@
 			}
 			spin_unlock_irqrestore(&desc->lock,flags);
 
-#ifdef CONFIG_SMP
 			/* Wait to make sure it's not being used on another CPU */
-			while (desc->status & IRQ_INPROGRESS)
-				barrier();
-#endif
+			synchronize_irq(irq);
 			irq_kfree(action);
 			return 0;
 		}
@@ -296,12 +304,7 @@
 void disable_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
-
-	if (!local_irq_count(smp_processor_id())) {
-		do {
-			barrier();
-		} while (irq_desc[irq].status & IRQ_INPROGRESS);
-	}
+	synchronize_irq(irq);
 }
 
 /**
@@ -346,8 +349,10 @@
 	struct irqaction * action;
 
 	seq_printf(p, "           ");
-	for (j=0; j<smp_num_cpus; j++)
-		seq_printf(p, "CPU%d       ",j);
+	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++) {
@@ -356,9 +361,10 @@
 			continue;
 		seq_printf(p, "%3d: ", i);		
 #ifdef CONFIG_SMP
-		for (j = 0; j < smp_num_cpus; j++)
-			seq_printf(p, "%10u ",
-				kstat.irqs[cpu_logical_map(j)][i]);
+		for (j = 0; j < NR_CPUS; j++) {
+			if (cpu_online(j))
+				seq_printf(p, "%10u ", kstat.irqs[j][i]);
+		}
 #else		
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #endif /* CONFIG_SMP */
@@ -382,7 +388,7 @@
 	int status = 0;
 
 	if (!(action->flags & SA_INTERRUPT))
-		__sti();
+		local_irq_enable();
 
 	do {
 		status |= action->flags;
@@ -391,7 +397,7 @@
 	} while (action);
 	if (status & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	__cli();
+	local_irq_disable();
 }
 
 #ifdef CONFIG_SMP
@@ -403,7 +409,7 @@
 } ____cacheline_aligned irq_balance_t;
 
 static irq_balance_t irq_balance[NR_IRQS] __cacheline_aligned
-			= { [ 0 ... NR_IRQS-1 ] = { 1, 0 } };
+			= { [ 0 ... NR_IRQS-1 ] = { 0, 0 } };
 
 #define IDLE_ENOUGH(cpu,now) \
 		(idle_cpu(cpu) && ((now) - irq_stat[(cpu)].idle_timestamp > ((HZ/100)+1)))
@@ -425,14 +431,14 @@
 inside:
 		if (direction == 1) {
 			cpu++;
-			if (cpu >= smp_num_cpus)
+			if (cpu >= NR_CPUS)
 				cpu = 0;
 		} else {
 			cpu--;
 			if (cpu == -1)
-				cpu = smp_num_cpus-1;
+				cpu = NR_CPUS-1;
 		}
-	} while (!IRQ_ALLOWED(cpu,allowed_mask) ||
+	} while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu,allowed_mask) ||
 			(search_idle && !IDLE_ENOUGH(cpu,now)));
 
 	return cpu;
@@ -474,7 +480,9 @@
 	int cpu = smp_processor_id();
 	irq_desc_t *desc = irq_desc + irq;
 
-	balance_irq(irq);
+	/* XXX This causes bad performance and lockups on XICS - Anton */
+	if (naca->interrupt_controller == IC_OPEN_PIC)
+		balance_irq(irq);
 
 	kstat.irqs[cpu][irq]++;
 	spin_lock(&desc->lock);
@@ -566,7 +574,7 @@
 	struct ItLpQueue *lpq;
 #endif
 
-	irq_enter(cpu);
+	irq_enter();
 
 #ifdef CONFIG_PPC_ISERIES
 	lpaca = get_paca();
@@ -597,7 +605,7 @@
 		ppc_spurious_interrupts++;
 #endif
 
-        irq_exit(cpu);
+        irq_exit();
 
 #ifdef CONFIG_PPC_ISERIES
 	if (lpaca->xLpPaca.xIntDword.xFields.xDecrInt) {
@@ -640,156 +648,6 @@
 	ppc_md.init_IRQ();
 	if(ppc_md.init_ras_IRQ) ppc_md.init_ras_IRQ(); 
 }
-
-#ifdef CONFIG_SMP
-unsigned char global_irq_holder = NO_PROC_ID;
-
-static void show(char * str)
-{
-	int cpu = smp_processor_id();
-	int i;
-
-	printk("\n%s, CPU %d:\n", str, cpu);
-	printk("irq:  %d [ ", irqs_running());
-	for (i = 0; i < smp_num_cpus; i++)
-		printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]);
-	printk("]\nbh:   %d [ ",
-		(spin_is_locked(&global_bh_lock) ? 1 : 0));
-	for (i = 0; i < smp_num_cpus; i++)
-		printk("%u ", local_bh_count(i));
-	printk("]\n");
-}
-
-#define MAXCOUNT 10000000
-
-void synchronize_irq(void)
-{
-	if (irqs_running()) {
-		cli();
-		sti();
-	}
-}
-
-static inline void get_irqlock(int cpu)
-{
-        int count;
-
-        if ((unsigned char)cpu == global_irq_holder)
-                return;
-
-        count = MAXCOUNT;
-again:
-        br_write_lock(BR_GLOBALIRQ_LOCK);
-        for (;;) {
-                spinlock_t *lock;
-
-                if (!irqs_running() &&
-                    (local_bh_count(smp_processor_id()) || !spin_is_locked(&global_bh_lock)))
-                        break;
-
-                br_write_unlock(BR_GLOBALIRQ_LOCK);
-                lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
-                while (irqs_running() ||
-                       spin_is_locked(lock) ||
-                       (!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) {
-                        if (!--count) {
-                                show("get_irqlock");
-                                count = (~0 >> 1);
-                        }
-                        __sti();
-                        barrier();
-                        __cli();
-                }
-                goto again;
-        }
-
-        global_irq_holder = cpu;
-}
-
-/*
- * A global "cli()" while in an interrupt context
- * turns into just a local cli(). Interrupts
- * should use spinlocks for the (very unlikely)
- * case that they ever want to protect against
- * each other.
- *
- * If we already have local interrupts disabled,
- * this will not turn a local disable into a
- * global one (problems with spinlocks: this makes
- * save_flags+cli+sti usable inside a spinlock).
- */
-void __global_cli(void)
-{
-	unsigned long flags;
-	
-	__save_flags(flags);
-	if (flags & (1UL << 15)) {
-		int cpu = smp_processor_id();
-		__cli();
-		if (!local_irq_count(cpu))
-			get_irqlock(cpu);
-	}
-}
-
-void __global_sti(void)
-{
-	int cpu = smp_processor_id();
-
-	if (!local_irq_count(cpu))
-		release_irqlock(cpu);
-	__sti();
-}
-
-/*
- * SMP flags value to restore to:
- * 0 - global cli
- * 1 - global sti
- * 2 - local cli
- * 3 - local sti
- */
-unsigned long __global_save_flags(void)
-{
-	int retval;
-	int local_enabled;
-	unsigned long flags;
-
-	__save_flags(flags);
-	local_enabled = (flags >> 15) & 1;
-	/* default to local */
-	retval = 2 + local_enabled;
-
-	/* check for global flags if we're not in an interrupt */
-	if (!local_irq_count(smp_processor_id())) {
-		if (local_enabled)
-			retval = 1;
-		if (global_irq_holder == (unsigned char) smp_processor_id())
-			retval = 0;
-	}
-	return retval;
-}
-
-void __global_restore_flags(unsigned long flags)
-{
-	switch (flags) {
-	case 0:
-		__global_cli();
-		break;
-	case 1:
-		__global_sti();
-		break;
-	case 2:
-		__cli();
-		break;
-	case 3:
-		__sti();
-		break;
-	default:
-		printk("global_restore_flags: %016lx caller %p\n",
-			flags, __builtin_return_address(0));
-	}
-}
-
-#endif /* CONFIG_SMP */
 
 static struct proc_dir_entry * root_irq_dir;
 static struct proc_dir_entry * irq_dir [NR_IRQS];
diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
--- a/arch/ppc64/kernel/misc.S	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc64/kernel/misc.S	Wed Jul 24 14:03:37 2002
@@ -66,6 +66,7 @@
 #ifdef CONFIG_PPC_ISERIES
 /* unsigned long __no_use_save_flags(void) */
 _GLOBAL(__no_use_save_flags)
+#warning FIX ISERIES
 	mfspr	r4,SPRG3
 	lbz	r3,PACAPROCENABLED(r4)
 	blr
@@ -78,6 +79,7 @@
  * sense anyway.
  *    -- Cort
  */
+#warning FIX ISERIES
 	mfspr	r6,SPRG3
 	lbz	r5,PACAPROCENABLED(r6)
 	 /* Check if things are setup the way we want _already_. */
@@ -99,6 +101,7 @@
 	blr
 
 _GLOBAL(__no_use_cli)
+#warning FIX ISERIES
 	mfspr	r5,SPRG3
 	lbz	r3,PACAPROCENABLED(r5)
 	li	r4,0
@@ -106,6 +109,7 @@
 	blr			/* Done */
 
 _GLOBAL(__no_use_sti)
+#warning FIX ISERIES
 	mfspr	r6,SPRG3
 	li	r3,1
 	stb	r3,PACAPROCENABLED(r6)
diff -Nru a/arch/ppc64/kernel/mk_defs.c b/arch/ppc64/kernel/mk_defs.c
--- a/arch/ppc64/kernel/mk_defs.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/mk_defs.c	Wed Jul 24 14:03:38 2002
@@ -14,7 +14,6 @@
  */
 
 #include <stddef.h>
-#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -48,7 +47,6 @@
 	DEFINE(THREAD_SHIFT, THREAD_SHIFT);
 	DEFINE(THREAD_SIZE, THREAD_SIZE);
 	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
-	DEFINE(_TIF_32BIT, _TIF_32BIT);
 
 	/* task_struct->thread */
 	DEFINE(THREAD, offsetof(struct task_struct, thread));
@@ -68,6 +66,7 @@
         DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct naca_struct, iCacheL1LogLineSize));
         DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct naca_struct, iCacheL1LinesPerPage));
 	DEFINE(SLBSIZE, offsetof(struct naca_struct, slb_size));
+	DEFINE(PLATFORM, offsetof(struct naca_struct, platform));
 
 	/* paca */
         DEFINE(PACA_SIZE, sizeof(struct paca_struct));
diff -Nru a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c
--- a/arch/ppc64/kernel/nvram.c	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc64/kernel/nvram.c	Wed Jul 24 14:03:35 2002
@@ -99,11 +99,11 @@
 }
 
 struct file_operations nvram_fops = {
-	owner:		THIS_MODULE,
-	llseek:		nvram_llseek,
-	read:		read_nvram,
-	write:		write_nvram,
-	ioctl:		nvram_ioctl,
+	.owner =	THIS_MODULE,
+	.llseek =	nvram_llseek,
+	.read =		read_nvram,
+	.write =	write_nvram,
+	.ioctl =	nvram_ioctl,
 };
 
 static struct miscdevice nvram_dev = {
diff -Nru a/arch/ppc64/kernel/open_pic.c b/arch/ppc64/kernel/open_pic.c
--- a/arch/ppc64/kernel/open_pic.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/open_pic.c	Wed Jul 24 14:03:38 2002
@@ -33,7 +33,6 @@
 static volatile struct OpenPIC *OpenPIC = NULL;
 u_int OpenPIC_NumInitSenses __initdata = 0;
 u_char *OpenPIC_InitSenses __initdata = NULL;
-extern int use_of_interrupt_tree;
 
 void find_ISUs(void);
 
@@ -86,10 +85,10 @@
  */
 #ifdef CONFIG_SMP
 #define THIS_CPU		Processor[cpu]
-#define DECL_THIS_CPU		int cpu = hard_smp_processor_id()
+#define DECL_THIS_CPU		int cpu = smp_processor_id()
 #define CHECK_THIS_CPU		check_arg_cpu(cpu)
 #else
-#define THIS_CPU		Processor[hard_smp_processor_id()]
+#define THIS_CPU		Processor[smp_processor_id()]
 #define DECL_THIS_CPU
 #define CHECK_THIS_CPU
 #endif /* CONFIG_SMP */
@@ -357,7 +356,7 @@
 	/* SIOint (8259 cascade) is special */
 	if (offset) {
 		openpic_initirq(0, 8, offset, 1, 1);
-		openpic_mapirq(0, 1<<get_hard_smp_processor_id(0));
+		openpic_mapirq(0, 1 << boot_cpuid);
 	}
 
 	/* Init all external sources */
@@ -375,7 +374,7 @@
 		/* Enabled, Priority 8 or 9 */
 		openpic_initirq(i, pri, i+offset, !sense, sense);
 		/* Processor 0 */
-		openpic_mapirq(i, 1<<get_hard_smp_processor_id(0));
+		openpic_mapirq(i, 1 << boot_cpuid);
 	}
 
 	/* Init descriptors */
@@ -504,23 +503,10 @@
 			   vec);
 }
 
-/*
- * Convert a cpu mask from logical to physical cpu numbers.
- */
-static inline u32 physmask(u32 cpumask)
-{
-	int i;
-	u32 mask = 0;
-
-	for (i = 0; i < smp_num_cpus; ++i, cpumask >>= 1)
-		mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
-	return mask;
-}
-
 void openpic_init_processor(u_int cpumask)
 {
 	openpic_write(&OpenPIC->Global.Processor_Initialization,
-		      physmask(cpumask));
+		      cpumask & cpu_online_map);
 }
 
 #ifdef CONFIG_SMP
@@ -554,7 +540,7 @@
 	CHECK_THIS_CPU;
 	check_arg_ipi(ipi);
 	openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
-		      physmask(cpumask));
+		      cpumask & cpu_online_map);
 }
 
 void openpic_request_IPIs(void)
@@ -594,7 +580,7 @@
 {
 #ifdef CONFIG_IRQ_ALL_CPUS
  	int i;
-	u32 msk = 1 << hard_smp_processor_id();
+	u32 msk = 1 << smp_processor_id();
 #endif
 
 	spin_lock(&openpic_setup_lock);
@@ -639,7 +625,7 @@
 {
 	check_arg_timer(timer);
 	openpic_write(&OpenPIC->Global.Timer[timer].Destination,
-		      physmask(cpumask));
+		      cpumask & cpu_online_map);
 }
 
 
@@ -762,7 +748,7 @@
 
 static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask)
 {
-	openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask));
+	openpic_mapirq(irq_nr - open_pic_irq_offset, cpumask & cpu_online_map);
 }
 
 #ifdef CONFIG_SMP
@@ -775,7 +761,7 @@
 	 * SA_INTERRUPT flag and let them execute with all interrupts OFF.
 	 * This would have the side effect of either running cross-CPU
 	 * functions with interrupts off, or we can re-enable them explicitely
-	 * with a __sti() in smp_call_function_interrupt(), since
+	 * with a local_irq_enable() in smp_call_function_interrupt(), since
 	 * smp_call_function() is protected by a spinlock.
 	 * Or maybe we shouldn't set the IRQ_PER_CPU flag on cross-CPU
 	 * function calls IPI at all but that would make a special case.
diff -Nru a/arch/ppc64/kernel/pSeries_htab.c b/arch/ppc64/kernel/pSeries_htab.c
--- a/arch/ppc64/kernel/pSeries_htab.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc64/kernel/pSeries_htab.c	Wed Jul 24 14:03:37 2002
@@ -20,6 +20,7 @@
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
+#include <asm/tlb.h>
 
 /*
  * Create a pte. Used during initialization only.
@@ -214,7 +215,7 @@
 
 	__asm__ __volatile__(
 	"1:	ldarx	%0,0,%3\n\
-		rldimi	%0,%2,0,62\n\
+		rldimi	%0,%2,0,61\n\
 		stdcx.	%0,0,%3\n\
 		bne	1b"
 	: "=&r" (old), "=m" (*p)
@@ -265,8 +266,6 @@
 	unsigned long vpn, avpn;
 	unsigned long flags;
 
-	udbg_printf("updatepp\n");
-
 	if (large)
 		vpn = va >> LARGE_PAGE_SHIFT;
 	else
@@ -358,7 +357,7 @@
 	hptep->dw0.dword0 = 0;
 
 	/* Invalidate the tlb */
-	if (!large && local && __is_processor(PV_POWER4)) {
+	if (cpu_has_tlbiel() && !large && local) {
 		_tlbiel(va);
 	} else {
 		spin_lock_irqsave(&pSeries_tlbie_lock, flags);
@@ -372,31 +371,32 @@
 {
 	unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn;
 	int i, j;
-	unsigned long va_array[MAX_BATCH_FLUSH];
 	HPTE *hptep;
 	Hpte_dword0 dw0;
-	struct tlb_batch_data *ptes = &tlb_batch_array[smp_processor_id()][0];
+	struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[smp_processor_id()];
 	/* XXX fix for large ptes */
 	unsigned long large = 0;
+
 	j = 0;
 	for (i = 0; i < number; i++) {
-		if ((ptes->addr >= USER_START) && (ptes->addr <= USER_END))
-			vsid = get_vsid(context, ptes->addr);
+		if ((batch->addr[i] >= USER_START) &&
+		    (batch->addr[i] <= USER_END))
+			vsid = get_vsid(context, batch->addr[i]);
 		else
-			vsid = get_kernel_vsid(ptes->addr);
+			vsid = get_kernel_vsid(batch->addr[i]);
 
-		va = (vsid << 28) | (ptes->addr & 0x0fffffff);
-		va_array[j] = va;
+		va = (vsid << 28) | (batch->addr[i] & 0x0fffffff);
+		batch->vaddr[j] = va;
 		if (large)
 			vpn = va >> LARGE_PAGE_SHIFT;
 		else
 			vpn = va >> PAGE_SHIFT;
 		hash = hpt_hash(vpn, large);
-		secondary = (pte_val(ptes->pte) & _PAGE_SECONDARY) >> 15;
+		secondary = (pte_val(batch->pte[i]) & _PAGE_SECONDARY) >> 15;
 		if (secondary)
 			hash = ~hash;
 		slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
-		slot += (pte_val(ptes->pte) & _PAGE_GROUP_IX) >> 12;
+		slot += (pte_val(batch->pte[i]) & _PAGE_GROUP_IX) >> 12;
 
 		hptep = htab_data.htab + slot;
 		avpn = vpn >> 11;
@@ -405,8 +405,6 @@
 
 		dw0 = hptep->dw0.dw0;
 
-		ptes++;
-
 		if ((dw0.avpn != avpn) || !dw0.v) {
 			pSeries_unlock_hpte(hptep);
 			udbg_printf("invalidate missed\n");
@@ -419,14 +417,14 @@
 		hptep->dw0.dword0 = 0;
 	}
 
-	if (!large && local && __is_processor(PV_POWER4)) {
+	if (cpu_has_tlbiel() && !large && local) {
 		asm volatile("ptesync":::"memory");
 
 		for (i = 0; i < j; i++) {
 			asm volatile("\n\
 			clrldi  %0,%0,16\n\
 			tlbiel   %0"
-			: : "r" (va_array[i]) : "memory" );
+			: : "r" (batch->vaddr[i]) : "memory" );
 		}
 
 		asm volatile("ptesync":::"memory");
@@ -440,7 +438,7 @@
 			asm volatile("\n\
 			clrldi  %0,%0,16\n\
 			tlbie   %0"
-			: : "r" (va_array[i]) : "memory" );
+			: : "r" (batch->vaddr[i]) : "memory" );
 		}
 
 		asm volatile("eieio; tlbsync; ptesync":::"memory");
diff -Nru a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c
--- a/arch/ppc64/kernel/pSeries_lpar.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/pSeries_lpar.c	Wed Jul 24 14:03:39 2002
@@ -33,6 +33,7 @@
 #include <linux/pci.h>
 #include <asm/naca.h>
 #include <asm/tlbflush.h>
+#include <asm/tlb.h>
 
 /* Status return values */
 #define H_Success	0
@@ -308,7 +309,7 @@
 {
 	unsigned long lpar_rc;
 
-	lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu),value);
+	lpar_rc = plpar_ipi(n_cpu, value);
 	if (lpar_rc != H_Success) {
 		panic(" bad return code qirr -ipi  - rc = %lx \n", lpar_rc); 
 	}
@@ -355,8 +356,13 @@
 		/* get some more chars. */
 		inbuflen = 0;
 		rc = plpar_get_term_char(vtermno, &inbuflen, buf);
-		if (inbuflen == 0 && rc == H_Success)
-			return -1;
+		if (rc != H_Success)
+			inbuflen = 0;	/* otherwise inbuflen is garbage */
+	}
+	if (inbuflen <= 0 || inbuflen > 16) {
+		/* Catch error case as well as other oddities (corruption) */
+		inbuflen = 0;
+		return -1;
 	}
 	ch = buf[0];
 	for (i = 1; i < inbuflen; i++)	/* shuffle them down. */
@@ -646,11 +652,9 @@
 {
 	unsigned long lpar_rc;
 	unsigned long flags;
-	flags = (newpp & 3) | H_AVPN;
+	flags = (newpp & 7) | H_AVPN;
 	unsigned long vpn = va >> PAGE_SHIFT;
 
-	udbg_printf("updatepp\n");
-
 	lpar_rc = plpar_pte_protect(flags, slot, (vpn >> 4) & ~0x7fUL);
 
 	if (lpar_rc == H_Not_Found) {
@@ -775,15 +779,14 @@
 				   int local)
 {
 	int i;
-	struct tlb_batch_data *ptes =
-		&tlb_batch_array[smp_processor_id()][0];
 	unsigned long flags;
+	struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[smp_processor_id()];
 
 	spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
-	for (i = 0; i < number; i++) {
-		flush_hash_page(context, ptes->addr, ptes->pte, local);
-		ptes++;
-	}
+
+	for (i = 0; i < number; i++)
+		flush_hash_page(context, batch->addr[i], batch->pte[i], local);
+
 	spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
 }
 
diff -Nru a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
--- a/arch/ppc64/kernel/pSeries_pci.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/pSeries_pci.c	Wed Jul 24 14:03:39 2002
@@ -22,7 +22,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/threads.h>
 #include <linux/pci.h>
@@ -36,7 +35,6 @@
 #include <asm/irq.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
-#include <asm/init.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppcdebug.h>
 #include <asm/naca.h>
@@ -71,7 +69,7 @@
  *
  *****************************************************************************/
 #define RTAS_PCI_READ_OP(size, type, nbytes) \
-int __chrp \
+int \
 rtas_read_config_##size(struct device_node *dn, int offset, type val) {  \
 	unsigned long returnval = ~0L; \
 	unsigned long buid; \
@@ -96,7 +94,7 @@
 	*val = returnval; \
 	return ret; \
 } \
-int __chrp \
+int \
 rtas_pci_read_config_##size(struct pci_dev *dev, int offset, type val) {  \
         struct device_node *dn = pci_device_to_OF_node(dev); \
 	int ret = rtas_read_config_##size(dn, offset, val); \
@@ -105,7 +103,7 @@
 }
 
 #define RTAS_PCI_WRITE_OP(size, type, nbytes) \
-int __chrp \
+int \
 rtas_write_config_##size(struct device_node *dn, int offset, type val) { \
 	unsigned long buid; \
 	unsigned int addr; \
@@ -126,7 +124,7 @@
 	} \
 	return ret; \
 } \
-int __chrp \
+int \
 rtas_pci_write_config_##size(struct pci_dev *dev, int offset, type val) { \
 	struct device_node*  dn = pci_device_to_OF_node(dev); \
 	int  ret = rtas_write_config_##size(dn, offset, val); \
@@ -515,8 +513,10 @@
 
 	/***************************************************************
 	* Speedwagon
+	*   include Winnipeg as well for the time being.
 	***************************************************************/
-	} else if (strstr(model, "Speedwagon")) {
+	} else if ((strstr(model, "Speedwagon")) || 
+		   (strstr(model, "Winnipeg"))) {
 		PPCDBG(PPCDBG_PHBINIT, "\tCreate speedwagon\n");
 	        phb = pci_alloc_pci_controller("PHB SW",phb_type_speedwagon);
 		if (phb == NULL) return NULL;
diff -Nru a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c
--- a/arch/ppc64/kernel/pacaData.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/pacaData.c	Wed Jul 24 14:03:39 2002
@@ -31,36 +31,36 @@
  * processors.  The processor VPD array needs one entry per physical
  * processor (not thread).
  */
-#define PACAINITDATA(number,start,lpq,asrr,asrv) \
-{                                                                          \
-        xLpPacaPtr: &paca[number].xLpPaca,                                 \
-        xLpRegSavePtr: &paca[number].xRegSav,                              \
-        xPacaIndex: (number),           /* Paca Index        */             \
-        default_decr: 0x00ff0000,       /* Initial Decr      */             \
-        xStab_data: {                                                       \
-                real: (asrr),           /* Real pointer to segment table */ \
-                virt: (asrv),           /* Virt pointer to segment table */ \
-                next_round_robin: 1     /* Round robin index */             \
-        },                                                                  \
-        lpQueuePtr: (lpq),              /* &xItLpQueue,                  */ \
-        /* xRtas: {                                                            \
-                lock: SPIN_LOCK_UNLOCKED                                    \
-        }, */                                                                  \
-        xProcStart: (start),            /* Processor start */               \
-        xLpPaca: {                                                          \
-                xDesc: 0xd397d781,      /* "LpPa"          */               \
-                xSize: sizeof(struct ItLpPaca),                             \
-                xFPRegsInUse: 1,                                            \
-                xDynProcStatus: 2,                                          \
-		xDecrVal: 0x00ff0000,					    \
-                xEndOfQuantum: 0xffffffffffffffff                           \
-        },                                                                  \
-        xRegSav: {                                                          \
-                xDesc: 0xd397d9e2,      /* "LpRS"          */               \
-                xSize: sizeof(struct ItLpRegSave)                           \
-        },                                                                  \
-        exception_sp:                                                       \
-                (&paca[number].exception_stack[0]) - EXC_FRAME_SIZE,       \
+#define PACAINITDATA(number,start,lpq,asrr,asrv)			    \
+{									    \
+	.xLpPacaPtr = &paca[number].xLpPaca,				    \
+	.xLpRegSavePtr = &paca[number].xRegSav,				    \
+	.xPacaIndex = (number),		/* Paca Index */		    \
+	.default_decr = 0x00ff0000,	/* Initial Decr */		    \
+	.xStab_data = {							    \
+		.real = (asrr),		/* Real pointer to segment table */ \
+		.virt = (asrv),		/* Virt pointer to segment table */ \
+		.next_round_robin = 1	/* Round robin index */		    \
+	},								    \
+	.lpQueuePtr = (lpq),		/* &xItLpQueue, */		    \
+	/* .xRtas = {							    \
+		.lock = SPIN_LOCK_UNLOCKED				    \
+	}, */								    \
+	.xProcStart = (start),		/* Processor start */		    \
+	.xLpPaca = {							    \
+		.xDesc = 0xd397d781,	/* "LpPa" */			    \
+		.xSize = sizeof(struct ItLpPaca),			    \
+		.xFPRegsInUse = 1,					    \
+		.xDynProcStatus = 2,					    \
+		.xDecrVal = 0x00ff0000,					    \
+		.xEndOfQuantum = 0xffffffffffffffff			    \
+	},								    \
+	.xRegSav = {							    \
+		.xDesc = 0xd397d9e2,	/* "LpRS" */			    \
+		.xSize = sizeof(struct ItLpRegSave)			    \
+	},								    \
+	.exception_sp =							    \
+		(&paca[number].exception_stack[0]) - EXC_FRAME_SIZE,	    \
 }
 
 struct paca_struct paca[MAX_PACAS] __page_aligned = {
diff -Nru a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
--- a/arch/ppc64/kernel/pci_dn.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/pci_dn.c	Wed Jul 24 14:03:38 2002
@@ -33,7 +33,6 @@
 #include <asm/irq.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
-#include <asm/init.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppcdebug.h>
 #include <asm/naca.h>
diff -Nru a/arch/ppc64/kernel/pmc.c b/arch/ppc64/kernel/pmc.c
--- a/arch/ppc64/kernel/pmc.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/kernel/pmc.c	Wed Jul 24 14:03:36 2002
@@ -59,7 +59,9 @@
 	stab_faults = stab_capacity_castouts = stab_invalidations = n = 0;
 
 	if (file == -1) {
-		for (i = 0;  i < smp_num_cpus; i++) {
+		for (i = 0;  i < NR_CPUS; i++) {
+			if (!cpu_online(i))
+				continue;
 			stab_faults += pmc_sw_cpu[i].stab_faults;
 			stab_capacity_castouts += pmc_sw_cpu[i].stab_capacity_castouts;
 			stab_invalidations += pmc_sw_cpu[i].stab_invalidations;
diff -Nru a/arch/ppc64/kernel/ppc_asm.h b/arch/ppc64/kernel/ppc_asm.h
--- a/arch/ppc64/kernel/ppc_asm.h	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc64/kernel/ppc_asm.h	Wed Jul 24 14:03:37 2002
@@ -11,8 +11,6 @@
  *  2 of the License, or (at your option) any later version.
  */
 
-#include <linux/config.h>
-
 #include <asm/ppc_asm.tmpl>
 #include "ppc_defs.h"
 
diff -Nru a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
--- a/arch/ppc64/kernel/ppc_ksyms.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/kernel/ppc_ksyms.c	Wed Jul 24 14:03:36 2002
@@ -86,8 +86,6 @@
 EXPORT_SYMBOL(disable_irq_nosync);
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(kernel_flag);
-EXPORT_SYMBOL(synchronize_irq);
-EXPORT_SYMBOL(smp_num_cpus);
 #endif /* CONFIG_SMP */
 
 EXPORT_SYMBOL(register_ioctl32_conversion);
@@ -212,10 +210,6 @@
 EXPORT_SYMBOL(flush_icache_page);
 EXPORT_SYMBOL(flush_dcache_page);
 #ifdef CONFIG_SMP
-EXPORT_SYMBOL(__global_cli);
-EXPORT_SYMBOL(__global_sti);
-EXPORT_SYMBOL(__global_save_flags);
-EXPORT_SYMBOL(__global_restore_flags);
 #ifdef CONFIG_PPC_ISERIES
 EXPORT_SYMBOL(__no_use_restore_flags);
 EXPORT_SYMBOL(__no_use_save_flags);
diff -Nru a/arch/ppc64/kernel/proc_pmc.c b/arch/ppc64/kernel/proc_pmc.c
--- a/arch/ppc64/kernel/proc_pmc.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc64/kernel/proc_pmc.c	Wed Jul 24 14:03:37 2002
@@ -24,6 +24,10 @@
  * End Change Activity 
  */
 
+#include <linux/config.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+
 #include <asm/proc_fs.h>
 #include <asm/paca.h>
 #include <asm/iSeries/ItLpPaca.h>
@@ -33,12 +37,10 @@
 #include <asm/processor.h>
 #include <asm/time.h>
 #include <asm/iSeries/LparData.h>
-
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
 #include <asm/pmc.h>
 #include <asm/uaccess.h>
 #include <asm/naca.h>
+#include <asm/rtas.h>
 
 
 static int proc_pmc_control_mode = 0;
@@ -100,21 +102,26 @@
 	if (!proc_ppc64_root) return;
 	spin_unlock(&proc_ppc64_lock);
 
-#ifdef CONFIG_PPC_EEH
-	eeh_init_proc(proc_ppc64_root);
-#endif
+	/* Placeholder for rtas interfaces. */
+	rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root);
+
 
 	proc_ppc64_pmc_root = proc_mkdir("pmc", proc_ppc64_root);
 
 	proc_ppc64_pmc_system_root = proc_mkdir("system", proc_ppc64_pmc_root);
-	for (i = 0; i < naca->processorCount; i++) {
-		sprintf(buf, "cpu%ld", i); 
-		proc_ppc64_pmc_cpu_root[i] = proc_mkdir(buf, proc_ppc64_pmc_root);
+	for (i = 0; i < NR_CPUS; i++) {
+		if (cpu_online(i)) {
+			sprintf(buf, "cpu%ld", i); 
+			proc_ppc64_pmc_cpu_root[i] =
+				proc_mkdir(buf, proc_ppc64_pmc_root);
+		}
 	}
 
 
 	/* Create directories for the software counters. */
-	for (i = 0; i < naca->processorCount; i++) {
+	for (i = 0; i < NR_CPUS; i++) {
+		if (!cpu_online(i))
+			continue;
 		ent = create_proc_entry("stab", S_IRUGO | S_IWUSR, 
 					proc_ppc64_pmc_cpu_root[i]);
 		if (ent) {
@@ -153,7 +160,9 @@
 	}
 
 	/* Create directories for the hardware counters. */
-	for (i = 0; i < naca->processorCount; i++) {
+	for (i = 0; i < NR_CPUS; i++) {
+		if (!cpu_online(i))
+			continue;
 		ent = create_proc_entry("hardware", S_IRUGO | S_IWUSR, 
 					proc_ppc64_pmc_cpu_root[i]);
 		if (ent) {
@@ -189,7 +198,9 @@
 	   (unsigned long) proc_ppc64_pmc_system_root) {
 		return(-1); 
 	} else {
-		for (i = 0; i < naca->processorCount; i++) {
+		for (i = 0; i < NR_CPUS; i++) {
+			if (!cpu_online(i))
+				continue;
 			if ((unsigned long)data ==
 			   (unsigned long)proc_ppc64_pmc_cpu_root[i]) {
 				return(i); 
@@ -324,6 +335,7 @@
     if (!ent) return;
     ent->nlink = 1;
     ent->data = (void *)0;
+    ent->size = 0;
     ent->read_proc = proc_get_titanTod;
     ent->write_proc = NULL;
 
@@ -380,9 +392,10 @@
 			(unsigned long)xItLpQueue.xLpIntCountByType[i] );
 	}
 	len += sprintf( page+len, "\n  events processed by processor:\n" );
-	for (i=0; i<naca->processorCount; ++i) {
-		len += sprintf( page+len, "    CPU%02d  %10u\n",
-			i, paca[i].lpEvent_count );
+	for (i = 0; i < NR_CPUS; ++i) {
+		if (cpu_online(i))
+			len += sprintf( page+len, "    CPU%02d  %10u\n",
+				i, paca[i].lpEvent_count );
 	}
 
 	return pmc_calc_metrics( page, start, off, count, eof, len );
diff -Nru a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
--- a/arch/ppc64/kernel/process.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/process.c	Wed Jul 24 14:03:38 2002
@@ -44,8 +44,6 @@
 #include <asm/machdep.h>
 #include <asm/iSeries/HvCallHpt.h>
 
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs);
-
 struct task_struct *last_task_used_math = NULL;
 
 struct mm_struct ioremap_mm = { pgd             : ioremap_dir  
@@ -77,7 +75,7 @@
 }
 
 void
-_switch_to(struct task_struct *prev, struct task_struct *new)
+__switch_to(struct task_struct *prev, struct task_struct *new)
 {
 	struct thread_struct *new_thread, *old_thread;
 	unsigned long flags;
@@ -99,9 +97,9 @@
 	new_thread = &new->thread;
 	old_thread = &current->thread;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	_switch(old_thread, new_thread);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 void show_regs(struct pt_regs * regs)
@@ -177,9 +175,8 @@
 	childregs = (struct pt_regs *) sp;
 	*childregs = *regs;
 	if ((childregs->msr & MSR_PR) == 0) {
-		/* for kernel thread, set `current' and stackptr in new task */
+		/* for kernel thread, set stackptr in new task */
 		childregs->gpr[1] = sp + sizeof(struct pt_regs);
-		childregs->gpr[13] = (unsigned long) p;
 		p->thread.regs = NULL;	/* no user register state */
 		clear_ti_thread_flag(p->thread_info, TIF_32BIT);
 #ifdef CONFIG_PPC_ISERIES
@@ -300,13 +297,13 @@
 
 void initialize_paca_hardware_interrupt_stack(void)
 {
-	extern struct naca_struct *naca;
-
 	int i;
 	unsigned long stack;
 	unsigned long end_of_stack =0;
 
-	for (i=1; i < naca->processorCount; i++) {
+	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_KERNEL, get_order(8*PAGE_SIZE));
 
@@ -326,10 +323,12 @@
 	 * __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 (__is_processor(PV_POWER4))
+	if (cpu_has_largepage())
 		return;
 
-	for (i=0; i < naca->processorCount; i++) {
+	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);
diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
--- a/arch/ppc64/kernel/prom.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/prom.c	Wed Jul 24 14:03:39 2002
@@ -48,7 +48,6 @@
 #define call_yaboot(FUNC,...) do { ; } while (0)
 #endif
 
-#include <asm/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <asm/prom.h>
@@ -446,9 +445,12 @@
 	}
 
 	/* We gotta have at least 1 cpu... */
-        if ( (_naca->processorCount = num_cpus) < 1 )
+        if (num_cpus < 1)
                 PROM_BUG();
 
+	if (num_cpus > 1)
+		RELOC(ppc64_is_smp) = 1;
+
 	_naca->physicalMemorySize = lmb_phys_mem_size();
 
 	if (_naca->platform == PLATFORM_PSERIES) {
@@ -478,10 +480,6 @@
 	_naca->slb_size = 64;
 
 #ifdef DEBUG_PROM
-        prom_print(RELOC("naca->processorCount       = 0x"));
-        prom_print_hex(_naca->processorCount);
-        prom_print_nl();
-
         prom_print(RELOC("naca->physicalMemorySize   = 0x"));
         prom_print_hex(_naca->physicalMemorySize);
         prom_print_nl();
@@ -904,11 +902,13 @@
 		/* Keep the old logic in tack to avoid regression. */
 		if (compatible[0] != 0) {
 			if((strstr(compatible, RELOC("python")) == NULL) &&
-			   (strstr(compatible, RELOC("Speedwagon")) == NULL))
+			   (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
+			   (strstr(compatible, RELOC("Winnipeg")) == NULL))
 				continue;
 		} else if (model[0] != 0) {
 			if ((strstr(model, RELOC("ython")) == NULL) &&
-			    (strstr(model, RELOC("peedwagon")) == NULL))
+			    (strstr(model, RELOC("peedwagon")) == NULL) &&
+			    (strstr(model, RELOC("innipeg")) == NULL))
 				continue;
 		}
 
@@ -1045,20 +1045,15 @@
 	phandle node;
 	unsigned long offset = reloc_offset();
 	char type[64], *path;
-	int cpuid = 0;
 	extern void __secondary_hold(void);
         extern unsigned long __secondary_hold_spinloop;
         extern unsigned long __secondary_hold_acknowledge;
         unsigned long *spinloop     = __v2a(&__secondary_hold_spinloop);
         unsigned long *acknowledge  = __v2a(&__secondary_hold_acknowledge);
         unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold));
-        struct naca_struct *_naca = RELOC(naca);
 	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
 	struct prom_t *_prom = PTRRELOC(&prom);
 
-	/* Initially, we must have one active CPU. */
-	_naca->processorCount = 1;
-
 #ifdef DEBUG_PROM
 	prom_print(RELOC("prom_hold_cpus: start...\n"));
 	prom_print(RELOC("    1) spinloop       = 0x"));
@@ -1118,19 +1113,12 @@
 				     node, path, 255) < 0)
 			continue;
 
-		cpuid++;
-
 #ifdef DEBUG_PROM
 		prom_print_nl();
-		prom_print(RELOC("cpuid        = 0x"));
-		prom_print_hex(cpuid);
-		prom_print_nl();
 		prom_print(RELOC("cpu hw idx   = 0x"));
 		prom_print_hex(reg);
 		prom_print_nl();
 #endif
-		_xPaca[cpuid].xHwProcNum = reg;
-
 		prom_print(RELOC("starting cpu "));
 		prom_print(path);
 
@@ -1156,11 +1144,9 @@
 		prom_print(RELOC("    3) secondary_hold = 0x"));
 		prom_print_hex(secondary_hold);
 		prom_print_nl();
-		prom_print(RELOC("    3) cpuid = 0x"));
-		prom_print_hex(cpuid);
 		prom_print_nl();
 #endif
-		call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid);
+		call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, reg);
 		prom_print(RELOC("..."));
 		for ( i = 0 ; (i < 100000000) && 
 			      (*acknowledge == ((unsigned long)-1)); i++ ) ;
@@ -1172,10 +1158,10 @@
 			prom_print_nl();
 		}
 #endif
-		if (*acknowledge == cpuid) {
+		if (*acknowledge == reg) {
 			prom_print(RELOC("ok\n"));
 			/* Set the number of active processors. */
-			_naca->processorCount++;
+			_xPaca[reg].active = 1;
 		} else {
 			prom_print(RELOC("failed: "));
 			prom_print_hex(*acknowledge);
@@ -1189,10 +1175,11 @@
 	    __is_processor(PV_SSTAR)) {
 		prom_print(RELOC("    starting secondary threads\n"));
 
-		for (i=0; i < _naca->processorCount ;i++) {
-			unsigned long threadid = _naca->processorCount*2-1-i;
-			
-			if (i == 0) {
+		for (i = 0; i < NR_CPUS; i += 2) {
+			if (!_xPaca[i].active)
+				continue;
+
+			if (i == boot_cpuid) {
 				unsigned long pir = _get_PIR();
 				if (__is_processor(PV_PULSAR)) {
 					RELOC(hmt_thread_data)[i].pir = 
@@ -1202,21 +1189,9 @@
 						pir & 0x3ff;
 				}
 			}
-			
-			RELOC(hmt_thread_data)[i].threadid = threadid;
-#ifdef DEBUG_PROM
-			prom_print(RELOC("        cpuid 0x"));
-			prom_print_hex(i);
-			prom_print(RELOC(" maps to threadid 0x"));
-			prom_print_hex(threadid);
-			prom_print_nl();
-			prom_print(RELOC(" pir 0x"));
-			prom_print_hex(RELOC(hmt_thread_data)[i].pir);
-			prom_print_nl();
-#endif
-			_xPaca[threadid].xHwProcNum = _xPaca[i].xHwProcNum+1;
+			_xPaca[i+1].active = 1;
+			RELOC(hmt_thread_data)[i].threadid = i+1;
 		}
-		_naca->processorCount *= 2;
 	} else {
 		prom_print(RELOC("Processor is not HMT capable\n"));
 	}
@@ -1373,7 +1348,9 @@
 		cpu_pkg, RELOC("reg"),
 		&getprop_rval, sizeof(getprop_rval));
 	_prom->cpu = (int)(unsigned long)getprop_rval;
-	_xPaca[0].xHwProcNum = _prom->cpu;
+	_xPaca[_prom->cpu].active = 1;
+	RELOC(cpu_online_map) = 1 << _prom->cpu;
+	RELOC(boot_cpuid) = _prom->cpu;
 
 #ifdef DEBUG_PROM
   	prom_print(RELOC("Booting CPU hw index = 0x"));
@@ -1409,7 +1386,7 @@
          * following, regardless of whether we have an SMP
          * kernel or not.
          */
-        if ( _naca->processorCount > 1 )
+        if (RELOC(ppc64_is_smp))
 	        prom_hold_cpus(mem);
 
 	mem = check_display(mem);
@@ -2110,7 +2087,7 @@
 /*
  * Returns all nodes linked together
  */
-struct device_node * __openfirmware
+struct device_node *
 find_all_nodes(void)
 {
 	struct device_node *head, **prevp, *np;
@@ -2235,7 +2212,7 @@
 /*
  * Add a property to a node
  */
-void __openfirmware
+void
 prom_add_property(struct device_node* np, struct property* prop)
 {
 	struct property **next = &np->properties;
@@ -2247,7 +2224,7 @@
 }
 
 #if 0
-void __openfirmware
+void
 print_properties(struct device_node *np)
 {
 	struct property *pp;
diff -Nru a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
--- a/arch/ppc64/kernel/ptrace.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc64/kernel/ptrace.c	Wed Jul 24 14:03:37 2002
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/ppc/kernel/ptrace.c
+ *  linux/arch/ppc64/kernel/ptrace.c
  *
  *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -30,11 +30,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-
-/*
- * Set of msr bits that gdb can change on behalf of a process.
- */
-#define MSR_DEBUGCHANGE	(MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
+#include <asm/ptrace-common.h>
 
 /*
  * does not yet catch signals sent when the child dies.
@@ -42,48 +38,6 @@
  */
 
 /*
- * Get contents of register REGNO in task TASK.
- */
-static inline unsigned long get_reg(struct task_struct *task, int regno)
-{
-	if (regno < sizeof(struct pt_regs) / sizeof(unsigned long))
-		return ((unsigned long *)task->thread.regs)[regno];
-	return (0);
-}
-
-/*
- * Write contents of register REGNO in task TASK.
- */
-static inline int put_reg(struct task_struct *task, int regno,
-			  unsigned long data)
-{
-	if (regno < PT_SOFTE) {
-		if (regno == PT_MSR)
-			data = (data & MSR_DEBUGCHANGE)
-				| (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
-		((unsigned long *)task->thread.regs)[regno] = data;
-		return 0;
-	}
-	return -EIO;
-}
-
-static inline void
-set_single_step(struct task_struct *task)
-{
-	struct pt_regs *regs = task->thread.regs;
-	if (regs != NULL)
-		regs->msr |= MSR_SE;
-}
-
-static inline void
-clear_single_step(struct task_struct *task)
-{
-	struct pt_regs *regs = task->thread.regs;
-	if (regs != NULL)
-		regs->msr &= ~MSR_SE;
-}
-
-/*
  * Called by kernel/ptrace.c when detaching..
  *
  * Make sure single step bits etc are not set.
@@ -148,16 +102,17 @@
 
 	/* read the word at location addr in the USER area. */
 	case PTRACE_PEEKUSR: {
-		unsigned long index, tmp;
+		unsigned long index;
+		unsigned long tmp;
 
 		ret = -EIO;
 		/* convert to index and check */
 		index = (unsigned long) addr >> 3;
-		if ((addr & 7) || index > PT_FPSCR)
+		if ((addr & 7) || (index > PT_FPSCR))
 			break;
 
 		if (index < PT_FPR0) {
-			tmp = get_reg(child, (int) index);
+			tmp = get_reg(child, (int)index);
 		} else {
 			if (child->thread.regs->msr & MSR_FP)
 				giveup_fpu(child);
@@ -171,7 +126,8 @@
 	case PTRACE_POKETEXT: /* write the word at location addr. */
 	case PTRACE_POKEDATA:
 		ret = 0;
-		if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+		if (access_process_vm(child, addr, &data, sizeof(data), 1)
+				== sizeof(data))
 			break;
 		ret = -EIO;
 		break;
@@ -183,7 +139,7 @@
 		ret = -EIO;
 		/* convert to index and check */
 		index = (unsigned long) addr >> 3;
-		if ((addr & 7) || index > PT_FPSCR)
+		if ((addr & 7) || (index > PT_FPSCR))
 			break;
 
 		if (index == PT_ORIG_R3)
@@ -216,11 +172,11 @@
 		break;
 	}
 
-/*
- * make the child exit.  Best I can do is send it a sigkill. 
- * perhaps it should be put in the status that it wants to 
- * exit.
- */
+	/*
+	 * make the child exit.  Best I can do is send it a sigkill.
+	 * perhaps it should be put in the status that it wants to
+	 * exit.
+	 */
 	case PTRACE_KILL: {
 		ret = 0;
 		if (child->state == TASK_ZOMBIE)	/* already dead */
@@ -249,56 +205,50 @@
 		ret = ptrace_detach(child, data);
 		break;
 
-	case PPC_PTRACE_GETREGS:
-	{ /* Get GPRs 0 - 31. */
+	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
 		u64 tmp;
 		u64 cntr;
+
 		ret = 0; 
-		for (cntr=0; cntr<32 && ret==0; ++cntr)
-		{
+		for (cntr=0; cntr<32 && ret==0; ++cntr) {
 			tmp = ((u64*)child->thread.regs)[cntr];
 			ret = put_user(tmp, (u64*)(data+cntr));
 		}
 		break;
 	}
 
-	case PPC_PTRACE_SETREGS:
-	{ /* Set GPRs 0 - 31. */
+	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
 		u64 cntr;
+
 		ret = 0; 
 		for (cntr=0; cntr<32 && ret==0; ++cntr)
-		{
 			ret = put_reg(child, cntr, *(u64*)(data+cntr));
-		}
 		break;
 	}
 
-	case PPC_PTRACE_GETFPREGS:
-	{ /* Get FPRs 0 - 31. */
+	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
 		u64 tmp;
 		u64 cntr;
+
 		ret = -EIO;
 		if (child->thread.regs->msr & MSR_FP)
 			giveup_fpu(child);
 		ret = 0; 
-		for (cntr=0; cntr<32 && ret==0; ++cntr)
-		{
+		for (cntr=0; cntr<32 && ret==0; ++cntr) {
 			tmp = ((u64*)child->thread.fpr)[cntr];
 			ret = put_user(tmp, (u64*)(data+cntr));
 		}
 		break;
 	}
 
-	case PPC_PTRACE_SETFPREGS:
-	{ /* Get FPRs 0 - 31. */
+	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
 		u64 cntr;
+
 		ret = -EIO;
 		if (child->thread.regs->msr & MSR_FP)
 			giveup_fpu(child);
 		for (cntr=0; cntr<32; ++cntr)
-		{
 			((u64*)child->thread.fpr)[cntr] = *(u64*)(data+cntr);
-		}
 		ret = 0; 
 		break;
 	}
@@ -334,4 +284,3 @@
 		current->exit_code = 0;
 	}
 }
-
diff -Nru a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c
--- a/arch/ppc64/kernel/ptrace32.c	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc64/kernel/ptrace32.c	Wed Jul 24 14:03:35 2002
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/ppc/kernel/ptrace32.c
+ *  linux/arch/ppc64/kernel/ptrace32.c
  *
  *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -30,64 +30,18 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-
-/*
- * Set of msr bits that gdb can change on behalf of a process.
- */
-#define MSR_DEBUGCHANGE	(MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
+#include <asm/ptrace-common.h>
 
 /*
  * does not yet catch signals sent when the child dies.
  * in exit.c or in signal.c.
  */
 
-/*
- * Get contents of register REGNO in task TASK.
- */
-static inline unsigned long get_reg(struct task_struct *task, int regno)
-{
-	if (regno < sizeof(struct pt_regs) / sizeof(unsigned long))
-		return ((unsigned long *)task->thread.regs)[regno];
-	return (0);
-}
-
-/*
- * Write contents of register REGNO in task TASK.
- * (Put DATA into task TASK's register REGNO.)
- */
-static inline int put_reg(struct task_struct *task, int regno, unsigned long data)
-{
-	if (regno < PT_SOFTE) 
-  {
-		if (regno == PT_MSR)
-			data = (data & MSR_DEBUGCHANGE) | (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
-		((unsigned long *)task->thread.regs)[regno] = data;
-		return 0;
-	}
-	return -EIO;
-}
-
-static inline void
-set_single_step(struct task_struct *task)
-{
-	struct pt_regs *regs = task->thread.regs;
-	if (regs != NULL)
-		regs->msr |= MSR_SE;
-}
-
-static inline void
-clear_single_step(struct task_struct *task)
-{
-	struct pt_regs *regs = task->thread.regs;
-	if (regs != NULL)
-		regs->msr &= ~MSR_SE;
-}
-
 int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
 {
 	struct task_struct *child;
-	int ret  = -EPERM;
-  
+	int ret = -EPERM;
+
 	lock_kernel();
 	if (request == PTRACE_TRACEME) {
 		/* are we already being traced? */
@@ -120,92 +74,95 @@
 	if (ret < 0)
 		goto out_tsk;
 
-	switch (request)
-	{
-	/* Read word at location ADDR */
+	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
-	case PTRACE_PEEKDATA: 
-	{
-		unsigned int  tmp_mem_value;
+	case PTRACE_PEEKDATA: {
+		unsigned int tmp;
 		int copied;
 
-		copied = access_process_vm(child, addr, &tmp_mem_value, sizeof(tmp_mem_value), 0);
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
 		ret = -EIO;
-		if (copied != sizeof(tmp_mem_value))
+		if (copied != sizeof(tmp))
 			break;
-		ret = put_user(tmp_mem_value, (u32*)data);  // copy 4 bytes of data into the user location specified by the 8 byte pointer in "data".
+		ret = put_user(tmp, (u32*)data);
 		break;
 	}
 
-	/* Read 4 bytes of the other process' storage */
-	/*  data is a pointer specifying where the user wants the 4 bytes copied into */
-	/*  addr is a pointer in the user's storage that contains an 8 byte address in the other process of the 4 bytes that is to be read */
-	/* (this is run in a 32-bit process looking at a 64-bit process) */
-	/* when I and D space are separate, these will need to be fixed. */
+	/*
+	 * Read 4 bytes of the other process' storage
+	 *  data is a pointer specifying where the user wants the
+	 *	4 bytes copied into
+	 *  addr is a pointer in the user's storage that contains an 8 byte
+	 *	address in the other process of the 4 bytes that is to be read
+	 * (this is run in a 32-bit process looking at a 64-bit process)
+	 * when I and D space are separate, these will need to be fixed.
+	 */
 	case PPC_PTRACE_PEEKTEXT_3264:
-	case PPC_PTRACE_PEEKDATA_3264: 
-	{
-		u32  tmp_mem_value;
-		int  copied;
+	case PPC_PTRACE_PEEKDATA_3264: {
+		u32 tmp;
+		int copied;
 		u32* addrOthers;
 
 		ret = -EIO;
 
 		/* Get the addr in the other process that we want to read */
-		if (get_user(addrOthers,(u32**)addr) != 0)
+		if (get_user(addrOthers, (u32**)addr) != 0)
 			break;
 
-		copied = access_process_vm(child, (u64)addrOthers, &tmp_mem_value, sizeof(tmp_mem_value), 0);
-		if (copied != sizeof(tmp_mem_value))
+		copied = access_process_vm(child, (u64)addrOthers, &tmp,
+				sizeof(tmp), 0);
+		if (copied != sizeof(tmp))
 			break;
-		ret = put_user(tmp_mem_value, (u32*)data);  // copy 4 bytes of data into the user location specified by the 8 byte pointer in "data".
+		ret = put_user(tmp, (u32*)data);
 		break;
 	}
 
 	/* Read a register (specified by ADDR) out of the "user area" */
 	case PTRACE_PEEKUSR: {
 		int index;
-		unsigned int reg32bits;
-		unsigned long tmp_reg_value;
+		unsigned long tmp;
 
 		ret = -EIO;
 		/* convert to index and check */
 		index = (unsigned long) addr >> 2;
-		if ((addr & 3) || index > PT_FPSCR32)
+		if ((addr & 3) || (index > PT_FPSCR32))
 			break;
 
 		if (index < PT_FPR0) {
-			tmp_reg_value = get_reg(child,  index);
+			tmp = get_reg(child, index);
 		} else {
 			if (child->thread.regs->msr & MSR_FP)
 				giveup_fpu(child);
-			/* the user space code considers the floating point to be 
-			 *   an array of unsigned int (32 bits) - the index passed 
-			 *   in is based on this assumption.
+			/*
+			 * the user space code considers the floating point
+			 * to be an array of unsigned int (32 bits) - the
+			 * index passed in is based on this assumption.
 			 */
-			tmp_reg_value = ((unsigned int *)child->thread.fpr)[index - PT_FPR0];
+			tmp = ((unsigned int *)child->thread.fpr)[index - PT_FPR0];
 		}
-		reg32bits = tmp_reg_value;
-		ret = put_user(reg32bits, (u32*)data);  // copy 4 bytes of data into the user location specified by the 8 byte pointer in "data".
+		ret = put_user((unsigned int)tmp, (u32*)data);
 		break;
 	}
   
-	/* Read 4 bytes out of the other process' pt_regs area */
-	/*  data is a pointer specifying where the user wants the 4 bytes copied into */
-	/*  addr is the offset into the other process' pt_regs structure that is to be read */
-	/* (this is run in a 32-bit process looking at a 64-bit process) */
-	case PPC_PTRACE_PEEKUSR_3264:
-	{
+	/*
+	 * Read 4 bytes out of the other process' pt_regs area
+	 *  data is a pointer specifying where the user wants the
+	 *	4 bytes copied into
+	 *  addr is the offset into the other process' pt_regs structure
+	 *	that is to be read
+	 * (this is run in a 32-bit process looking at a 64-bit process)
+	 */
+	case PPC_PTRACE_PEEKUSR_3264: {
 		u32 index;
 		u32 reg32bits;
-		u64 tmp_reg_value;
+		u64 tmp;
 		u32 numReg;
 		u32 part;
 
 		ret = -EIO;
 		/* Determine which register the user wants */
-		index = (u64)addr >> 2;  /* Divide addr by 4 */
+		index = (u64)addr >> 2;
 		numReg = index / 2;
 		/* Determine which part of the register the user wants */
 		if (index % 2)
@@ -217,117 +174,120 @@
 		if ((addr & 3) || numReg > PT_FPSCR)
 			break;
 
-		if (numReg >= PT_FPR0)
-		{
+		if (numReg >= PT_FPR0) {
 			if (child->thread.regs->msr & MSR_FP)
 				giveup_fpu(child);
-		}
-		tmp_reg_value = get_reg(child, numReg);
-		reg32bits = ((u32*)&tmp_reg_value)[part];
-		ret = put_user(reg32bits, (u32*)data);  /* copy 4 bytes of data into the user location specified by the 8 byte pointer in "data". */
+		        if (numReg == PT_FPSCR) 
+			        tmp = ((unsigned int *)child->thread.fpscr);
+		        else 
+			        tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
+		} else { /* register within PT_REGS struct */
+			tmp = get_reg(child, numReg);
+		} 
+		reg32bits = ((u32*)&tmp)[part];
+		ret = put_user(reg32bits, (u32*)data);
 		break;
 	}
 
-	/* Write the word at location ADDR */
 	/* If I and D space are separate, this will have to be fixed. */
 	case PTRACE_POKETEXT: /* write the word at location addr. */
 	case PTRACE_POKEDATA: {
-		unsigned int tmp_value_to_write;
-		tmp_value_to_write =  data;
+		unsigned int tmp;
+		tmp = data;
 		ret = 0;
-		if (access_process_vm(child, addr, &tmp_value_to_write, sizeof(tmp_value_to_write), 1) == sizeof(tmp_value_to_write))
+		if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1)
+				== sizeof(tmp))
 			break;
 		ret = -EIO;
 		break;
 	}
 
-	/* Write 4 bytes into the other process' storage */
-	/*  data is the 4 bytes that the user wants written */
-	/*  addr is a pointer in the user's storage that contains an 8 byte address in the other process where the 4 bytes that is to be written */
-	/* (this is run in a 32-bit process looking at a 64-bit process) */
-	/* when I and D space are separate, these will need to be fixed. */
+	/*
+	 * Write 4 bytes into the other process' storage
+	 *  data is the 4 bytes that the user wants written
+	 *  addr is a pointer in the user's storage that contains an
+	 *	8 byte address in the other process where the 4 bytes
+	 *	that is to be written
+	 * (this is run in a 32-bit process looking at a 64-bit process)
+	 * when I and D space are separate, these will need to be fixed.
+	 */
 	case PPC_PTRACE_POKETEXT_3264:
-	case PPC_PTRACE_POKEDATA_3264:
-	{
-		u32  tmp_value_to_write = data;
+	case PPC_PTRACE_POKEDATA_3264: {
+		u32 tmp = data;
 		u32* addrOthers;
-		int  bytesWritten;
 
 		/* Get the addr in the other process that we want to write into */
 		ret = -EIO;
-		if (get_user(addrOthers,(u32**)addr) != 0)
+		if (get_user(addrOthers, (u32**)addr) != 0)
 			break;
-
 		ret = 0;
-		bytesWritten = access_process_vm(child, (u64)addrOthers, &tmp_value_to_write, sizeof(tmp_value_to_write), 1);
-		if (bytesWritten == sizeof(tmp_value_to_write))
+		if (access_process_vm(child, (u64)addrOthers, &tmp,
+					sizeof(tmp), 1) == sizeof(tmp))
 			break;
 		ret = -EIO;
 		break;
 	}
 
-	/* Write DATA into location ADDR within the USER area  */
+	/* write the word at location addr in the USER area */
 	case PTRACE_POKEUSR: {
 		unsigned long index;
 
 		ret = -EIO;
-
 		/* convert to index and check */
 		index = (unsigned long) addr >> 2;
-		if ((addr & 3) || index > PT_FPSCR32)
+		if ((addr & 3) || (index > PT_FPSCR32))
 			break;
 
 		if (index == PT_ORIG_R3)
 			break;
-
-
 		if (index < PT_FPR0) {
 			ret = put_reg(child, index, data);
 		} else {
 			if (child->thread.regs->msr & MSR_FP)
 				giveup_fpu(child);
-      /* the user space code considers the floating point to be 
-       *   an array of unsigned int (32 bits) - the index passed 
-       *   in is based on this assumption.
-       */
-
+			/*
+			 * the user space code considers the floating point
+			 * to be an array of unsigned int (32 bits) - the
+			 * index passed in is based on this assumption.
+			 */
 			((unsigned int *)child->thread.fpr)[index - PT_FPR0] = data;
 			ret = 0;
 		}
 		break;
 	}
 
-	/* Write 4 bytes into the other process' pt_regs area */
-	/*  data is the 4 bytes that the user wants written */
-	/*  addr is the offset into the other process' pt_regs structure that is to be written into */
-	/* (this is run in a 32-bit process looking at a 64-bit process) */
-	case PPC_PTRACE_POKEUSR_3264:
-	{
+	/*
+	 * Write 4 bytes into the other process' pt_regs area
+	 *  data is the 4 bytes that the user wants written
+	 *  addr is the offset into the other process' pt_regs structure
+	 *	that is to be written into
+	 * (this is run in a 32-bit process looking at a 64-bit process)
+	 */
+	case PPC_PTRACE_POKEUSR_3264: {
 		u32 index;
 		u32 numReg;
 
 		ret = -EIO;
-
 		/* Determine which register the user wants */
-		index = (u64)addr >> 2;  /* Divide addr by 4 */
+		index = (u64)addr >> 2;
 		numReg = index / 2;
-
-		/* Validate the input - check to see if address is on the wrong boundary or beyond the end of the user area */
-		if ((addr & 3) || numReg > PT_FPSCR)
+		/*
+		 * Validate the input - check to see if address is on the
+		 * wrong boundary or beyond the end of the user area
+		 */
+		if ((addr & 3) || (numReg > PT_FPSCR))
 			break;
 		/* Insure it is a register we let them change */
-		if ((numReg == PT_ORIG_R3) || ((numReg > PT_CCR) && (numReg < PT_FPR0)))
+		if ((numReg == PT_ORIG_R3)
+				|| ((numReg > PT_CCR) && (numReg < PT_FPR0)))
 			break;
-
-		if (numReg >= PT_FPR0)
-		{
+		if (numReg >= PT_FPR0) {
 			if (child->thread.regs->msr & MSR_FP)
 				giveup_fpu(child);
 		}
-
 		if (numReg == PT_MSR)
-			data = (data & MSR_DEBUGCHANGE) | (child->thread.regs->msr & ~MSR_DEBUGCHANGE);
-
+			data = (data & MSR_DEBUGCHANGE)
+				| (child->thread.regs->msr & ~MSR_DEBUGCHANGE);
 		((u32*)child->thread.regs)[index] = data;
 		ret = 0;
 		break;
@@ -351,8 +311,8 @@
 	}
 
 	/*
-	 * make the child exit.  Best I can do is send it a sigkill. 
-	 * perhaps it should be put in the status that it wants to 
+	 * make the child exit.  Best I can do is send it a sigkill.
+	 * perhaps it should be put in the status that it wants to
 	 * exit.
 	 */
 	case PTRACE_KILL: {
diff -Nru a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
--- a/arch/ppc64/kernel/rtas-proc.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/rtas-proc.c	Wed Jul 24 14:03:38 2002
@@ -162,26 +162,26 @@
 		size_t count, loff_t *ppos);
 
 struct file_operations ppc_rtas_poweron_operations = {
-	read:		ppc_rtas_poweron_read,
-	write:		ppc_rtas_poweron_write
+	.read =		ppc_rtas_poweron_read,
+	.write =	ppc_rtas_poweron_write
 };
 struct file_operations ppc_rtas_progress_operations = {
-	read:		ppc_rtas_progress_read,
-	write:		ppc_rtas_progress_write
+	.read =		ppc_rtas_progress_read,
+	.write =	ppc_rtas_progress_write
 };
 
 struct file_operations ppc_rtas_clock_operations = {
-	read:		ppc_rtas_clock_read,
-	write:		ppc_rtas_clock_write
+	.read =		ppc_rtas_clock_read,
+	.write =	ppc_rtas_clock_write
 };
 
 struct file_operations ppc_rtas_tone_freq_operations = {
-	read:		ppc_rtas_tone_freq_read,
-	write:		ppc_rtas_tone_freq_write
+	.read =		ppc_rtas_tone_freq_read,
+	.write =	ppc_rtas_tone_freq_write
 };
 struct file_operations ppc_rtas_tone_volume_operations = {
-	read:		ppc_rtas_tone_volume_read,
-	write:		ppc_rtas_tone_volume_write
+	.read =		ppc_rtas_tone_volume_read,
+	.write =	ppc_rtas_tone_volume_write
 };
 
 int ppc_rtas_find_all_sensors (void);
diff -Nru a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c
--- a/arch/ppc64/kernel/rtas.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/kernel/rtas.c	Wed Jul 24 14:03:36 2002
@@ -16,15 +16,19 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 
-#include <asm/init.h>
 #include <asm/prom.h>
 #include <asm/rtas.h>
+#include <asm/semaphore.h>
 #include <asm/machdep.h>
 #include <asm/paca.h>
 #include <asm/page.h>
 #include <asm/system.h>
+#include <asm/abs_addr.h>
 #include <asm/udbg.h>
 
+struct proc_dir_entry *rtas_proc_dir;	/* /proc/ppc64/rtas dir */
+struct flash_block_list_header rtas_firmware_flash_list = {0, 0};
+
 /*
  * prom_init() is called very early on, before the kernel text
  * and data have been mapped to KERNELBASE.  At this point the code
@@ -47,7 +51,7 @@
  */
 
 struct rtas_t rtas = { 
-	lock: SPIN_LOCK_UNLOCKED
+	.lock = SPIN_LOCK_UNLOCKED
 };
 
 extern unsigned long reloc_offset(void);
@@ -105,7 +109,6 @@
 #if 0
 #define DEBUG_RTAS
 #endif
-__openfirmware
 int
 rtas_token(const char *service)
 {
@@ -120,7 +123,6 @@
 	return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
 }
 
-__openfirmware
 long
 rtas_call(int token, int nargs, int nret,
 	  unsigned long *outputs, ...)
@@ -184,25 +186,107 @@
 	return (ulong)((nret > 0) ? rtas_args->rets[0] : 0);
 }
 
-void __chrp
+#define FLASH_BLOCK_LIST_VERSION (1UL)
+static void
+rtas_flash_firmware(void)
+{
+	unsigned long image_size;
+	struct flash_block_list *f, *next, *flist;
+	unsigned long rtas_block_list;
+	int i, status, update_token;
+
+	update_token = rtas_token("ibm,update-flash-64-and-reboot");
+	if (update_token == RTAS_UNKNOWN_SERVICE) {
+		printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n");
+		printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
+		return;
+	}
+
+	/* NOTE: the "first" block list is a global var with no data
+	 * blocks in the kernel data segment.  We do this because
+	 * we want to ensure this block_list addr is under 4GB.
+	 */
+	rtas_firmware_flash_list.num_blocks = 0;
+	flist = (struct flash_block_list *)&rtas_firmware_flash_list;
+	rtas_block_list = virt_to_absolute((unsigned long)flist);
+	if (rtas_block_list >= (4UL << 20)) {
+		printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
+		return;
+	}
+
+	printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
+	/* Update the block_list in place. */
+	image_size = 0;
+	for (f = flist; f; f = next) {
+		/* Translate data addrs to absolute */
+		for (i = 0; i < f->num_blocks; i++) {
+			f->blocks[i].data = (char *)virt_to_absolute((unsigned long)f->blocks[i].data);
+			image_size += f->blocks[i].length;
+		}
+		next = f->next;
+		f->next = (struct flash_block_list *)virt_to_absolute((unsigned long)f->next);
+		/* make num_blocks into the version/length field */
+		f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
+	}
+
+	printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
+	printk(KERN_ALERT "FLASH: performing flash and reboot\n");
+	ppc_md.progress("Flashing        \n", 0x0);
+	ppc_md.progress("Please Wait...  ", 0x0);
+	printk(KERN_ALERT "FLASH: this will take several minutes.  Do not power off!\n");
+	status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
+	switch (status) {	/* should only get "bad" status */
+	    case 0:
+		printk(KERN_ALERT "FLASH: success\n");
+		break;
+	    case -1:
+		printk(KERN_ALERT "FLASH: hardware error.  Firmware may not be not flashed\n");
+		break;
+	    case -3:
+		printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform.  Firmware not flashed\n");
+		break;
+	    case -4:
+		printk(KERN_ALERT "FLASH: flash failed when partially complete.  System may not reboot\n");
+		break;
+	    default:
+		printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
+		break;
+	}
+}
+
+void rtas_flash_bypass_warning(void)
+{
+	printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
+	printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
+}
+
+
+void
 rtas_restart(char *cmd)
 {
+	if (rtas_firmware_flash_list.next)
+		rtas_flash_firmware();
+
         printk("RTAS system-reboot returned %ld\n",
 	       rtas_call(rtas_token("system-reboot"), 0, 1, NULL));
         for (;;);
 }
 
-void __chrp
+void
 rtas_power_off(void)
 {
+	if (rtas_firmware_flash_list.next)
+		rtas_flash_bypass_warning();
         /* allow power on only with power button press */
         printk("RTAS power-off returned %ld\n",
                rtas_call(rtas_token("power-off"), 2, 1, NULL,0xffffffff,0xffffffff));
         for (;;);
 }
 
-void __chrp
+void
 rtas_halt(void)
 {
+	if (rtas_firmware_flash_list.next)
+		rtas_flash_bypass_warning();
         rtas_power_off();
 }
diff -Nru a/arch/ppc64/kernel/rtas_flash.c b/arch/ppc64/kernel/rtas_flash.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc64/kernel/rtas_flash.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,240 @@
+/*
+ *  c 2001 PPC 64 Team, IBM Corp
+ *
+ *      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.
+ *
+ * /proc/ppc64/rtas/firmware_flash interface
+ *
+ * This file implements a firmware_flash interface to pump a firmware
+ * image into the kernel.  At reboot time rtas_restart() will see the
+ * firmware image and flash it as it reboots (see rtas.c).
+ */
+
+#include <linux/module.h>
+
+#include <linux/config.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/rtas.h>
+
+#define MODULE_VERSION "1.0"
+#define MODULE_NAME "rtas_flash"
+
+#define FIRMWARE_FLASH_NAME "firmware_flash"
+
+/* Local copy of the flash block list.
+ * We only allow one open of the flash proc file and create this
+ * list as we go.  This list will be put in the kernel's
+ * rtas_firmware_flash_list global var once it is fully read.
+ *
+ * For convenience as we build the list we use virtual addrs,
+ * we do not fill in the version number, and the length field
+ * is treated as the number of entries currently in the block
+ * (i.e. not a byte count).  This is all fixed on release.
+ */
+static struct flash_block_list *flist;
+static char *flash_msg;
+static int flash_possible;
+
+static int rtas_flash_open(struct inode *inode, struct file *file)
+{
+	if ((file->f_mode & FMODE_WRITE) && flash_possible) {
+		if (flist)
+			return -EBUSY;
+		flist = (struct flash_block_list *)get_free_page(GFP_KERNEL);
+		if (!flist)
+			return -ENOMEM;
+	}
+	return 0;
+}
+
+/* Do simple sanity checks on the flash image. */
+static int flash_list_valid(struct flash_block_list *flist)
+{
+	struct flash_block_list *f;
+	int i;
+	unsigned long block_size, image_size;
+
+	flash_msg = NULL;
+	/* Paranoid self test here.  We also collect the image size. */
+	image_size = 0;
+	for (f = flist; f; f = f->next) {
+		for (i = 0; i < f->num_blocks; i++) {
+			if (f->blocks[i].data == NULL) {
+				flash_msg = "error: internal error null data\n";
+				return 0;
+			}
+			block_size = f->blocks[i].length;
+			if (block_size <= 0 || block_size > PAGE_SIZE) {
+				flash_msg = "error: internal error bad length\n";
+				return 0;
+			}
+			image_size += block_size;
+		}
+	}
+	if (image_size < (256 << 10)) {
+		if (image_size < 2)
+			flash_msg = NULL;	/* allow "clear" of image */
+		else
+			flash_msg = "error: flash image short\n";
+		return 0;
+	}
+	printk(KERN_INFO "FLASH: flash image with %ld bytes stored for hardware flash on reboot\n", image_size);
+	return 1;
+}
+
+static void free_flash_list(struct flash_block_list *f)
+{
+	struct flash_block_list *next;
+	int i;
+
+	while (f) {
+		for (i = 0; i < f->num_blocks; i++)
+			free_page((unsigned long)(f->blocks[i].data));
+		next = f->next;
+		free_page((unsigned long)f);
+		f = next;
+	}
+}
+
+static int rtas_flash_release(struct inode *inode, struct file *file)
+{
+	if (flist) {
+		/* Always clear saved list on a new attempt. */
+		if (rtas_firmware_flash_list.next) {
+			free_flash_list(rtas_firmware_flash_list.next);
+			rtas_firmware_flash_list.next = NULL;
+		}
+
+		if (flash_list_valid(flist))
+			rtas_firmware_flash_list.next = flist;
+		else
+			free_flash_list(flist);
+		flist = NULL;
+	}
+	return 0;
+}
+
+/* Reading the proc file will show status (not the firmware contents) */
+static ssize_t rtas_flash_read(struct file *file, char *buf,
+			       size_t count, loff_t *ppos)
+{
+	int error;
+	char *msg;
+	int msglen;
+
+	if (!flash_possible) {
+		msg = "error: this partition does not have service authority\n";
+	} else if (flist) {
+		msg = "info: this file is busy for write by some process\n";
+	} else if (flash_msg) {
+		msg = flash_msg;	/* message from last flash attempt */
+	} else if (rtas_firmware_flash_list.next) {
+		msg = "ready: firmware image ready for flash on reboot\n";
+	} else {
+		msg = "info: no firmware image for flash\n";
+	}
+	msglen = strlen(msg);
+	if (msglen > count)
+		msglen = count;
+
+	if (ppos && *ppos != 0)
+		return 0;	/* be cheap */
+
+	error = verify_area(VERIFY_WRITE, buf, msglen);
+	if (error)
+		return -EINVAL;
+
+	copy_to_user(buf, msg, msglen);
+
+	if (ppos)
+		*ppos = msglen;
+	return msglen;
+}
+
+/* We could be much more efficient here.  But to keep this function
+ * simple we allocate a page to the block list no matter how small the
+ * count is.  If the system is low on memory it will be just as well
+ * that we fail....
+ */
+static ssize_t rtas_flash_write(struct file *file, const char *buffer,
+				size_t count, loff_t *off)
+{
+	size_t len = count;
+	char *p;
+	int next_free;
+	struct flash_block_list *fl = flist;
+
+	if (!flash_possible || len == 0)
+		return len;	/* discard data */
+
+	while (fl->next)
+		fl = fl->next; /* seek to last block_list for append */
+	next_free = fl->num_blocks;
+	if (next_free == FLASH_BLOCKS_PER_NODE) {
+		/* Need to allocate another block_list */
+		fl->next = (struct flash_block_list *)get_free_page(GFP_KERNEL);
+		if (!fl->next)
+			return -ENOMEM;
+		fl = fl->next;
+		next_free = 0;
+	}
+
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+	p = (char *)get_free_page(GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+	if(copy_from_user(p, buffer, len)) {
+		free_page((unsigned long)p);
+		return -EFAULT;
+	}
+	fl->blocks[next_free].data = p;
+	fl->blocks[next_free].length = len;
+	fl->num_blocks++;
+
+	return len;
+}
+
+static struct file_operations rtas_flash_operations = {
+	read:		rtas_flash_read,
+	write:		rtas_flash_write,
+	open:		rtas_flash_open,
+	release:	rtas_flash_release,
+};
+
+
+int __init rtas_flash_init(void)
+{
+	struct proc_dir_entry *ent = NULL;
+
+	if (!rtas_proc_dir) {
+		printk(KERN_WARNING "rtas proc dir does not already exist");
+		return -ENOENT;
+	}
+
+	if (rtas_token("ibm,update-flash-64-and-reboot") != RTAS_UNKNOWN_SERVICE)
+		flash_possible = 1;
+
+	if ((ent = create_proc_entry(FIRMWARE_FLASH_NAME, S_IRUSR | S_IWUSR, rtas_proc_dir)) != NULL) {
+		ent->nlink = 1;
+		ent->proc_fops = &rtas_flash_operations;
+		ent->owner = THIS_MODULE;
+	}
+	return 0;
+}
+
+void __exit rtas_flash_cleanup(void)
+{
+	if (!rtas_proc_dir)
+		return;
+	remove_proc_entry(FIRMWARE_FLASH_NAME, rtas_proc_dir);
+}
+
+module_init(rtas_flash_init);
+module_exit(rtas_flash_cleanup);
+MODULE_LICENSE("GPL");
diff -Nru a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c
--- a/arch/ppc64/kernel/rtasd.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc64/kernel/rtasd.c	Wed Jul 24 14:03:37 2002
@@ -114,10 +114,10 @@
 }
 
 struct file_operations proc_rtas_log_operations = {
-	read:		rtas_log_read,
-	poll:		rtas_log_poll,
-	open:		rtas_log_open,
-	release:	rtas_log_release,
+	.read =		rtas_log_read,
+	.poll =		rtas_log_poll,
+	.open =		rtas_log_open,
+	.release =	rtas_log_release,
 };
 
 static void log_rtas(char *buf)
@@ -220,10 +220,15 @@
 	current->nice = sys_sched_get_priority_max(SCHED_FIFO) + 1;
 #endif
 
-	cpu = 0;
-	set_cpus_allowed(current, 1UL << cpu_logical_map(cpu));
+repeat:
+	for (cpu = 0; cpu < NR_CPUS; cpu++) {
+		if (!cpu_online(cpu))
+			continue;
+
+		DEBUG("scheduling on %d\n", cpu);
+		set_cpus_allowed(current, 1UL << cpu);
+		DEBUG("watchdog scheduled on cpu %d\n", smp_processor_id());
 
-	while(1) {
 		do {
 			memset(logdata, 0, rtas_error_log_max);
 			error = rtas_call(event_scan, 4, 1, NULL,
@@ -239,31 +244,23 @@
 
 		} while(error == 0);
 
-		DEBUG("watchdog scheduled on cpu %d\n", smp_processor_id());
-
-		cpu++;
-		if (cpu >= smp_num_cpus) {
-
-			if (first_pass && surveillance_requested) {
-				DEBUG("enabling surveillance\n");
-				if (enable_surveillance())
-					goto error_vfree;
-				DEBUG("surveillance enabled\n");
-			}
-
-			first_pass = 0;
-			cpu = 0;
-		}
-
-		set_cpus_allowed(current, 1UL << cpu_logical_map(cpu));
-
-
 		/* Check all cpus for pending events before sleeping*/
 		if (!first_pass) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout((HZ*60/rtas_event_scan_rate) / 2);
 		}
 	}
+
+	if (first_pass && surveillance_requested) {
+		DEBUG("enabling surveillance\n");
+		if (enable_surveillance())
+			goto error_vfree;
+		DEBUG("surveillance enabled\n");
+	} else {
+		first_pass = 0;
+	}
+
+	goto repeat;
 
 error_vfree:
 	vfree(rtas_log_buf);
diff -Nru a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
--- a/arch/ppc64/kernel/rtc.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/rtc.c	Wed Jul 24 14:03:38 2002
@@ -178,12 +178,12 @@
  *	The various file operations we support.
  */
 static struct file_operations rtc_fops = {
-	owner:		THIS_MODULE,
-	llseek:		rtc_llseek,
-	read:		rtc_read,
-	ioctl:		rtc_ioctl,
-	open:		rtc_open,
-	release:	rtc_release,
+	.owner =	THIS_MODULE,
+	.llseek =	rtc_llseek,
+	.read =		rtc_read,
+	.ioctl =	rtc_ioctl,
+	.open =		rtc_open,
+	.release =	rtc_release,
 };
 
 static struct miscdevice rtc_dev=
diff -Nru a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
--- a/arch/ppc64/kernel/setup.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/setup.c	Wed Jul 24 14:03:38 2002
@@ -23,7 +23,6 @@
 #include <linux/ioport.h>
 #include <linux/tty.h>
 #include <linux/root_dev.h>
-#include <asm/init.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/processor.h>
@@ -43,9 +42,6 @@
 extern HTAB htab_data;
 extern unsigned long loops_per_jiffy;
 
-extern unsigned long embedded_sysmap_start;
-extern unsigned long embedded_sysmap_end;
-
 int have_of = 1;
 
 extern void  chrp_init(unsigned long r3,
@@ -54,7 +50,6 @@
 		       unsigned long r6,
 		       unsigned long r7);
 
-extern void chrp_init_map_io_space( void );
 extern void iSeries_init( void );
 extern void iSeries_init_early( void );
 extern void pSeries_init_early( void );
@@ -173,10 +168,6 @@
 	udbg_puthex((unsigned long)naca);
 	udbg_putc('\n');
 
-	udbg_puts("naca->processorCount       = 0x");
-	udbg_puthex(naca->processorCount);
-	udbg_putc('\n');
-
 	udbg_puts("naca->physicalMemorySize   = 0x");
 	udbg_puthex(naca->physicalMemorySize);
 	udbg_putc('\n');
@@ -294,6 +285,9 @@
 	pvr = paca[cpu_id].pvr;
 
 	switch (PVR_VER(pvr)) {
+	case PV_NORTHSTAR:
+		seq_printf(m, "RS64-II (northstar)\n");
+		break;
 	case PV_PULSAR:
 		seq_printf(m, "RS64-III (pulsar)\n");
 		break;
@@ -306,6 +300,9 @@
 	case PV_SSTAR:
 		seq_printf(m, "RS64-IV (sstar)\n");
 		break;
+	case PV_POWER4p:
+		seq_printf(m, "POWER4+ (gq)\n");
+		break;
 	case PV_630:
 		seq_printf(m, "POWER3 (630)\n");
 		break;
@@ -338,7 +335,7 @@
 	if (ppc_md.setup_residual != NULL)
 		ppc_md.setup_residual(m, cpu_id);
 
-	seq_printf(m, "revision\t: %hd.%hd\n", maj, min);
+	seq_printf(m, "revision\t: %hd.%hd\n\n", maj, min);
 	
 	return 0;
 }
@@ -356,10 +353,10 @@
 {
 }
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	show_cpuinfo,
+	.start =c_start,
+	.next =	c_next,
+	.stop =	c_stop,
+	.show =	show_cpuinfo,
 };
 
 /*
@@ -499,6 +496,7 @@
 }	
 
 extern void (*calibrate_delay)(void);
+extern void sort_exception_table(void);
 
 /*
  * Called into from start_kernel, after lock_kernel has been called.
diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
--- a/arch/ppc64/kernel/signal.c	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc64/kernel/signal.c	Wed Jul 24 14:03:35 2002
@@ -26,8 +26,6 @@
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/elf.h>
-#include <linux/tty.h>
-#include <linux/binfmts.h>
 #include <asm/ppc32.h>
 #include <asm/sigcontext.h>
 #include <asm/ucontext.h>
@@ -59,9 +57,36 @@
  */
 #define MSR_USERCHANGE	(MSR_FE0 | MSR_FE1)
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern long sys_wait4(pid_t pid, unsigned int *stat_addr,
-		     int options, /*unsigned long*/ struct rusage *ru);
+/*
+ * When we have signals to deliver, we set up on the
+ * user stack, going down from the original stack pointer:
+ *	a sigregs struct
+ *	one or more sigcontext structs with
+ *	a gap of __SIGNAL_FRAMESIZE bytes
+ *
+ * Each of these things must be a multiple of 16 bytes in size.
+ *
+ */
+struct sigregs {
+	elf_gregset_t	gp_regs;
+	double		fp_regs[ELF_NFPREG];
+	unsigned int	tramp[2];
+	/* 64 bit API allows for 288 bytes below sp before 
+	   decrementing it. */
+	int		abigap[72];
+};
+
+struct rt_sigframe
+{
+	unsigned long	_unused[2];
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+};
+
+
+extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
 
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
@@ -127,7 +152,7 @@
 
 long sys_sigaltstack(const stack_t *uss, stack_t *uoss)
 {
-	struct pt_regs *regs = (struct pt_regs *) &uss;
+	struct pt_regs *regs = (struct pt_regs *)&uss;
 	return do_sigaltstack(uss, uoss, regs->gpr[1]);
 }
 
@@ -139,6 +164,7 @@
 
 	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))
@@ -148,8 +174,7 @@
 		siginitset(&new_ka.sa.sa_mask, mask);
 	}
 
-	ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL));
-
+	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) ||
@@ -163,35 +188,6 @@
 }
 
 /*
- * When we have signals to deliver, we set up on the
- * user stack, going down from the original stack pointer:
- *	a sigregs struct
- *	one or more sigcontext structs with
- *	a gap of __SIGNAL_FRAMESIZE bytes
- *
- * Each of these things must be a multiple of 16 bytes in size.
- *
- */
-struct sigregs {
-	elf_gregset_t	gp_regs;
-	double		fp_regs[ELF_NFPREG];
-	unsigned int	tramp[2];
-	/* 64 bit API allows for 288 bytes below sp before 
-	   decrementing it. */
-	int		abigap[72];
-};
-
-struct rt_sigframe
-{
-	unsigned long	_unused[2];
-	struct siginfo *pinfo;
-	void *puc;
-	struct siginfo info;
-	struct ucontext uc;
-};
-
-
-/*
  *  When we have rt signals to deliver, we set up on the
  *  user stack, going down from the original stack pointer:
  *	   a sigregs struct
@@ -231,7 +227,7 @@
 	 * preamble frame (where registers are stored) 
 	 * see handle_signal()
 	 */
-	sr = (struct sigregs *) sigctx.regs;
+	sr = (struct sigregs *)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)
@@ -251,11 +247,10 @@
 	do_exit(SIGSEGV);
 }
 
-static void
-setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
+static void setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
 	       signed long newsp)
 {
-	struct rt_sigframe *rt_sf = (struct rt_sigframe *) newsp;
+	struct rt_sigframe *rt_sf = (struct rt_sigframe *)newsp;
 	/* Handler is *really* a pointer to the function descriptor for
 	 * the signal routine.  The first entry in the function
 	 * descriptor is the entry address of signal and the second
@@ -277,11 +272,13 @@
 	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_rt_sigreturn, &frame->tramp[0])	/* li r0, __NR_rt_sigreturn */
-	    || __put_user(0x44000002UL, &frame->tramp[1]))	/* sc */
+	    /* li r0, __NR_rt_sigreturn */
+	    || __put_user(0x38000000UL + __NR_rt_sigreturn, &frame->tramp[0])
+	    /* sc */
+	    || __put_user(0x44000002UL, &frame->tramp[1]))
 		goto badframe;
-	flush_icache_range((unsigned long) &frame->tramp[0],
-			   (unsigned long) &frame->tramp[2]);
+	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
@@ -289,11 +286,11 @@
 	*/
 	newsp -= __SIGNAL_FRAMESIZE;
 
-        if ( get_user(temp_ptr, &rt_sf->uc.uc_mcontext.handler)) {
+        if (get_user(temp_ptr, &rt_sf->uc.uc_mcontext.handler)) {
 		goto badframe;
 	}
 
-        funct_desc_ptr = ( struct funct_descr_entry *) temp_ptr;
+        funct_desc_ptr = (struct funct_descr_entry *)temp_ptr;
         
 	if (put_user(regs->gpr[1], (unsigned long *)newsp)
 	    || get_user(regs->nip, &funct_desc_ptr->entry)
@@ -304,8 +301,8 @@
 		goto badframe;
 
 	regs->gpr[1] = newsp;
-	regs->gpr[6] = (unsigned long) rt_sf;
-	regs->link = (unsigned long) frame->tramp;
+	regs->gpr[6] = (unsigned long)rt_sf;
+	regs->link = (unsigned long)frame->tramp;
 
 	return;
 
@@ -342,11 +339,11 @@
 	current->blocked = set;
 	recalc_sigpending();
 	spin_unlock_irq(&current->sigmask_lock);
-	if (regs->msr & MSR_FP )
+	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
 
 	/* restore registers */
-	sr = (struct sigregs *) sigctx.regs;
+	sr = (struct sigregs *)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)
@@ -367,8 +364,7 @@
 /*
  * Set up a signal frame.
  */
-static void
-setup_frame(struct pt_regs *regs, struct sigregs *frame,
+static void setup_frame(struct pt_regs *regs, struct sigregs *frame,
 	    unsigned long newsp)
 {
 
@@ -385,7 +381,7 @@
 	struct funct_descr_entry * funct_desc_ptr;
 	unsigned long temp_ptr;
 
-	struct sigcontext_struct *sc = (struct sigcontext_struct *) newsp;
+	struct sigcontext_struct *sc = (struct sigcontext_struct *)newsp;
   
 	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto badframe;
@@ -394,27 +390,29 @@
 	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])    /* li r0, __NR_sigreturn */
-	    || __put_user(0x44000002UL, &frame->tramp[1]))   /* sc */
+	    /* li r0, __NR_sigreturn */
+	    || __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0])
+	    /* sc */
+	    || __put_user(0x44000002UL, &frame->tramp[1]))
 		goto badframe;
-	flush_icache_range((unsigned long) &frame->tramp[0],
-			   (unsigned long) &frame->tramp[2]);
+	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 ( get_user(temp_ptr, &sc->handler))
+	if (get_user(temp_ptr, &sc->handler))
 		goto badframe;
   
-	funct_desc_ptr = ( struct funct_descr_entry *) temp_ptr;
+	funct_desc_ptr = (struct funct_descr_entry *)temp_ptr;
 
 	if (put_user(regs->gpr[1], (unsigned long *)newsp)
-	    || get_user(regs->nip, & funct_desc_ptr ->entry)
-	    || get_user(regs->gpr[2],& funct_desc_ptr->toc)
+	    || get_user(regs->nip, &funct_desc_ptr ->entry)
+	    || get_user(regs->gpr[2],&funct_desc_ptr->toc)
 	    || get_user(regs->gpr[3], &sc->signal))
 		goto badframe;
 	regs->gpr[1] = newsp;
-	regs->gpr[4] = (unsigned long) sc;
-	regs->link = (unsigned long) frame->tramp;
+	regs->gpr[4] = (unsigned long)sc;
+	regs->link = (unsigned long)frame->tramp;
 
 	return;
 
@@ -429,8 +427,7 @@
 /*
  * OK, we're invoking a handler
  */
-static void
-handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
+static void handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
 	struct pt_regs * regs, unsigned long *newspp, unsigned long frame)
 {
 	struct sigcontext_struct *sc;
@@ -447,11 +444,12 @@
 	if (ka->sa.sa_flags & SA_SIGINFO) {
 		/* Put a Real Time Context onto stack */
 		*newspp -= sizeof(*rt_sf);
-		rt_sf = (struct rt_sigframe *) *newspp;
+		rt_sf = (struct rt_sigframe *)*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)
+		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 */
@@ -461,9 +459,11 @@
 		    || __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))
+			    &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))
@@ -471,11 +471,11 @@
 	} else {
 		/* Put a sigcontext on the stack */
 		*newspp -= sizeof(*sc);
-		sc = (struct sigcontext_struct *) *newspp;
+		sc = (struct sigcontext_struct *)*newspp;
 		if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
 			goto badframe;
 		
-		if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
+		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])
@@ -512,6 +512,7 @@
  * mistake.
  */
 extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+
 int do_signal(sigset_t *oldset, struct pt_regs *regs)
 {
 	siginfo_t info;
@@ -526,7 +527,7 @@
 	if (test_thread_flag(TIF_32BIT))
 		return do_signal32(oldset, regs);
 
-        if (!oldset)
+	if (!oldset)
 		oldset = &current->blocked;
 
 	newsp = frame = 0;
@@ -534,8 +535,8 @@
 	signr = get_signal_to_deliver(&info, regs);
 	if (signr > 0) {
 		ka = &current->sig->action[signr-1];
-		if ( (ka->sa.sa_flags & SA_ONSTACK)
-		     && (! on_sig_stack(regs->gpr[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];
@@ -557,9 +558,10 @@
 	if (newsp == frame)
 		return 0;		/* no signals delivered */
 
+	/* Invoke correct stack setup routine */
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(regs, (struct sigregs *) frame, newsp);
+		setup_rt_frame(regs, (struct sigregs *)frame, newsp);
 	else
-		setup_frame(regs, (struct sigregs *) frame, newsp);
+		setup_frame(regs, (struct sigregs *)frame, newsp);
 	return 1;
 }
diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
--- a/arch/ppc64/kernel/signal32.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/signal32.c	Wed Jul 24 14:03:39 2002
@@ -14,43 +14,19 @@
  *      2 of the License, or (at your option) any later version.
  */
 
-#include <asm/ptrace.h>
-#include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/fs.h> 
 #include <linux/mm.h> 
-#include <linux/file.h> 
-#include <linux/signal.h>
-#include <linux/utime.h>
-#include <linux/resource.h>
-#include <linux/times.h>
-#include <linux/utsname.h>
-#include <linux/timex.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/shm.h>
-#include <linux/slab.h>
-#include <linux/uio.h>
-#include <linux/nfs_fs.h>
-#include <linux/smb_fs.h>
-#include <linux/smb_mount.h>
-#include <linux/ncp_fs.h>
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/personality.h>
-#include <linux/stat.h>
-#include <linux/filter.h>
-#include <linux/tty.h>
-#include <linux/binfmts.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
 #include <linux/elf.h>
-#include <asm/types.h>
-#include <asm/ipc.h>
-#include <asm/uaccess.h>
 #include <asm/ppc32.h>
+#include <asm/uaccess.h>
 #include <asm/ppcdebug.h>
 #include <asm/unistd.h>
+#include <asm/cacheflush.h>
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 /* 
@@ -112,9 +88,6 @@
 };
 
 
-extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
-		int options, struct rusage * ru);
-
 
 /*
  *  Start of nonRT signal support
@@ -133,7 +106,7 @@
  *        setup_frame32
  */
 
-asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act,
+long sys32_sigaction(int sig, struct old_sigaction32 *act,
 		struct old_sigaction32 *oact)
 {
 	struct k_sigaction new_ka, old_ka;
@@ -145,32 +118,30 @@
 	if (act) {
 		old_sigset_t32 mask;
 
-		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
-		ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
-		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
-		ret |= __get_user(mask, &act->sa_mask);
-		if (ret)
-			return ret;
+		if (get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer) ||
+		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+		    __get_user(mask, &act->sa_mask))
+			return -EFAULT;
 		siginitset(&new_ka.sa.sa_mask, mask);
 	}
 
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 	if (!ret && oact) {
-		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
-		ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
-		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-		ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+		if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
+			return -EFAULT;
 	}
 
 	return ret;
 }
 
 
+extern long sys_sigpending(old_sigset_t *set);
 
-
-extern asmlinkage long sys_sigpending(old_sigset_t *set);
-
-asmlinkage long sys32_sigpending(old_sigset_t32 *set)
+long sys32_sigpending(old_sigset_t32 *set)
 {
 	old_sigset_t s;
 	int ret;
@@ -185,9 +156,7 @@
 }
 
 
-
-
-extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
+extern long sys_sigprocmask(int how, old_sigset_t *set,
 		old_sigset_t *oset);
 
 /*
@@ -197,7 +166,7 @@
  * of a signed int (msr in 32-bit mode) and the register representation
  * of a signed int (msr in 64-bit mode) is performed.
  */
-asmlinkage long sys32_sigprocmask(u32 how, old_sigset_t32 *set,
+long sys32_sigprocmask(u32 how, old_sigset_t32 *set,
 		old_sigset_t32 *oset)
 {
 	old_sigset_t s;
@@ -252,23 +221,21 @@
 	 * Note that PPC32 puts the upper 32 bits of the sigmask in the
 	 * unused part of the signal stackframe
 	 */
-	set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3])<< 32);
+	set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32);
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sigmask_lock);
 	current->blocked = set;
 	recalc_sigpending();
 	spin_unlock_irq(&current->sigmask_lock);
-
-	/* Last stacked signal - restore registers */
-	sr = (struct sigregs32*)(u64)sigctx.regs;
 	if (regs->msr & MSR_FP )
 		giveup_fpu(current);
+	/* Last stacked signal - restore registers */
+	sr = (struct sigregs32*)(u64)sigctx.regs;
 	/*
 	 * copy the 32 bit register values off the user stack
 	 * into the 32 bit register area
 	 */
-	if (copy_from_user(saved_regs, &sr->gp_regs,
-				sizeof(sr->gp_regs)))
+	if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
 		goto badframe;
 	/*
 	 * The saved reg structure in the frame is an elf_grepset_t32,
@@ -323,7 +290,6 @@
 		goto badframe;
 
 	ret = regs->result;
-
 	return ret;
 
 badframe:
@@ -387,12 +353,13 @@
 	 */
 	if (__copy_to_user(&frame->fp_regs, current->thread.fpr,
 			   ELF_NFPREG * sizeof(double))
-	    || __put_user(0x38000000U + __NR_sigreturn, &frame->tramp[0])    /* li r0, __NR_sigreturn */
-	    || __put_user(0x44000002U, &frame->tramp[1]))   /* sc */
+	    /* li r0, __NR_sigreturn */
+	    || __put_user(0x38000000U + __NR_sigreturn, &frame->tramp[0])
+	    /* sc */
+	    || __put_user(0x44000002U, &frame->tramp[1]))
 		goto badframe;
-
-	flush_icache_range((unsigned long) &frame->tramp[0],
-			   (unsigned long) &frame->tramp[2]);
+	flush_icache_range((unsigned long)&frame->tramp[0],
+			   (unsigned long)&frame->tramp[2]);
 	current->thread.fpscr = 0;	/* turn off all fp exceptions */
 
 	newsp -= __SIGNAL_FRAMESIZE32;
@@ -438,7 +405,7 @@
  *
  *  Other routines
  *        setup_rt_frame32
- *        siginfo64to32
+ *        copy_siginfo_to_user32
  *        siginfo32to64
  */
 
@@ -451,50 +418,45 @@
 			unsigned long r6, unsigned long r7, unsigned long r8,
 			struct pt_regs * regs)
 {
-	struct rt_sigframe_32 *rt_stack_frame;
+	struct rt_sigframe_32 *rt_sf;
 	struct sigcontext32_struct sigctx;
-	struct sigregs32 *signalregs;
+	struct sigregs32 *sr;
 	int ret;
 	elf_gregset_t32 saved_regs;   /* an array of 32 bit register values */
-	sigset_t signal_set; 
-	stack_t stack;
+	sigset_t set; 
+	stack_t st;
 	int i;
 
-	ret = 0;
 	/* Adjust the inputted reg1 to point to the first rt signal frame */
-	rt_stack_frame = (struct rt_sigframe_32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
+	rt_sf = (struct rt_sigframe_32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
 	/* Copy the information from the user stack  */
-	if (copy_from_user(&sigctx, &rt_stack_frame->uc.uc_mcontext,
-				sizeof(sigctx))
-	    || copy_from_user(&signal_set, &rt_stack_frame->uc.uc_sigmask,
-		    sizeof(signal_set))
-	    || copy_from_user(&stack,&rt_stack_frame->uc.uc_stack,
-		    sizeof(stack)))
+	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;
 
 	/*
 	 * Unblock the signal that was processed 
 	 *   After a signal handler runs - 
 	 *     if the signal is blockable - the signal will be unblocked  
-	 *       ( sigkill and sigstop are not blockable)
+	 *       (sigkill and sigstop are not blockable)
 	 */
-	sigdelsetmask(&signal_set, ~_BLOCKABLE); 
+	sigdelsetmask(&set, ~_BLOCKABLE); 
 	/* update the current based on the sigmask found in the rt_stackframe */
 	spin_lock_irq(&current->sigmask_lock);
-	current->blocked = signal_set;
+	current->blocked = set;
 	recalc_sigpending();
 	spin_unlock_irq(&current->sigmask_lock);
 
+	/* If currently owning the floating point - give them up */
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
 	/*
 	 * Set to point to the next rt_sigframe - this is used to
 	 * determine whether this is the last signal to process
 	 */
-	signalregs = (struct sigregs32 *) (u64)sigctx.regs;
-	/* If currently owning the floating point - give them up */
-	if (regs->msr & MSR_FP)
-		giveup_fpu(current);
-	if (copy_from_user(saved_regs, &signalregs->gp_regs,
-				sizeof(signalregs->gp_regs))) 
+	sr = (struct sigregs32 *)(u64)sigctx.regs;
+	if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs))) 
 		goto badframe;
 	/*
 	 * The saved reg structure in the frame is an elf_grepset_t32,
@@ -544,7 +506,7 @@
 
 
 
-asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act,
+long sys32_rt_sigaction(int sig, const struct sigaction32 *act,
 		struct sigaction32 *oact, size_t sigsetsize)
 {
 	struct k_sigaction new_ka, old_ka;
@@ -599,7 +561,7 @@
 }
 
 
-extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set,
+extern long sys_rt_sigprocmask(int how, sigset_t *set,
 		sigset_t *oset, size_t sigsetsize);
 
 /*
@@ -609,7 +571,7 @@
  * of a signed int (msr in 32-bit mode) and the register representation
  * of a signed int (msr in 64-bit mode) is performed.
  */
-asmlinkage long sys32_rt_sigprocmask(u32 how, sigset32_t *set,
+long sys32_rt_sigprocmask(u32 how, sigset32_t *set,
 		sigset32_t *oset, size_t sigsetsize)
 {
 	sigset_t s;
@@ -649,10 +611,10 @@
 }
 
 
-extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
+extern long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
 
 
-asmlinkage long sys32_rt_sigpending(sigset32_t *set,
+long sys32_rt_sigpending(sigset32_t *set,
 		__kernel_size_t32 sigsetsize)
 {
 	sigset_t s;
@@ -677,50 +639,54 @@
 }
 
 
-siginfo_t32 *siginfo64to32(siginfo_t32 *d, siginfo_t *s)
+static int copy_siginfo_to_user32(siginfo_t32 *d, siginfo_t *s)
 {
-	memset (d, 0, sizeof(siginfo_t32));
-	d->si_signo = s->si_signo;
-	d->si_errno = s->si_errno;
-	/* XXX why dont we just implement copy_siginfo_to_user32? - Anton */
-	d->si_code = s->si_code & 0xffff;
+	int err;
+
+	if (!access_ok (VERIFY_WRITE, d, sizeof(*d)))
+		return -EFAULT;
+
+	err = __put_user(s->si_signo, &d->si_signo);
+	err |= __put_user(s->si_errno, &d->si_errno);
+	err |= __put_user((short)s->si_code, &d->si_code);
 	if (s->si_signo >= SIGRTMIN) {
-		d->si_pid = s->si_pid;
-		d->si_uid = s->si_uid;
-		d->si_int = s->si_int;
+		err |= __put_user(s->si_pid, &d->si_pid);
+		err |= __put_user(s->si_uid, &d->si_uid);
+		err |= __put_user(s->si_int, &d->si_int);
 	} else {
 		switch (s->si_signo) {
 		/* XXX: What about POSIX1.b timers */
 		case SIGCHLD:
-			d->si_pid = s->si_pid;
-			d->si_status = s->si_status;
-			d->si_utime = s->si_utime;
-			d->si_stime = s->si_stime;
+			err |= __put_user(s->si_pid, &d->si_pid);
+			err |= __put_user(s->si_status, &d->si_status);
+			err |= __put_user(s->si_utime, &d->si_utime);
+			err |= __put_user(s->si_stime, &d->si_stime);
 			break;
 		case SIGSEGV:
 		case SIGBUS:
 		case SIGFPE:
 		case SIGILL:
-			d->si_addr = (long)(s->si_addr);
+			err |= __put_user((long)(s->si_addr), &d->si_addr);
 	        break;
 		case SIGPOLL:
-			d->si_band = s->si_band;
-			d->si_fd = s->si_fd;
+			err |= __put_user(s->si_band, &d->si_band);
+			err |= __put_user(s->si_fd, &d->si_fd);
 			break;
 		default:
-			d->si_pid = s->si_pid;
-			d->si_uid = s->si_uid;
+			err |= __put_user(s->si_pid, &d->si_pid);
+			err |= __put_user(s->si_uid, &d->si_uid);
 			break;
 		}
 	}
-	return d;
+	return err;
 }
 
-extern asmlinkage long sys_rt_sigtimedwait(const sigset_t *uthese,
+
+extern long sys_rt_sigtimedwait(const sigset_t *uthese,
 		siginfo_t *uinfo, const struct timespec *uts,
 		size_t sigsetsize);
 
-asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
+long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
 		struct timespec32 *uts, __kernel_size_t32 sigsetsize)
 {
 	sigset_t s;
@@ -729,8 +695,7 @@
 	int ret;
 	mm_segment_t old_fs = get_fs();
 	siginfo_t info;
-	siginfo_t32 info32;
-		
+
 	if (copy_from_user(&s32, uthese, sizeof(sigset32_t)))
 		return -EFAULT;
 	switch (_NSIG_WORDS) {
@@ -753,8 +718,7 @@
 				sigsetsize);
 	set_fs(old_fs);
 	if (ret >= 0 && uinfo) {
-		if (copy_to_user (uinfo, siginfo64to32(&info32, &info),
-				  sizeof(siginfo_t32)))
+		if (copy_siginfo_to_user32(uinfo, &info))
 			return -EFAULT;
 	}
 	return ret;
@@ -762,7 +726,7 @@
 
 
 
-siginfo_t * siginfo32to64(siginfo_t *d, siginfo_t32 *s)
+static siginfo_t * siginfo32to64(siginfo_t *d, siginfo_t32 *s)
 {
 	d->si_signo = s->si_signo;
 	d->si_errno = s->si_errno;
@@ -800,7 +764,7 @@
 }
 
 
-extern asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
+extern long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
 
 /*
  * Note: it is necessary to treat pid and sig as unsigned ints, with the
@@ -809,7 +773,7 @@
  * (msr in 32-bit mode) and the register representation of a signed int
  * (msr in 64-bit mode) is performed.
  */
-asmlinkage long sys32_rt_sigqueueinfo(u32 pid, u32 sig, siginfo_t32 *uinfo)
+long sys32_rt_sigqueueinfo(u32 pid, u32 sig, siginfo_t32 *uinfo)
 {
 	siginfo_t info;
 	siginfo_t32 info32;
@@ -974,8 +938,7 @@
 		unsigned int frame)
 {
 	struct sigcontext32_struct *sc;
-	struct rt_sigframe_32 *rt_stack_frame;
-	siginfo_t32 siginfo32bit;
+	struct rt_sigframe_32 *rt_sf;
 	struct k_sigaction *ka = &current->sig->action[sig-1];
 
 	if (regs->trap == 0x0C00 /* System Call! */
@@ -986,42 +949,35 @@
 
 	/*
 	 * Set up the signal frame
-	 * Determine if an real time frame - siginfo required
+	 * Determine if a real time frame and a siginfo is required
 	 */
 	if (ka->sa.sa_flags & SA_SIGINFO) {
-		siginfo64to32(&siginfo32bit,info);
-		*newspp -= sizeof(*rt_stack_frame);
-		rt_stack_frame = (struct rt_sigframe_32 *)(u64)(*newspp);
-
-		if (verify_area(VERIFY_WRITE, rt_stack_frame,
-					sizeof(*rt_stack_frame)))
+		*newspp -= sizeof(*rt_sf);
+		rt_sf = (struct rt_sigframe_32 *)(u64)(*newspp);
+		if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
 			goto badframe;
 		if (__put_user((u32)(u64)ka->sa.sa_handler,
-					&rt_stack_frame->uc.uc_mcontext.handler)
-		    || __put_user((u32)(u64)&rt_stack_frame->info,
-			    &rt_stack_frame->pinfo)
-		    || __put_user((u32)(u64)&rt_stack_frame->uc,
-			    &rt_stack_frame->puc)
+					&rt_sf->uc.uc_mcontext.handler)
+		    || __put_user((u32)(u64)&rt_sf->info, &rt_sf->pinfo)
+		    || __put_user((u32)(u64)&rt_sf->uc, &rt_sf->puc)
 		    /*  put the siginfo on the user stack                    */
-		    || __copy_to_user(&rt_stack_frame->info, &siginfo32bit,
-			    sizeof(siginfo32bit))
+		    || copy_siginfo_to_user32(&rt_sf->info, info)
 		    /*  set the ucontext on the user stack                   */ 
-		    || __put_user(0, &rt_stack_frame->uc.uc_flags)
-		    || __put_user(0, &rt_stack_frame->uc.uc_link)
-		    || __put_user(current->sas_ss_sp,
-			    &rt_stack_frame->uc.uc_stack.ss_sp)
+		    || __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_stack_frame->uc.uc_stack.ss_flags)
+			    &rt_sf->uc.uc_stack.ss_flags)
 		    || __put_user(current->sas_ss_size,
-			    &rt_stack_frame->uc.uc_stack.ss_size)
-		    || __copy_to_user(&rt_stack_frame->uc.uc_sigmask,
+			    &rt_sf->uc.uc_stack.ss_size)
+		    || __copy_to_user(&rt_sf->uc.uc_sigmask,
 			    oldset, sizeof(*oldset))
 		    /* point the mcontext.regs to the pramble register frame  */
-		    || __put_user(frame, &rt_stack_frame->uc.uc_mcontext.regs)
-		    || __put_user(sig,&rt_stack_frame->uc.uc_mcontext.signal))
+		    || __put_user(frame, &rt_sf->uc.uc_mcontext.regs)
+		    || __put_user(sig,&rt_sf->uc.uc_mcontext.signal))
 			goto badframe; 
 	} else {
-		/* Put another sigcontext on the stack */
+		/* Put a sigcontext on the stack */
 		*newspp -= sizeof(*sc);
 		sc = (struct sigcontext32_struct *)(u64)*newspp;
 		if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
@@ -1048,7 +1004,6 @@
 		recalc_sigpending();
 		spin_unlock_irq(&current->sigmask_lock);
 	}
-	
 	return;
 
 badframe:
@@ -1068,7 +1023,7 @@
  *       sigaltatck               sys32_sigaltstack
  */
 
-asmlinkage int sys32_sigaltstack(u32 newstack, u32 oldstack, int p3,
+int sys32_sigaltstack(u32 newstack, u32 oldstack, int p3,
 		int p4, int p6, int p7, struct pt_regs *regs)
 {
 	stack_t uss, uoss;
@@ -1114,7 +1069,7 @@
 /*
  *  Start of do_signal32 routine
  *
- *   This routine gets control when a pemding signal needs to be processed
+ *   This routine gets control when a pending signal needs to be processed
  *     in the 32 bit target thread -
  *
  *   It handles both rt and non-rt signals
@@ -1141,13 +1096,13 @@
 	signr = get_signal_to_deliver(&info, regs);
 	if (signr > 0) {
 		ka = &current->sig->action[signr-1];
-
-		if ((ka->sa.sa_flags & SA_ONSTACK) &&
-				(!on_sig_stack(regs->gpr[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 sigregs32);
+
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal32(signr, &info, oldset, regs, &newsp, frame);
 	}
@@ -1165,10 +1120,9 @@
 		return 0;		/* no signals delivered */
 
 	/* Invoke correct stack setup routine */
-	if (ka->sa.sa_flags & SA_SIGINFO) 
+	if (ka->sa.sa_flags & SA_SIGINFO)
 		setup_rt_frame32(regs, (struct sigregs32*)(u64)frame, newsp);
 	else
 		setup_frame32(regs, (struct sigregs32*)(u64)frame, newsp);
-
 	return 1;
 }
diff -Nru a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
--- a/arch/ppc64/kernel/smp.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/smp.c	Wed Jul 24 14:03:39 2002
@@ -28,7 +28,6 @@
 #define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
 #include <linux/init.h>
-/* #include <linux/openpic.h> */
 #include <linux/spinlock.h>
 #include <linux/cache.h>
 #include <linux/err.h>
@@ -40,7 +39,6 @@
 #include <asm/pgtable.h>
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
-#include <asm/init.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/smp.h>
@@ -56,20 +54,18 @@
 
 int smp_threads_ready = 0;
 volatile int smp_commenced = 0;
-int smp_num_cpus = 1;
 int smp_tb_synchronized = 0;
 spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
 unsigned long cache_decay_ticks;
 static int max_cpus __initdata = NR_CPUS;
 
-unsigned long cpu_online_map;
+/* initialised so it doesnt end up in bss */
+unsigned long cpu_online_map = 0;
+int boot_cpuid = 0;
+int ppc64_is_smp = 0;
 
 volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};
 
-#define TB_SYNC_PASSES 4
-volatile unsigned long __initdata tb_sync_flag = 0;
-volatile unsigned long __initdata tb_offset = 0;
-
 extern unsigned char stab_array[];
 
 int start_secondary(void *);
@@ -104,7 +100,7 @@
 	int cpu = smp_processor_id();
 	int msg;
 
-	if ( smp_num_cpus < 2 )
+	if ( num_online_cpus() < 2 )
 		return;
 
 	for ( msg = 0; msg < 4; ++msg )
@@ -116,11 +112,16 @@
 static void smp_iSeries_message_pass(int target, int msg, unsigned long data, int wait)
 {
 	int i;
-	for (i = 0; i < smp_num_cpus; ++i) {
-		if ( (target == MSG_ALL) || 
-                    (target == i) || 
-                    ((target == MSG_ALL_BUT_SELF) && (i != smp_processor_id())) ) {
-			set_bit( msg, &iSeries_smp_message[i] );
+
+	for (i = 0; i < NR_CPUS; ++i) {
+		if (!cpu_online(i))
+			continue;
+
+		if ((target == MSG_ALL) || 
+		    (target == i) || 
+		    ((target == MSG_ALL_BUT_SELF) &&
+		     (i != smp_processor_id())) ) {
+			set_bit(msg, &iSeries_smp_message[i]);
 			HvCall_sendIPI(&(paca[i]));
 		}
 	}
@@ -141,7 +142,7 @@
 	return np;
 }
 
-static int smp_iSeries_probe(void)
+static void smp_iSeries_probe(void)
 {
 	unsigned i;
 	unsigned np;
@@ -151,13 +152,13 @@
 	for (i=0; i < MAX_PACAS; ++i) {
 		lpPaca = paca[i].xLpPacaPtr;
 		if ( lpPaca->xDynProcStatus < 2 ) {
+			paca[i].active = 1;
 			++np;
 			paca[i].next_jiffy_update_tb = paca[0].next_jiffy_update_tb;
 		}
 	}
-	
+
 	smp_tb_synchronized = 1;
-	return np;
 }
 
 static void smp_iSeries_kick_cpu(int nr)
@@ -197,8 +198,10 @@
 	ppc_md.smp_probe        = smp_iSeries_probe;
 	ppc_md.smp_kick_cpu     = smp_iSeries_kick_cpu;
 	ppc_md.smp_setup_cpu    = smp_iSeries_setup_cpu;
-
+#ifdef CONFIG_PPC_ISERIES
+#warning fix for iseries
 	naca->processorCount	= smp_iSeries_numProcs();
+#endif
 }
 
 
@@ -226,13 +229,10 @@
 	}
 }
 
-static int
-smp_chrp_probe(void)
+static void smp_chrp_probe(void)
 {
-	if (naca->processorCount > 1)
+	if (ppc64_is_smp)
 		openpic_request_IPIs();
-
-	return naca->processorCount;
 }
 
 static void
@@ -259,14 +259,14 @@
 
 extern struct gettimeofday_struct do_gtod;
 
-static void smp_space_timers( unsigned nr )
+static void smp_space_timers()
 {
-	unsigned long offset, i;
-	
-	offset = tb_ticks_per_jiffy / nr;
-	for ( i=1; i<nr; ++i ) {
-		paca[i].next_jiffy_update_tb = paca[i-1].next_jiffy_update_tb + offset;
-	}
+	int i;
+	unsigned long offset = tb_ticks_per_jiffy / NR_CPUS;
+
+	for (i = 1; i < NR_CPUS; ++i)
+		paca[i].next_jiffy_update_tb =
+			paca[i-1].next_jiffy_update_tb + offset;
 }
 
 static void
@@ -278,7 +278,7 @@
 	if (naca->platform == PLATFORM_PSERIES_LPAR) {
 		/* timebases already synced under the hypervisor. */
 		paca[cpu_nr].next_jiffy_update_tb = tb_last_stamp = get_tb();
-		if (cpu_nr == 0) {
+		if (cpu_nr == boot_cpuid) {
 			do_gtod.tb_orig_stamp = tb_last_stamp;
 			/* Should update do_gtod.stamp_xsec.
 			 * For now we leave it which means the time can be some
@@ -287,9 +287,9 @@
 		}
 		smp_tb_synchronized = 1;
 	} else {
-		if (cpu_nr == 0) {
+		if (cpu_nr == boot_cpuid) {
 			/* wait for all the others */
-			while (atomic_read(&ready) < smp_num_cpus)
+			while (atomic_read(&ready) < num_online_cpus())
 				barrier();
 			atomic_set(&ready, 1);
 			/* freeze the timebase */
@@ -297,9 +297,9 @@
 			mb();
 			frozen = 1;
 			set_tb(0, 0);
-			paca[0].next_jiffy_update_tb = 0;
-			smp_space_timers(smp_num_cpus);
-			while (atomic_read(&ready) < smp_num_cpus)
+			paca[boot_cpuid].next_jiffy_update_tb = 0;
+			smp_space_timers();
+			while (atomic_read(&ready) < num_online_cpus())
 				barrier();
 			/* thaw the timebase again */
 			rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
@@ -323,8 +323,8 @@
 	if (OpenPIC_Addr) {
 		do_openpic_setup_cpu();
 	} else {
-	  if (cpu_nr > 0)
-	    xics_setup_cpu();
+		if (cpu_nr != boot_cpuid)
+			xics_setup_cpu();
 	}
 }
 
@@ -333,7 +333,10 @@
 {
 	int i;
 
-	for (i = 0; i < smp_num_cpus; ++i) {
+	for (i = 0; i < NR_CPUS; ++i) {
+		if (!cpu_online(i))
+			continue;
+
 		if (target == MSG_ALL || target == i
 		    || (target == MSG_ALL_BUT_SELF
 			&& i != smp_processor_id())) {
@@ -344,10 +347,8 @@
 	}
 }
 
-static int
-smp_xics_probe(void)
+static void smp_xics_probe(void)
 {
-	return naca->processorCount;
 }
 
 /* This is called very early */
@@ -427,7 +428,7 @@
 
 static void stop_this_cpu(void *dummy)
 {
-	__cli();
+	local_irq_disable();
 	while (1)
 		;
 }
@@ -435,7 +436,6 @@
 void smp_send_stop(void)
 {
 	smp_call_function(stop_this_cpu, NULL, 1, 0);
-	smp_num_cpus = 1;
 }
 
 /*
@@ -473,7 +473,7 @@
 
 { 
 	struct call_data_struct data;
-	int ret = -1, cpus = smp_num_cpus-1;
+	int ret = -1, cpus = num_online_cpus()-1;
 	int timeout;
 
 	if (!cpus)
@@ -560,29 +560,23 @@
 
 void __init smp_boot_cpus(void)
 {
-	int i, cpu_nr;
+	int i, cpu_nr = 0;
 	struct task_struct *p;
 
 	printk("Entering SMP Mode...\n");
 
-	smp_num_cpus = 1;
-        smp_store_cpu_info(0);
-	cpu_online_map = 1UL;
+        smp_store_cpu_info(boot_cpuid);
+	cpu_callin_map[boot_cpuid] = 1;
 
-	/*
-	 * assume for now that the first cpu booted is
-	 * cpu 0, the master -- Cort
-	 */
-	cpu_callin_map[0] = 1;
 	/* XXX buggy - Anton */
 	current_thread_info()->cpu = 0;
 
 	for (i = 0; i < NR_CPUS; i++) {
 		paca[i].prof_counter = 1;
 		paca[i].prof_multiplier = 1;
-		if(i != 0) {
+		if (i != boot_cpuid) {
 		        /*
-			 * Processor 0's segment table is statically 
+			 * the boot cpu segment table is statically 
 			 * initialized to real address 0x5000.  The
 			 * Other processor's tables are created and
 			 * initialized here.
@@ -595,36 +589,37 @@
 	}
 
 	/*
-	 * XXX very rough. On POWER4 we optimise tlb flushes for
-	 * tasks that only run on one cpu so we increase decay ticks.
+	 * XXX very rough. 
 	 */
-	if (__is_processor(PV_POWER4))
-		cache_decay_ticks = HZ/50;
-	else
-		cache_decay_ticks = HZ/100;
+	cache_decay_ticks = HZ/100;
 
-	/* Probe arch for CPUs */
-	cpu_nr = ppc_md.smp_probe();
+	ppc_md.smp_probe();
 
+	for (i = 0; i < NR_CPUS; i++) {
+		if (paca[i].active)
+			cpu_nr++;
+	}
 	printk("Probe found %d CPUs\n", cpu_nr);
 
-	/*
-	 * only check for cpus we know exist.  We keep the callin map
-	 * with cpus at the bottom -- Cort
-	 */
-	if (cpu_nr > max_cpus)
-		cpu_nr = max_cpus;
-
 #ifdef CONFIG_ISERIES
-	smp_space_timers( cpu_nr );
+	smp_space_timers();
 #endif
 
 	printk("Waiting for %d CPUs\n", cpu_nr-1);
 
-	for ( i = 1 ; i < cpu_nr; i++ ) {
+	for (i = 1 ; i < NR_CPUS; i++) {
 		int c;
 		struct pt_regs regs;
 
+		if (!paca[i].active)
+			continue;
+
+		if (i == boot_cpuid)
+			continue;
+
+		if (num_online_cpus() >= max_cpus)
+			break;
+
 		/* create a process for the processor */
 		/* we don't care about the values in regs since we'll
 		   never reschedule the forked task. */
@@ -668,16 +663,15 @@
 		{
 			printk("Processor %d found.\n", i);
 			/* this sync's the decr's -- Cort */
-			smp_num_cpus++;
 		} else {
 			printk("Processor %d is stuck.\n", i);
 		}
 	}
 
-	/* Setup CPU 0 last (important) */
-	ppc_md.smp_setup_cpu(0);
-	
-	if (smp_num_cpus < 2) {
+	/* Setup boot cpu last (important) */
+	ppc_md.smp_setup_cpu(boot_cpuid);
+
+	if (num_online_cpus() < 2) {
 	        tb_last_stamp = get_tb();
 		smp_tb_synchronized = 1;
 	}
@@ -699,15 +693,16 @@
 
         smp_store_cpu_info(cpu);
 	set_dec(paca[cpu].default_decr);
-	cpu_callin_map[cpu] = 1;
 	set_bit(smp_processor_id(), &cpu_online_map);
+	smp_mb();
+	cpu_callin_map[cpu] = 1;
 
 	ppc_md.smp_setup_cpu(cpu);
 	
 	while(!smp_commenced) {
 		barrier();
 	}
-	__sti();
+	local_irq_enable();
 }
 
 /* intel needs this */
@@ -729,7 +724,7 @@
 {
 }
 
-int __init setup_profiling_timer(unsigned int multiplier)
+int setup_profiling_timer(unsigned int multiplier)
 {
 	return 0;
 }
diff -Nru a/arch/ppc64/kernel/stab.c b/arch/ppc64/kernel/stab.c
--- a/arch/ppc64/kernel/stab.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/stab.c	Wed Jul 24 14:03:39 2002
@@ -25,8 +25,6 @@
 int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid);
 void make_slbe(unsigned long esid, unsigned long vsid, int large);
 
-#define cpu_has_slb()	(__is_processor(PV_POWER4))
-
 /*
  * Build an entry for the base kernel segment and put it into
  * the segment table or SLB.  All other segment table or SLB
@@ -371,7 +369,7 @@
 		/* Force previous translations to complete. DRENG */
 		asm volatile("isync" : : : "memory");
 
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		if (get_paca()->stab_cache_pointer != 0xff && !STAB_PRESSURE) {
 			int i;
 			unsigned char *segments = get_paca()->xSegments;
@@ -417,7 +415,7 @@
 		}
 
 		get_paca()->stab_cache_pointer = 0;
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 
 	if (ppc64_stab_preload)
diff -Nru a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
--- a/arch/ppc64/kernel/time.c	Wed Jul 24 14:03:39 2002
+++ b/arch/ppc64/kernel/time.c	Wed Jul 24 14:03:39 2002
@@ -53,7 +53,6 @@
 #include <asm/nvram.h>
 #include <asm/cache.h>
 #include <asm/machdep.h>
-#include <asm/init.h>
 #ifdef CONFIG_PPC_ISERIES
 #include <asm/iSeries/HvCallXm.h>
 #endif
@@ -183,9 +182,9 @@
 #ifdef CONFIG_PPC_ISERIES
 
 /* 
- * This function recalibrates the timebase based on the 49-bit time-of-day value in the Titan chip.
- * The Titan is much more accurate than the value returned by the service processor for the
- * timebase frequency.  
+ * This function recalibrates the timebase based on the 49-bit time-of-day
+ * value in the Titan chip.  The Titan is much more accurate than the value
+ * returned by the service processor for the timebase frequency.  
  */
 
 static void iSeries_tb_recal(void)
@@ -256,7 +255,7 @@
 	unsigned long cpu = lpaca->xPacaIndex;
 	struct ItLpQueue * lpq;
 
-	irq_enter(cpu);
+	irq_enter();
 
 #ifndef CONFIG_PPC_ISERIES
 	if (!user_mode(regs))
@@ -270,7 +269,7 @@
 #ifdef CONFIG_SMP
 		smp_local_timer_interrupt(regs);
 #endif
-		if (cpu == 0) {
+		if (cpu == boot_cpuid) {
 			write_lock(&xtime_lock);
 			tb_last_stamp = lpaca->next_jiffy_update_tb;
 			do_timer(regs);
@@ -292,7 +291,7 @@
 	if (lpq && ItLpQueue_isLpIntPending(lpq))
 		lpEvent_count += ItLpQueue_process(lpq, regs); 
 
-	irq_exit(cpu);
+	irq_exit();
 
 	if (softirq_pending(cpu))
 		do_softirq();
@@ -485,10 +484,10 @@
  * After adjtimex is called, adjust the conversion of tb ticks
  * to microseconds to keep do_gettimeofday synchronized 
  * with ntpd.
-
+ *
  * Use the time_adjust, time_freq and time_offset computed by adjtimex to 
  * adjust the frequency.
-*/
+ */
 
 /* #define DEBUG_PPC_ADJTIMEX 1 */
 
@@ -531,8 +530,11 @@
 		
 		/* Compute parts per million frequency adjustment to match time_adjust */
 		singleshot_ppm = tickadj * HZ;	
-		/* The adjustment should be tickadj*HZ to match the code in linux/kernel/timer.c, but
-		   experiments show that this is too large. 3/4 of tickadj*HZ seems about right */
+		/*
+		 * The adjustment should be tickadj*HZ to match the code in
+		 * linux/kernel/timer.c, but experiments show that this is too
+		 * large. 3/4 of tickadj*HZ seems about right
+		 */
 		singleshot_ppm -= singleshot_ppm / 4;
 		/* Use SHIFT_USEC to get it into the same units as time_freq */	
 		singleshot_ppm <<= SHIFT_USEC;
diff -Nru a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
--- a/arch/ppc64/kernel/traps.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/kernel/traps.c	Wed Jul 24 14:03:38 2002
@@ -172,8 +172,9 @@
 	if (!user_mode(regs)) {
 		/* Attempt to recover if the interrupt is recoverable */
 		if (regs->msr & MSR_RI) {
-			if (__is_processor(PV_POWER4) &&
-			    power4_handle_mce(regs))
+			if ((__is_processor(PV_POWER4) ||
+			     __is_processor(PV_POWER4p)) &&
+			     power4_handle_mce(regs))
 				return;
 		}
 
diff -Nru a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
--- a/arch/ppc64/kernel/xics.c	Wed Jul 24 14:03:35 2002
+++ b/arch/ppc64/kernel/xics.c	Wed Jul 24 14:03:35 2002
@@ -340,7 +340,7 @@
 	/* Find the server numbers for the boot cpu. */
 	for (np = find_type_devices("cpu"); np; np = np->next) {
 		ireg = (uint *)get_property(np, "reg", &ilen);
-		if (ireg && ireg[0] == hard_smp_processor_id()) {
+		if (ireg && ireg[0] == smp_processor_id()) {
 			ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
 			i = ilen / sizeof(int);
 			if (ireg && i > 0) {
@@ -357,6 +357,7 @@
 	np = find_type_devices("interrupt-controller");
 	if (!np) {
 		printk(KERN_WARNING "xics:  no ISA Interrupt Controller\n");
+		xics_irq_8259_cascade_real = -1;
 		xics_irq_8259_cascade = -1;
 	} else {
 		ireg = (uint *) get_property(np, "interrupts", 0);
@@ -371,10 +372,12 @@
 
 	if (naca->platform == PLATFORM_PSERIES) {
 #ifdef CONFIG_SMP
-		for (i = 0; i < naca->processorCount; ++i) {
+		for (i = 0; i < NR_CPUS; ++i) {
+			if (!paca[i].active)
+				continue;
 			xics_info.per_cpu[i] =
-			  __ioremap((ulong)inodes[get_hard_smp_processor_id(i)].addr, 
-				  (ulong)inodes[get_hard_smp_processor_id(i)].size, _PAGE_NO_CACHE);
+			  __ioremap((ulong)inodes[i].addr, 
+				  (ulong)inodes[i].size, _PAGE_NO_CACHE);
 		}
 #else
 		xics_info.per_cpu[0] = __ioremap((ulong)intr_base, intr_size, _PAGE_NO_CACHE);
@@ -395,7 +398,7 @@
 	for (; i < NR_IRQS; ++i)
 		irq_desc[i].handler = &xics_pic;
 
-	ops->cppr_info(0, 0xff);
+	ops->cppr_info(boot_cpuid, 0xff);
 	iosync();
 	if (xics_irq_8259_cascade != -1) {
 		if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action,
@@ -420,23 +423,6 @@
 	i8259_init();
 }
 
-/*
- * Find first logical cpu and return its physical cpu number
- */
-static inline u32 physmask(u32 cpumask)
-{
-	int i;
-
-	for (i = 0; i < smp_num_cpus; ++i, cpumask >>= 1) {
-		if (cpumask & 1)
-			return get_hard_smp_processor_id(i);
-	}
-
-	printk(KERN_ERR "xics_set_affinity: invalid irq mask\n");
-
-	return default_distrib_server;
-}
-
 void xics_set_affinity(unsigned int virq, unsigned long cpumask)
 {
         irq_desc_t *desc = irq_desc + virq;
@@ -462,10 +448,13 @@
 	}
 
 	/* For the moment only implement delivery to all cpus or one cpu */
-	if (cpumask == 0xffffffff)
+	if (cpumask == 0xffffffff) {
 		newmask = default_distrib_server;
-	else
-		newmask = physmask(cpumask);
+	} else {
+		if (!(cpumask & cpu_online_map))
+			goto out;
+		newmask = find_first_bit(&cpumask, 32);
+	}
 
 	status = rtas_call(ibm_set_xive, 3, 1, NULL,
 				irq, newmask, xics_status[1]);
diff -Nru a/arch/ppc64/lib/string.S b/arch/ppc64/lib/string.S
--- a/arch/ppc64/lib/string.S	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/lib/string.S	Wed Jul 24 14:03:36 2002
@@ -171,11 +171,11 @@
 	add	r4,r0,r4
 	subf	r6,r0,r6
 	srwi	r0,r4,2
+	andi.	r4,r4,3
 	mtctr	r0
-	bdz	6f
+	bdz	7f
 1:	stwu	r5,4(r6)
 	bdnz	1b
-6:	andi.	r4,r4,3
 	/* clear byte sized chunks */
 7:	cmpwi	0,r4,0
 	beqlr
@@ -184,14 +184,20 @@
 8:	stbu	r5,1(r6)
 	bdnz	8b
 	blr
-99:	li	r3,-EFAULT
+90:	mr	r3,r4
+	blr
+91:	mfctr	r3
+	slwi	r3,r3,2
+	add	r3,r3,r4
+	blr
+92:	mfctr	r3
 	blr
 
 	.section __ex_table,"a"
 	.align	3
-	.llong	11b,99b
-	.llong	1b,99b
-	.llong	8b,99b
+	.llong	11b,90b
+	.llong	1b,91b
+	.llong	8b,92b
 	.text
 
 _GLOBAL(__strncpy_from_user)
diff -Nru a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c
--- a/arch/ppc64/mm/fault.c	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/mm/fault.c	Wed Jul 24 14:03:36 2002
@@ -121,16 +121,18 @@
 	 */
 	switch (handle_mm_fault(mm, vma, address, is_write)) {
 
-	case 1:
+	case VM_FAULT_MINOR:
 		current->min_flt++;
 		break;
-	case 2:
+	case VM_FAULT_MAJOR:
 		current->maj_flt++;
 		break;
-	case 0:
+	case VM_FAULT_SIGBUS:
 		goto do_sigbus;
-	default:
+	case VM_FAULT_OOM:
 		goto out_of_memory;
+	default:
+		BUG();
 	}
 
 	up_read(&mm->mmap_sem);
diff -Nru a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
--- a/arch/ppc64/mm/init.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/mm/init.c	Wed Jul 24 14:03:38 2002
@@ -1,6 +1,4 @@
 /*
- *  
- *
  *  PowerPC version 
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
@@ -59,11 +57,10 @@
 #include <asm/tlb.h>
 #include <asm/naca.h>
 #include <asm/eeh.h>
+#include <asm/processor.h>
 
 #include <asm/ppcdebug.h>
 
-#define	PGTOKB(pages)	(((pages) * PAGE_SIZE) >> 10)
-
 #ifdef CONFIG_PPC_ISERIES
 #include <asm/iSeries/iSeries_dma.h>
 #endif
@@ -76,15 +73,10 @@
 
 extern pgd_t swapper_pg_dir[];
 extern char __init_begin, __init_end;
-extern char __chrp_begin, __chrp_end;
-extern char __openfirmware_begin, __openfirmware_end;
-extern struct _of_tce_table of_tce_table[];
 extern char _start[], _end[];
 extern char _stext[], etext[];
 extern struct task_struct *current_set[NR_CPUS];
 
-void mm_init_ppc64(void);
-
 extern pgd_t ioremap_dir[];
 pgd_t * ioremap_pgd = (pgd_t *)&ioremap_dir;
 
@@ -107,7 +99,7 @@
 
 void show_mem(void)
 {
-	int i,free = 0,total = 0,reserved = 0;
+	int i,total = 0,reserved = 0;
 	int shared = 0, cached = 0;
 
 	printk("Mem-info:\n");
@@ -120,13 +112,10 @@
 			reserved++;
 		else if (PageSwapCache(mem_map+i))
 			cached++;
-		else if (!atomic_read(&mem_map[i].count))
-			free++;
-		else
-			shared += atomic_read(&mem_map[i].count) - 1;
+		else if (page_count(mem_map+i))
+			shared += page_count(mem_map+i) - 1;
 	}
 	printk("%d pages of RAM\n",total);
-	printk("%d free pages\n",free);
 	printk("%d reserved pages\n",reserved);
 	printk("%d pages shared\n",shared);
 	printk("%d pages swap cached\n",cached);
@@ -179,7 +168,7 @@
 	else {
 		ea = ioremap_bot;
 		ioremap_bot += size;
-        }
+	}
 
 	if ((flags & _PAGE_PRESENT) == 0)
 		flags |= pgprot_val(PAGE_KERNEL);
@@ -196,9 +185,9 @@
 void iounmap(void *addr) 
 {
 #ifdef CONFIG_PPC_ISERIES
-     /* iSeries I/O Remap is a noop              */
+	/* iSeries I/O Remap is a noop              */
 	return;
-#else 
+#else
 	/* DRENG / PPPBBB todo */
 	return;
 #endif
@@ -229,7 +218,7 @@
 		/* If the mm subsystem is not fully up, we cannot create a
 		 * linux page table entry for this mapping.  Simply bolt an
 		 * entry in the hardware page table. 
- 		 */
+		 */
 		vsid = get_kernel_vsid(ea);
 		ppc_md.make_pte(htab_data.htab,
 			(vsid << 28) | (ea & 0xFFFFFFF), // va (NOT the ea)
@@ -302,7 +291,7 @@
 	}
 }
 
-struct tlb_batch_data tlb_batch_array[NR_CPUS][MAX_BATCH_FLUSH];
+struct ppc64_tlb_batch ppc64_tlb_batch[NR_CPUS];
 
 void
 __flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
@@ -312,81 +301,69 @@
 	pte_t *ptep;
 	pte_t pte;
 	unsigned long pgd_end, pmd_end;
-	unsigned long context;
-	int i = 0;
-	struct tlb_batch_data *ptes = &tlb_batch_array[smp_processor_id()][0];
+	unsigned long context = 0;
+	struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[smp_processor_id()];
+	unsigned long i = 0;
 	int local = 0;
 
-	if ( start >= end )
-		panic("flush_tlb_range: start (%016lx) greater than end (%016lx)\n", start, end );
-
-	if ( REGION_ID(start) != REGION_ID(end) )
-		panic("flush_tlb_range: start (%016lx) and end (%016lx) not in same region\n", start, end );
-	
-	context = 0;
-
-	switch( REGION_ID(start) ) {
+	switch(REGION_ID(start)) {
 	case VMALLOC_REGION_ID:
-		pgd = pgd_offset_k( start );
+		pgd = pgd_offset_k(start);
 		break;
 	case IO_REGION_ID:
-		pgd = pgd_offset_i( start );
+		pgd = pgd_offset_i(start);
 		break;
 	case USER_REGION_ID:
-		pgd = pgd_offset( mm, start );
+		pgd = pgd_offset(mm, start);
 		context = mm->context;
 
 		/* XXX are there races with checking cpu_vm_mask? - Anton */
-		if (mm->cpu_vm_mask == (1 << smp_processor_id())) {
+		if (mm->cpu_vm_mask == (1 << smp_processor_id()))
 			local = 1;
-		}
 
 		break;
 	default:
 		panic("flush_tlb_range: invalid region for start (%016lx) and end (%016lx)\n", start, end);
-	
 	}
 
 	do {
 		pgd_end = (start + PGDIR_SIZE) & PGDIR_MASK;
-		if ( pgd_end > end ) 
+		if (pgd_end > end)
 			pgd_end = end;
-		if ( !pgd_none( *pgd ) ) {
-			pmd = pmd_offset( pgd, start );
+		if (!pgd_none(*pgd)) {
+			pmd = pmd_offset(pgd, start);
 			do {
-				pmd_end = ( start + PMD_SIZE ) & PMD_MASK;
-				if ( pmd_end > end )
+				pmd_end = (start + PMD_SIZE) & PMD_MASK;
+				if (pmd_end > end)
 					pmd_end = end;
-				if ( !pmd_none( *pmd ) ) {
-					ptep = pte_offset_kernel( pmd, start );
+				if (!pmd_none(*pmd)) {
+					ptep = pte_offset_kernel(pmd, start);
 					do {
-						if ( pte_val(*ptep) & _PAGE_HASHPTE ) {
+						if (pte_val(*ptep) & _PAGE_HASHPTE) {
 							pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
-							if ( pte_val(pte) & _PAGE_HASHPTE ) {
-								ptes->pte = pte;
-								ptes->addr = start;
-								ptes++;
+							if (pte_val(pte) & _PAGE_HASHPTE) {								
+								batch->pte[i] = pte;
+								batch->addr[i] = start;
 								i++;
-								if (i == MAX_BATCH_FLUSH) {
-									flush_hash_range(context, MAX_BATCH_FLUSH, local);
+								if (i == PPC64_TLB_BATCH_NR) {
+									flush_hash_range(context, i, local);
 									i = 0;
-									ptes = &tlb_batch_array[smp_processor_id()][0];
 								}
 							}
 						}
 						start += PAGE_SIZE;
 						++ptep;
-					} while ( start < pmd_end );
-				}
-				else
+					} while (start < pmd_end);
+				} else {
 					start = pmd_end;
+				}
 				++pmd;
-			} while ( start < pgd_end );
-		}
-		else
+			} while (start < pgd_end);
+		} else {
 			start = pgd_end;
+		}
 		++pgd;
-	} while ( start < end );
+	} while (start < end);
 
 	if (i)
 		flush_hash_range(context, i, local);
@@ -435,12 +412,12 @@
 	 * The range of contexts [FIRST_USER_CONTEXT, NUM_USER_CONTEXT)
 	 * are stored on a stack/queue for easy allocation and deallocation.
 	 */
-        mmu_context_queue.lock = SPIN_LOCK_UNLOCKED;
-        mmu_context_queue.head = 0;
-        mmu_context_queue.tail = NUM_USER_CONTEXT-1;
-        mmu_context_queue.size = NUM_USER_CONTEXT;
+	mmu_context_queue.lock = SPIN_LOCK_UNLOCKED;
+	mmu_context_queue.head = 0;
+	mmu_context_queue.tail = NUM_USER_CONTEXT-1;
+	mmu_context_queue.size = NUM_USER_CONTEXT;
 	for(index=0; index < NUM_USER_CONTEXT ;index++) {
-                mmu_context_queue.elements[index] = index+FIRST_USER_CONTEXT;
+		mmu_context_queue.elements[index] = index+FIRST_USER_CONTEXT;
 	}
 
 	/* Setup guard pages for the Paca's */
@@ -463,7 +440,6 @@
 	unsigned long start, bootmap_pages;
 	unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
 
-	PPCDBG(PPCDBG_MMINIT, "do_init_bootmem: start\n");
 	/*
 	 * Find an area to use for the bootmem bitmap.  Calculate the size of
 	 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
@@ -472,21 +448,16 @@
 	bootmap_pages = bootmem_bootmap_pages(total_pages);
 
 	start = (unsigned long)__a2p(lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE));
-	if( start == 0 ) {
+	if (start == 0) {
 		udbg_printf("do_init_bootmem: failed to allocate a bitmap.\n");
 		udbg_printf("\tbootmap_pages = 0x%lx.\n", bootmap_pages);
 		PPCDBG_ENTER_DEBUGGER(); 
 	}
 
-	PPCDBG(PPCDBG_MMINIT, "\tstart               = 0x%lx\n", start);
-	PPCDBG(PPCDBG_MMINIT, "\tbootmap_pages       = 0x%lx\n", bootmap_pages);
-	PPCDBG(PPCDBG_MMINIT, "\tphysicalMemorySize  = 0x%lx\n", naca->physicalMemorySize);
-
 	boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
-	PPCDBG(PPCDBG_MMINIT, "\tboot_mapsize        = 0x%lx\n", boot_mapsize);
 
 	/* add all physical memory to the bootmem map */
-	for (i=0; i < lmb.memory.cnt ;i++) {
+	for (i=0; i < lmb.memory.cnt; i++) {
 		unsigned long physbase, size;
 		unsigned long type = lmb.memory.region[i].type;
 
@@ -497,19 +468,14 @@
 		size = lmb.memory.region[i].size;
 		free_bootmem(physbase, size);
 	}
+
 	/* reserve the sections we're already using */
-	for (i=0; i < lmb.reserved.cnt ;i++) {
+	for (i=0; i < lmb.reserved.cnt; i++) {
 		unsigned long physbase = lmb.reserved.region[i].physbase;
 		unsigned long size = lmb.reserved.region[i].size;
-#if 0 /* PPPBBB */
-		if ( (physbase == 0) && (size < (16<<20)) ) {
-			size = 16 << 20;
-		}
-#endif
+
 		reserve_bootmem(physbase, size);
 	}
-
-	PPCDBG(PPCDBG_MMINIT, "do_init_bootmem: end\n");
 }
 
 /*
@@ -522,7 +488,7 @@
 	/*
 	 * All pages are DMA-able so we put them all in the DMA zone.
 	 */
-	zones_size[0] = lmb_end_of_DRAM() >> PAGE_SHIFT;
+	zones_size[ZONE_DMA] = lmb_end_of_DRAM() >> PAGE_SHIFT;
 	for (i = 1; i < MAX_NR_ZONES; i++)
 		zones_size[i] = 0;
 	free_area_init(zones_size);
@@ -554,14 +520,6 @@
 
 	totalram_pages += free_all_bootmem();
 
-	ifppcdebug(PPCDBG_MMINIT) {
-		udbg_printf("mem_init: totalram_pages = 0x%lx\n", totalram_pages);
-		udbg_printf("mem_init: va_rtas_base   = 0x%lx\n", va_rtas_base); 
-		udbg_printf("mem_init: va_rtas_end    = 0x%lx\n", PAGE_ALIGN(va_rtas_base+rtas.size)); 
-		udbg_printf("mem_init: pinned start   = 0x%lx\n", __va(0)); 
-		udbg_printf("mem_init: pinned end     = 0x%lx\n", PAGE_ALIGN(klimit)); 
-	}
-
 	if ( sysmap_size )
 		for (addr = (unsigned long)sysmap;
 		     addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ;
@@ -582,7 +540,7 @@
 			datapages++;
 	}
 
-        printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08lx,%08lx]\n",
+	printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08lx,%08lx]\n",
 	       (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10),
 	       codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
 	       initpages<< (PAGE_SHIFT-10),
@@ -613,6 +571,12 @@
 
 void flush_icache_page(struct vm_area_struct *vma, struct page *page)
 {
+	if (cpu_has_noexecute())
+		return;
+
+	if ((vma->vm_flags & VM_EXEC) == 0)
+		return;
+
 	if (page->mapping && !PageReserved(page)
 	    && !test_bit(PG_arch_1, &page->flags)) {
 		__flush_dcache_icache(page_address(page));
@@ -620,15 +584,35 @@
 	}
 }
 
-void clear_user_page(void *page, unsigned long vaddr)
+void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
 {
 	clear_page(page);
+
+	/* XXX we shouldnt have to do this, but glibc requires it */
+	if (cpu_has_noexecute())
+		clear_bit(PG_arch_1, &pg->flags);
+	else
+		__flush_dcache_icache(page);
 }
 
-void copy_user_page(void *vto, void *vfrom, unsigned long vaddr)
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+		    struct page *pg)
 {
 	copy_page(vto, vfrom);
-	__flush_dcache_icache(vto);
+
+	/*
+	 * Unfortunately we havent always marked our GOT and PLT sections
+	 * as executable, so we need to flush all file regions - Anton
+	 */
+#if 0
+	if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0))
+		return;
+#endif
+
+	if (cpu_has_noexecute())
+		clear_bit(PG_arch_1, &pg->flags);
+	else
+		__flush_dcache_icache(vto);
 }
 
 void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
@@ -642,7 +626,7 @@
 
 extern pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea);
 int __hash_page(unsigned long ea, unsigned long access, unsigned long vsid,
-		pte_t *ptep);
+		pte_t *ptep, unsigned long trap);
 
 /*
  * This is called at the end of handling a user page fault, when the
@@ -670,5 +654,6 @@
 	ptep = find_linux_pte(pgdir, ea);
 	vsid = get_vsid(vma->vm_mm->context, ea);
 
-	__hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep);
+	__hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep,
+		    0x300);
 }
diff -Nru a/arch/ppc64/vmlinux.lds b/arch/ppc64/vmlinux.lds
--- a/arch/ppc64/vmlinux.lds	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/vmlinux.lds	Wed Jul 24 14:03:36 2002
@@ -1,4 +1,4 @@
-OUTPUT_ARCH(powerpc)
+OUTPUT_ARCH(powerpc:common64)
 SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
 /* Do we need any of these for elf?
    __DYNAMIC = 0;    */
@@ -116,19 +116,6 @@
   __per_cpu_end = .;
   . = ALIGN(4096);
   __init_end = .;
-
-  __chrp_begin = .;
-  .text.chrp : { *(.text.chrp) }
-  .data.chrp : { *(.data.chrp) }
-  . = ALIGN(4096);
-  __chrp_end = .;
-
-  . = ALIGN(4096);
-  __openfirmware_begin = .;
-  .text.openfirmware : { *(.text.openfirmware) }
-  .data.openfirmware : { *(.data.openfirmware) }
-  . = ALIGN(4096);
-  __openfirmware_end = .;
 
   __toc_start = .;
   .toc       :
diff -Nru a/arch/ppc64/xmon/privinst.h b/arch/ppc64/xmon/privinst.h
--- a/arch/ppc64/xmon/privinst.h	Wed Jul 24 14:03:36 2002
+++ b/arch/ppc64/xmon/privinst.h	Wed Jul 24 14:03:36 2002
@@ -6,7 +6,6 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  */
-#include <linux/config.h>
 
 #define GETREG(reg)		\
     static inline unsigned long get_ ## reg (void)	\
diff -Nru a/arch/ppc64/xmon/start.c b/arch/ppc64/xmon/start.c
--- a/arch/ppc64/xmon/start.c	Wed Jul 24 14:03:38 2002
+++ b/arch/ppc64/xmon/start.c	Wed Jul 24 14:03:38 2002
@@ -58,9 +58,9 @@
 }
 static struct sysrq_key_op sysrq_xmon_op = 
 {
-	handler:	sysrq_handle_xmon,
-	help_msg:	"xmon",
-	action_msg:	"Entering xmon\n",
+	.handler =	sysrq_handle_xmon,
+	.help_msg =	"xmon",
+	.action_msg =	"Entering xmon\n",
 };
 
 void
diff -Nru a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c
--- a/arch/ppc64/xmon/xmon.c	Wed Jul 24 14:03:37 2002
+++ b/arch/ppc64/xmon/xmon.c	Wed Jul 24 14:03:37 2002
@@ -14,6 +14,7 @@
 #include <linux/smp.h>
 #include <linux/mm.h>
 #include <linux/reboot.h>
+#include <linux/delay.h>
 #include <asm/ptrace.h>
 #include <asm/string.h>
 #include <asm/prom.h>
@@ -123,11 +124,7 @@
 static void mem_check(void);
 static void mem_find_real(void);
 static void mem_find_vsid(void);
-static void mem_check_pagetable_vsids (void);
 
-static void mem_map_check_slab(void);
-static void mem_map_lock_pages(void);
-static void mem_check_dup_rpn (void);
 static void debug_trace(void);
 
 extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned long);
@@ -189,13 +186,6 @@
 	asm volatile("sync; isync");
 }
 
-extern inline void __delay(unsigned int loops)
-{
-	if (loops != 0)
-		__asm__ __volatile__("mtctr %0; 1: bdnz 1b" : :
-				     "r" (loops) : "ctr");
-}
-
 /* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
  A PPC stack frame looks like this:
 
@@ -440,11 +430,11 @@
 xmon_irq(int irq, void *d, struct pt_regs *regs)
 {
 	unsigned long flags;
-	__save_flags(flags);
-	__cli();
+	local_save_flags(flags);
+	local_irq_disable();
 	printf("Keyboard interrupt\n");
 	xmon(regs);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 int
@@ -552,7 +542,7 @@
 		}
 	}
 
-	if (!__is_processor(PV_POWER4)) {
+	if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) {
 		if (dabr.enabled)
 			set_dabr(dabr.address);
 		if (iabr.enabled)
@@ -569,7 +559,7 @@
 
 	if (naca->platform != PLATFORM_PSERIES)
 		return;
-	if (!__is_processor(PV_POWER4)) {
+	if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) {
 		set_dabr(0);
 		set_iabr(0);
 	}
@@ -642,27 +632,15 @@
 			case 'c':
 				mem_check();
 				break;
-			case 'j':
-				mem_map_check_slab();
-				break;
 			case 'f':
 				mem_find_real();
 				break;
 			case 'e':
 				mem_find_vsid();
 				break;
-			case 'r':
-				mem_check_dup_rpn();
-				break;           
 			case 'i':
 				show_mem();
 				break;
-			case 'o':
-				mem_check_pagetable_vsids ();
-				break;
-			case 'q':
-				mem_map_lock_pages() ;
-				break;
 			default:
 				termch = cmd;
 				memex();
@@ -866,7 +844,7 @@
 	cmd = inchar();
 	switch (cmd) {
 	case 'd':	/* bd - hardware data breakpoint */
-		if (__is_processor(PV_POWER4)) {
+		if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
 			printf("Not implemented on POWER4\n");
 			break;
 		}
@@ -886,7 +864,7 @@
 			dabr.address = (dabr.address & ~7) | mode;
 		break;
 	case 'i':	/* bi - hardware instr breakpoint */
-		if (__is_processor(PV_POWER4)) {
+		if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
 			printf("Not implemented on POWER4\n");
 			break;
 		}
@@ -2456,249 +2434,6 @@
 		}
 	}
 	printf("\nDone -------------------\n");
-}
-
-void mem_map_check_slab()
-{
-	int i, slab_count;
-
-	i = max_mapnr;
-	slab_count = 0;
-	
-	while (i-- > 0)  {
-		if (PageSlab(mem_map+i)){
-			printf(" slab entry - mem_map entry =%p  \n", mem_map+i);
-			slab_count ++;
-		}
-	}
-
-	printf(" count of pages for slab = %d \n", slab_count);
-}
-
-void mem_map_lock_pages()
-{
-	int i, lock_count;
-
-	i = max_mapnr;
-	lock_count = 0;
-	
-	while (i-- > 0)  {
-		if (PageLocked(mem_map+i)){
-			printf(" locked entry - mem_map entry =%p  \n", mem_map+i);
-			lock_count ++;
-		}
-	}
-
-	printf(" count of locked pages = %d \n", lock_count); 
-}
-
-void mem_check_dup_rpn ()
-{
-	unsigned long htab_size_bytes;
-	unsigned long htab_end;
-	unsigned long last_rpn;
-	HPTE *hpte1, *hpte2;
-	int dup_count;
-	struct task_struct *p;
-	unsigned long kernel_vsid_c0,kernel_vsid_c1,kernel_vsid_c2,kernel_vsid_c3;
-	unsigned long kernel_vsid_c4,kernel_vsid_c5,kernel_vsid_d,kernel_vsid_e;
-	unsigned long kernel_vsid_f;
-	unsigned long vsid0,vsid1,vsidB,vsid2;
-
-	htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
-	htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
-	// last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
-	last_rpn = 0xfffff;
-
-	printf("\nHardware Page Table Check\n-------------------\n");
-	printf("htab base      : %.16lx\n", htab_data.htab);
-	printf("htab size      : %.16lx\n", htab_size_bytes);
-
-
-	for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
-		if ( hpte1->dw0.dw0.v != 0 ) {
-			if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
-				dup_count = 0;
-				for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
-					if ( hpte2->dw0.dw0.v != 0 ) {
-						if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
-							dup_count++;
-						}
-					}
-				}
-				if(dup_count > 5) {
-					printf(" Duplicate rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
-					printf("    mem map array entry %p count = %d \n",
-					       (mem_map+(hpte1->dw1.dw1.rpn)), (mem_map+(hpte1->dw1.dw1.rpn))->count);
-					for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
-						if ( hpte2->dw0.dw0.v != 0 ) {
-							if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
-								printf("   hpte2: %16.16lx  *hpte2: %16.16lx %16.16lx\n",
-								       hpte2, hpte2->dw0.dword0, hpte2->dw1.dword1);
-							}
-						}
-					}
-				}
-			} else {
-				printf(" Bogus rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
-				printf("   hpte: %16.16lx  *hpte: %16.16lx %16.16lx\n",
-				       hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
-			}
-		}
-		if (xmon_interrupted())
-			return;
-	}                                                                     
-
-
-
-	// print the kernel vsids
-	kernel_vsid_c0 =  get_kernel_vsid(0xC000000000000000);
-	kernel_vsid_c1 =  get_kernel_vsid(0xC000000010000000);
-	kernel_vsid_c2 =  get_kernel_vsid(0xC000000020000000);
-	kernel_vsid_c3 =  get_kernel_vsid(0xC000000030000000);
-	kernel_vsid_c4 =  get_kernel_vsid(0xC000000040000000);
-	kernel_vsid_c5 =  get_kernel_vsid(0xC000000050000000);
-	kernel_vsid_d  =  get_kernel_vsid(0xD000000000000000);
-	kernel_vsid_e  =  get_kernel_vsid(0xE000000000000000);
-	kernel_vsid_f  =  get_kernel_vsid(0xF000000000000000);
-
-	printf(" kernel vsid -  seg c0  = %lx\n",  kernel_vsid_c0 );
-	printf(" kernel vsid -  seg c1  = %lx\n",  kernel_vsid_c1 );
-	printf(" kernel vsid -  seg c2  = %lx\n",  kernel_vsid_c2 );
-	printf(" kernel vsid -  seg c3  = %lx\n",  kernel_vsid_c3 );
-	printf(" kernel vsid -  seg c4  = %lx\n",  kernel_vsid_c4 );
-	printf(" kernel vsid -  seg c5  = %lx\n",  kernel_vsid_c5 );
-	printf(" kernel vsid -  seg d   = %lx\n",  kernel_vsid_d );
-	printf(" kernel vsid -  seg e   = %lx\n",  kernel_vsid_e );
-	printf(" kernel vsid -  seg f   = %lx\n",  kernel_vsid_f );
-
-
-  // print a list of valid vsids for the tasks
-	read_lock(&tasklist_lock);
-	for_each_task(p)
-		if(p->mm) {
-			struct mm_struct *mm = p->mm; 
-			printf(" task = %p  mm =  %lx  pgd   %lx\n", 
-			       p, mm, mm->pgd);
-			vsid0 = get_vsid( mm->context, 0 );
-			vsid1 = get_vsid( mm->context, 0x10000000 );
-			vsid2 = get_vsid( mm->context, 0x20000000 );
-			vsidB = get_vsid( mm->context, 0xB0000000 );
-			printf("            context = %lx  vsid seg 0  = %lx\n",  mm->context, vsid0 );
-			printf("                           vsid seg 1  = %lx\n",  vsid1 );
-			printf("                           vsid seg 2  = %lx\n",  vsid2 );
-			printf("                           vsid seg 2  = %lx\n",  vsidB );
-	  
-			printf("\n");
-		};
-	read_unlock(&tasklist_lock);
-
-	printf("\nDone -------------------\n");
-}
-
-
-
-void mem_check_pagetable_vsids ()
-{
-	unsigned long htab_size_bytes;
-	unsigned long htab_end;
-	unsigned long last_rpn;
-	struct task_struct *p;
-	unsigned long valid_table_count,invalid_table_count,bogus_rpn_count;
-	int found;
-	unsigned long user_address_table_count,kernel_page_table_count;
-	unsigned long pt_vsid;
-	HPTE *hpte1;
-
-
-	htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
-	htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
-	// last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
-	last_rpn = 0xfffff;
-
-	printf("\nHardware Page Table Check\n-------------------\n");
-	printf("htab base      : %.16lx\n", htab_data.htab);
-	printf("htab size      : %.16lx\n", htab_size_bytes);
-
-	valid_table_count = 0;
-	invalid_table_count = 0;
-	bogus_rpn_count = 0;
-	user_address_table_count = 0;
-	kernel_page_table_count = 0;
-	for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
-		if ( hpte1->dw0.dw0.v != 0 ) {
-			valid_table_count++;
-			if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
-				pt_vsid =  (hpte1->dw0.dw0.avpn) >> 5;
-				if ((pt_vsid == get_kernel_vsid(0xC000000000000000)) |
-				    (pt_vsid == get_kernel_vsid(0xC000000010000000)) |
-				    (pt_vsid == get_kernel_vsid(0xC000000020000000)) |
-				    (pt_vsid == get_kernel_vsid(0xC000000030000000)) |
-				    (pt_vsid == get_kernel_vsid(0xC000000040000000)) |
-				    (pt_vsid == get_kernel_vsid(0xC000000050000000)) |
-				    (pt_vsid == get_kernel_vsid(0xD000000000000000)) |
-				    (pt_vsid == get_kernel_vsid(0xE000000000000000)) |
-				    (pt_vsid == get_kernel_vsid(0xF000000000000000)) ) {
-					kernel_page_table_count ++;
-				} else {
-					read_lock(&tasklist_lock);
-					found = 0;
-					for_each_task(p) {
-						if(p->mm && (found == 0)) {
-							struct mm_struct *mm = p->mm; 
-	     
-							if ((pt_vsid == get_vsid( mm->context, 0 )) |
-							    (pt_vsid == get_vsid( mm->context, 0x10000000 )) |
-							    (pt_vsid == get_vsid( mm->context, 0x20000000 )) |
-							    (pt_vsid == get_vsid( mm->context, 0x30000000 )) |
-							    (pt_vsid == get_vsid( mm->context, 0x40000000 )) |
-							    (pt_vsid == get_vsid( mm->context, 0x50000000 )) |
-							    (pt_vsid == get_vsid( mm->context, 0x60000000 )) |
-							    (pt_vsid == get_vsid( mm->context, 0x70000000 )) |
-							    (pt_vsid == get_vsid( mm->context, 0x80000000 )) |
-							    (pt_vsid == get_vsid( mm->context, 0x90000000 )) |
-							    (pt_vsid == get_vsid( mm->context, 0xA0000000 )) |
-							    (pt_vsid == get_vsid( mm->context, 0xB0000000 ))) {
-								user_address_table_count ++;
-								found = 1;
-							}
-						}
-					}
-					read_unlock(&tasklist_lock);
-					if (found == 0)
-					{
-						printf(" vsid not found vsid = %lx, hpte = %p  \n", 
-						       pt_vsid,hpte1);
-						printf("    rpn in entry = %lx \n", hpte1->dw1.dw1.rpn);
-						printf("    mem map address = %lx  \n", mem_map + (hpte1->dw1.dw1.rpn));
-           
-					} else //  found
-					{
-					}
-
-				}  // good rpn
-       
-			} else {
-				bogus_rpn_count ++;
-			}
-		} else {
-			invalid_table_count++;
-		}
-	}                                                                     
-
-
-	printf(" page table valid counts - valid entries = %lx  invalid entries =  %lx \n",
-	       valid_table_count, invalid_table_count);
-
-	printf("  bogus rpn entries ( probably io) = %lx \n", bogus_rpn_count);
-
- 
-  
-	printf(" page table counts - kernel entries = %lx  user entries =  %lx \n",
-	       kernel_page_table_count, user_address_table_count); 
-
-	printf("\nDone -------------------\n");
-
 }
 
 static void debug_trace(void) {
diff -Nru a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
--- a/arch/s390/kernel/irq.c	Wed Jul 24 14:03:38 2002
+++ b/arch/s390/kernel/irq.c	Wed Jul 24 14:03:38 2002
@@ -161,9 +161,9 @@
 				show("wait_on_irq");
 				count = ~0;
 			}
-			__sti();
+			local_irq_enable();
 			SYNC_OTHER_CORES(cpu);
-			__cli();
+			local_irq_disable();
 			check_smp_invalidate(cpu);
 			if (atomic_read(&global_irq_count))
 				continue;
@@ -249,10 +249,10 @@
 {
 	unsigned long flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	if (flags & (1 << EFLAGS_I_SHIFT)) {
 		int cpu = smp_processor_id();
-		__cli();
+		local_irq_disable();
 		if (!in_irq())
 			get_irqlock(cpu);
 	}
@@ -263,7 +263,7 @@
 
 	if (!in_irq())
 		release_irqlock(smp_processor_id());
-	__sti();
+	local_irq_enable();
 }
 
 /*
@@ -279,7 +279,7 @@
 	int local_enabled;
 	unsigned long flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	local_enabled = (flags >> EFLAGS_I_SHIFT) & 1;
 	/* default to local */
 	retval = 2 + local_enabled;
@@ -305,10 +305,10 @@
 		__global_sti();
 		break;
 	case 2:
-		__cli();
+		local_irq_disable();
 		break;
 	case 3:
-		__sti();
+		local_irq_enable();
 		break;
 	default:
 		printk("global_restore_flags: %08lx (%08lx)\n",
diff -Nru a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
--- a/arch/s390/kernel/setup.c	Wed Jul 24 14:03:36 2002
+++ b/arch/s390/kernel/setup.c	Wed Jul 24 14:03:36 2002
@@ -86,7 +86,7 @@
 
         if (test_and_set_bit(nr,&cpu_initialized)) {
                 printk("CPU#%d ALREADY INITIALIZED!!!!!!!!!\n", nr);
-                for (;;) __sti();
+                for (;;) local_irq_enable();
         }
         cpus_initialized++;
 
diff -Nru a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
--- a/arch/s390/kernel/traps.c	Wed Jul 24 14:03:37 2002
+++ b/arch/s390/kernel/traps.c	Wed Jul 24 14:03:37 2002
@@ -280,7 +280,7 @@
 	 * now safely switch on interrupts.
 	 */
         if (regs->psw.mask & PSW_PROBLEM_STATE)
-		__sti();
+		local_irq_enable();
 
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
                 struct task_struct *tsk = current;
@@ -416,7 +416,7 @@
 	 * now safely switch on interrupts.
 	 */
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
-		__sti();
+		local_irq_enable();
 
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
 		get_user(*((__u16 *) opcode), location);
@@ -477,7 +477,7 @@
 	 * now safely switch on interrupts.
 	 */
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
-		__sti();
+		local_irq_enable();
 		
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
 		get_user(*((__u16 *) opcode), location);
@@ -540,7 +540,7 @@
 	 * now safely switch on interrupts.
 	 */
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
-		__sti();
+		local_irq_enable();
 
 	if (MACHINE_HAS_IEEE)
 		__asm__ volatile ("stfpc %0\n\t" 
diff -Nru a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
--- a/arch/s390/mm/fault.c	Wed Jul 24 14:03:39 2002
+++ b/arch/s390/mm/fault.c	Wed Jul 24 14:03:39 2002
@@ -199,7 +199,7 @@
 	 * task's user address space, so we can switch on the
 	 * interrupts again and then search the VMAs
 	 */
-	__sti();
+	local_irq_enable();
 
         down_read(&mm->mmap_sem);
 
@@ -528,7 +528,7 @@
 	 * now safely switch on interrupts.
 	 */
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
-		__sti();
+		local_irq_enable();
 
 	if (subcode & 0x0080) {
 		/* signal bit is set -> a page has been swapped in by VM */
diff -Nru a/arch/s390x/kernel/irq.c b/arch/s390x/kernel/irq.c
--- a/arch/s390x/kernel/irq.c	Wed Jul 24 14:03:39 2002
+++ b/arch/s390x/kernel/irq.c	Wed Jul 24 14:03:39 2002
@@ -162,9 +162,9 @@
 				show("wait_on_irq");
 				count = ~0;
 			}
-			__sti();
+			local_irq_enable();
 			SYNC_OTHER_CORES(cpu);
-			__cli();
+			local_irq_disable();
 			check_smp_invalidate(cpu);
 			if (atomic_read(&global_irq_count))
 				continue;
@@ -250,10 +250,10 @@
 {
 	unsigned long flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	if (flags & (1UL << EFLAGS_I_SHIFT)) {
 		int cpu = smp_processor_id();
-		__cli();
+		local_irq_disable();
 		if (!in_irq())
 			get_irqlock(cpu);
 	}
@@ -264,7 +264,7 @@
 
 	if (!in_irq())
 		release_irqlock(smp_processor_id());
-	__sti();
+	local_irq_enable();
 }
 
 /*
@@ -280,7 +280,7 @@
 	int local_enabled;
 	unsigned long flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	local_enabled = (flags >> EFLAGS_I_SHIFT) & 1;
 	/* default to local */
 	retval = 2 + local_enabled;
@@ -306,10 +306,10 @@
 		__global_sti();
 		break;
 	case 2:
-		__cli();
+		local_irq_disable();
 		break;
 	case 3:
-		__sti();
+		local_irq_enable();
 		break;
 	default:
 		printk("global_restore_flags: %08lx (%08lx)\n",
diff -Nru a/arch/s390x/kernel/setup.c b/arch/s390x/kernel/setup.c
--- a/arch/s390x/kernel/setup.c	Wed Jul 24 14:03:37 2002
+++ b/arch/s390x/kernel/setup.c	Wed Jul 24 14:03:37 2002
@@ -86,7 +86,7 @@
 
         if (test_and_set_bit(nr,&cpu_initialized)) {
                 printk("CPU#%d ALREADY INITIALIZED!!!!!!!!!\n", nr);
-                for (;;) __sti();
+                for (;;) local_irq_enable();
         }
         cpus_initialized++;
 
diff -Nru a/arch/s390x/kernel/traps.c b/arch/s390x/kernel/traps.c
--- a/arch/s390x/kernel/traps.c	Wed Jul 24 14:03:39 2002
+++ b/arch/s390x/kernel/traps.c	Wed Jul 24 14:03:39 2002
@@ -282,7 +282,7 @@
 	 * now safely switch on interrupts.
 	 */
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
-		__sti();
+		local_irq_enable();
 
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
                 struct task_struct *tsk = current;
@@ -419,7 +419,7 @@
 	 * now safely switch on interrupts.
 	 */
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
-		__sti();
+		local_irq_enable();
 
 	/* WARNING don't change this check back to */
 	/* int problem_state=(regs->psw.mask & PSW_PROBLEM_STATE); */
@@ -452,7 +452,7 @@
 	 * now safely switch on interrupts.
 	 */
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
-		__sti();
+		local_irq_enable();
 
 	__asm__ volatile ("stfpc %0\n\t" 
 			  : "=m" (current->thread.fp_regs.fpc));
diff -Nru a/arch/s390x/mm/fault.c b/arch/s390x/mm/fault.c
--- a/arch/s390x/mm/fault.c	Wed Jul 24 14:03:37 2002
+++ b/arch/s390x/mm/fault.c	Wed Jul 24 14:03:37 2002
@@ -199,7 +199,7 @@
 	 * task's user address space, so we can switch on the
 	 * interrupts again and then search the VMAs
 	 */
-	__sti();
+	local_irq_enable();
 
         down_read(&mm->mmap_sem);
 
@@ -440,7 +440,7 @@
 	 * now safely switch on interrupts.
 	 */
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
-		__sti();
+		local_irq_enable();
 
 	if (subcode & 0x0080) {
 		/* signal bit is set -> a page has been swapped in by VM */
diff -Nru a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
--- a/arch/sh/kernel/irq.c	Wed Jul 24 14:03:37 2002
+++ b/arch/sh/kernel/irq.c	Wed Jul 24 14:03:37 2002
@@ -130,7 +130,7 @@
 	status = 1;	/* Force the "do bottom halves" bit */
 
 	if (!(action->flags & SA_INTERRUPT))
-		__sti();
+		local_irq_enable();
 
 	do {
 		status |= action->flags;
@@ -139,7 +139,7 @@
 	} while (action);
 	if (status & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	__cli();
+	local_irq_disable();
 
 	irq_exit(cpu, irq);
 
diff -Nru a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
--- a/arch/sh/kernel/process.c	Wed Jul 24 14:03:39 2002
+++ b/arch/sh/kernel/process.c	Wed Jul 24 14:03:39 2002
@@ -46,13 +46,13 @@
 			if (need_resched())
 				break;
 		} else {
-			__cli();
+			local_irq_disable();
 			while (!need_resched()) {
-				__sti();
+				local_irq_enable();
 				asm volatile("sleep" : : : "memory");
-				__cli();
+				local_irq_disable();
 			}
-			__sti();
+			local_irq_enable();
 		}
 		schedule();
 		check_pgt_cache();
diff -Nru a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
--- a/arch/sparc/kernel/irq.c	Wed Jul 24 14:03:35 2002
+++ b/arch/sparc/kernel/irq.c	Wed Jul 24 14:03:35 2002
@@ -231,7 +231,7 @@
 
 
 /*
- * We have to allow irqs to arrive between __sti and __cli
+ * We have to allow irqs to arrive between local_irq_enable and local_irq_disable
  */
 #define SYNC_OTHER_CORES(x) barrier()
 
@@ -276,9 +276,9 @@
 				show("get_irqlock");
 				count = (~0 >> 1);
 			}
-			__sti();
+			local_irq_enable();
 			SYNC_OTHER_CORES(cpu);
-			__cli();
+			local_irq_disable();
 		}
 		goto again;
 	}
@@ -302,11 +302,11 @@
 {
 	unsigned long flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 
 	if ((flags & PSR_PIL) != PSR_PIL) {
 		int cpu = smp_processor_id();
-		__cli();
+		local_irq_disable();
 		if (!local_irq_count(cpu))
 			get_irqlock(cpu);
 	}
@@ -318,7 +318,7 @@
 
 	if (!local_irq_count(cpu))
 		release_irqlock(cpu);
-	__sti();
+	local_irq_enable();
 }
 
 /*
@@ -333,7 +333,7 @@
 	unsigned long flags, retval;
 	unsigned long local_enabled = 0;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 
 	if ((flags & PSR_PIL) != PSR_PIL)
 		local_enabled = 1;
@@ -361,10 +361,10 @@
 		__global_sti();
 		break;
 	case 2:
-		__cli();
+		local_irq_disable();
 		break;
 	case 3:
-		__sti();
+		local_irq_enable();
 		break;
 	default:
 	{
diff -Nru a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
--- a/arch/sparc/kernel/pcic.c	Wed Jul 24 14:03:35 2002
+++ b/arch/sparc/kernel/pcic.c	Wed Jul 24 14:03:35 2002
@@ -780,7 +780,7 @@
 		prom_printf("time_init: unable to attach IRQ%d\n", timer_irq);
 		prom_halt();
 	}
-	__sti();
+	local_irq_enable();
 }
 
 static __inline__ unsigned long do_gettimeoffset(void)
diff -Nru a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
--- a/arch/sparc/kernel/smp.c	Wed Jul 24 14:03:37 2002
+++ b/arch/sparc/kernel/smp.c	Wed Jul 24 14:03:37 2002
@@ -253,7 +253,7 @@
 /* Stopping processors. */
 void smp_stop_cpu_irq(void)
 {
-	__sti();
+	local_irq_enable();
 	while(1)
 		barrier();
 }
diff -Nru a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
--- a/arch/sparc/kernel/sun4d_irq.c	Wed Jul 24 14:03:35 2002
+++ b/arch/sparc/kernel/sun4d_irq.c	Wed Jul 24 14:03:35 2002
@@ -488,14 +488,14 @@
 		 * has copied the firmwares level 14 vector into boot cpu's
 		 * trap table, we must fix this now or we get squashed.
 		 */
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
 		trap_table->inst_one = lvl14_save[0];
 		trap_table->inst_two = lvl14_save[1];
 		trap_table->inst_three = lvl14_save[2];
 		trap_table->inst_four = lvl14_save[3];
 		local_flush_cache_all();
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 #endif
 }
@@ -539,7 +539,7 @@
 
 void __init sun4d_init_IRQ(void)
 {
-	__cli();
+	local_irq_disable();
 
 	BTFIXUPSET_CALL(enable_irq, sun4d_enable_irq, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(disable_irq, sun4d_disable_irq, BTFIXUPCALL_NORM);
diff -Nru a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
--- a/arch/sparc/kernel/sun4d_smp.c	Wed Jul 24 14:03:36 2002
+++ b/arch/sparc/kernel/sun4d_smp.c	Wed Jul 24 14:03:36 2002
@@ -144,7 +144,7 @@
 	local_flush_cache_all();
 	local_flush_tlb_all();
 	
-	__sti();	/* We don't allow PIL 14 yet */
+	local_irq_enable();	/* We don't allow PIL 14 yet */
 	
 	while(!smp_commenced)
 		barrier();
@@ -182,7 +182,7 @@
 	if (boot_cpu_id)
 		current_set[0] = NULL;
 
-	__sti();
+	local_irq_enable();
 	cpu_present_map = 0;
 	for(i=0; i < linux_num_cpus; i++)
 		cpu_present_map |= (1<<linux_cpus[i].mid);
diff -Nru a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
--- a/arch/sparc/kernel/sun4m_irq.c	Wed Jul 24 14:03:38 2002
+++ b/arch/sparc/kernel/sun4m_irq.c	Wed Jul 24 14:03:38 2002
@@ -297,13 +297,13 @@
 		 * has copied the firmwares level 14 vector into boot cpu's
 		 * trap table, we must fix this now or we get squashed.
 		 */
-		__save_and_cli(flags);
+		local_irq_save(flags);
 		trap_table->inst_one = lvl14_save[0];
 		trap_table->inst_two = lvl14_save[1];
 		trap_table->inst_three = lvl14_save[2];
 		trap_table->inst_four = lvl14_save[3];
 		local_flush_cache_all();
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 #endif
 }
@@ -315,7 +315,7 @@
 	int num_regs;
 	struct resource r;
     
-	__cli();
+	local_irq_disable();
 	if((ie_node = prom_searchsiblings(prom_getchild(prom_root_node), "obio")) == 0 ||
 	   (ie_node = prom_getchild (ie_node)) == 0 ||
 	   (ie_node = prom_searchsiblings (ie_node, "interrupt")) == 0) {
diff -Nru a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
--- a/arch/sparc/kernel/sun4m_smp.c	Wed Jul 24 14:03:37 2002
+++ b/arch/sparc/kernel/sun4m_smp.c	Wed Jul 24 14:03:37 2002
@@ -127,7 +127,7 @@
 	local_flush_cache_all();
 	local_flush_tlb_all();
 
-	__sti();
+	local_irq_enable();
 }
 
 extern int cpu_idle(void *unused);
@@ -153,7 +153,7 @@
 
 	printk("Entering SMP Mode...\n");
 
-	__sti();
+	local_irq_enable();
 	cpu_present_map = 0;
 
 	for(i=0; i < linux_num_cpus; i++)
diff -Nru a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
--- a/arch/sparc/kernel/time.c	Wed Jul 24 14:03:38 2002
+++ b/arch/sparc/kernel/time.c	Wed Jul 24 14:03:38 2002
@@ -437,7 +437,7 @@
 #endif
 
 	/* Now that OBP ticker has been silenced, it is safe to enable IRQ. */
-	__sti();
+	local_irq_enable();
 }
 
 void __init time_init(void)
diff -Nru a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
--- a/arch/sparc/mm/srmmu.c	Wed Jul 24 14:03:35 2002
+++ b/arch/sparc/mm/srmmu.c	Wed Jul 24 14:03:35 2002
@@ -657,7 +657,7 @@
 
 	FLUSH_BEGIN(mm)
 	flush_user_windows();
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	octx = srmmu_get_context();
 	srmmu_set_context(mm->context);
 	a = 0x20; b = 0x40; c = 0x60;
@@ -681,7 +681,7 @@
 				     "r" (e), "r" (f), "r" (g));
 	} while(faddr);
 	srmmu_set_context(octx);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	FLUSH_END
 }
 
@@ -694,7 +694,7 @@
 
 	FLUSH_BEGIN(mm)
 	flush_user_windows();
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	octx = srmmu_get_context();
 	srmmu_set_context(mm->context);
 	a = 0x20; b = 0x40; c = 0x60;
@@ -723,7 +723,7 @@
 		start += SRMMU_PMD_SIZE;
 	}
 	srmmu_set_context(octx);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	FLUSH_END
 }
 
@@ -736,7 +736,7 @@
 
 	FLUSH_BEGIN(mm)
 	flush_user_windows();
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	octx = srmmu_get_context();
 	srmmu_set_context(mm->context);
 	a = 0x20; b = 0x40; c = 0x60;
@@ -762,7 +762,7 @@
 					     "r" (e), "r" (f), "r" (g));
 	} while(line != page);
 	srmmu_set_context(octx);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	FLUSH_END
 }
 
diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
--- a/arch/sparc64/kernel/irq.c	Wed Jul 24 14:03:37 2002
+++ b/arch/sparc64/kernel/irq.c	Wed Jul 24 14:03:37 2002
@@ -634,9 +634,9 @@
 				show("get_irqlock");
 				count = (~0 >> 1);
 			}
-			__sti();
+			local_irq_enable();
 			SYNC_OTHER_ULTRAS(cpu);
-			__cli();
+			local_irq_disable();
 		}
 		goto again;
 	}
@@ -648,10 +648,10 @@
 {
 	unsigned long flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	if(flags == 0) {
 		int cpu = smp_processor_id();
-		__cli();
+		local_irq_disable();
 		if (! local_irq_count(cpu))
 			get_irqlock(cpu);
 	}
@@ -663,14 +663,14 @@
 
 	if (! local_irq_count(cpu))
 		release_irqlock(cpu);
-	__sti();
+	local_irq_enable();
 }
 
 unsigned long __global_save_flags(void)
 {
 	unsigned long flags, local_enabled, retval;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	local_enabled = ((flags == 0) ? 1 : 0);
 	retval = 2 + local_enabled;
 	if (! local_irq_count(smp_processor_id())) {
@@ -692,10 +692,10 @@
 		__global_sti();
 		break;
 	case 2:
-		__cli();
+		local_irq_disable();
 		break;
 	case 3:
-		__sti();
+		local_irq_enable();
 		break;
 	default:
 	{
diff -Nru a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
--- a/arch/sparc64/kernel/smp.c	Wed Jul 24 14:03:35 2002
+++ b/arch/sparc64/kernel/smp.c	Wed Jul 24 14:03:35 2002
@@ -199,7 +199,7 @@
 
 	smp_setup_percpu_timer();
 
-	__sti();
+	local_irq_enable();
 
 	calibrate_delay();
 	smp_store_cpu_info(cpuid);
@@ -243,7 +243,7 @@
 	int cpucount = 0, i;
 
 	printk("Entering UltraSMPenguin Mode...\n");
-	__sti();
+	local_irq_enable();
 	smp_store_cpu_info(boot_cpu_id);
 
 	if (linux_num_cpus == 1) {
@@ -1222,7 +1222,7 @@
 		__get_free_pages(GFP_KERNEL, order = get_order(ecache_size));
 
 	if (flush_base != 0UL) {
-		__save_and_cli(flags);
+		local_irq_save(flags);
 
 		/* Scan twice the size once just to get the TLB entries
 		 * loaded and make sure the second scan measures pure misses.
@@ -1271,7 +1271,7 @@
 				     : "g1", "g2", "g3", "g5");
 		}
 
-		__restore_flags(flags);
+		local_irq_restore(flags);
 
 		raw = (tick2 - tick1);
 
diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c	Wed Jul 24 14:03:38 2002
+++ b/arch/sparc64/kernel/time.c	Wed Jul 24 14:03:38 2002
@@ -432,7 +432,7 @@
 		return;
 	}
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	cbus = central_bus;
 	if (cbus != NULL)
@@ -610,7 +610,7 @@
 
 	set_system_time();
 	
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 extern void init_timers(void (*func)(int, void *, struct pt_regs *),
diff -Nru a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
--- a/arch/sparc64/mm/init.c	Wed Jul 24 14:03:37 2002
+++ b/arch/sparc64/mm/init.c	Wed Jul 24 14:03:37 2002
@@ -1411,7 +1411,7 @@
 	 */
 	pt  = phys_base | _PAGE_VALID | _PAGE_SZ4MB;
 	pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W;
-	__save_and_cli(flags);
+	local_irq_save(flags);
 	if (tlb_type == spitfire) {
 		__asm__ __volatile__(
 	"	stxa	%1, [%0] %3\n"
@@ -1469,7 +1469,7 @@
 			: "memory");
 		}
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	
 	/* Now set kernel pgd to upper alias so physical page computations
 	 * work.
diff -Nru a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
--- a/arch/sparc64/prom/misc.c	Wed Jul 24 14:03:39 2002
+++ b/arch/sparc64/prom/misc.c	Wed Jul 24 14:03:39 2002
@@ -52,7 +52,7 @@
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 #ifdef CONFIG_SUN_CONSOLE
 	if(!serial_console && prom_palette)
@@ -75,7 +75,7 @@
 		prom_palette (0);
 #endif
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 #ifdef CONFIG_SMP
diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
--- a/arch/x86_64/kernel/apic.c	Wed Jul 24 14:03:36 2002
+++ b/arch/x86_64/kernel/apic.c	Wed Jul 24 14:03:36 2002
@@ -474,13 +474,13 @@
 	apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
 	apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
 	apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
-	__save_flags(flags);
-	__cli();
+	local_save_flags(flags);
+	local_irq_disable();
 	disable_local_APIC();
 	rdmsr(MSR_IA32_APICBASE, l, h);
 	l &= ~MSR_IA32_APICBASE_ENABLE;
 	wrmsr(MSR_IA32_APICBASE, l, h);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static void apic_pm_resume(void *data)
@@ -488,8 +488,8 @@
 	unsigned int l, h;
 	unsigned long flags;
 
-	__save_flags(flags);
-	__cli();
+	local_save_flags(flags);
+	local_irq_disable();
 	rdmsr(MSR_IA32_APICBASE, l, h);
 	l &= ~MSR_IA32_APICBASE_BASE;
 	l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
@@ -512,7 +512,7 @@
 	apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);
 	apic_write(APIC_ESR, 0);
 	apic_read(APIC_ESR);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	if (apic_pm_state.perfctr_pmdev)
 		pm_send(apic_pm_state.perfctr_pmdev, PM_RESUME, data);
 }
@@ -785,8 +785,8 @@
 	unsigned long flags;
 	int delta;
 
-	__save_flags(flags);
-	__sti();
+	local_save_flags(flags);
+	local_irq_enable();
 	/*
 	 * ok, Intel has some smart code in their APIC that knows
 	 * if a CPU was in 'hlt' lowpower mode, and this increases
@@ -825,7 +825,7 @@
 	printk("CPU%d<T0:%u,T1:%u,D:%d,S:%u,C:%u>\n",
 			smp_processor_id(), t0, t1, delta, slice, clocks);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
@@ -916,7 +916,7 @@
 	printk("Using local APIC timer interrupts.\n");
 	using_apic_timer = 1;
 
-	__cli();
+	local_irq_disable();
 
 	calibration_result = calibrate_APIC_clock();
 	/*
@@ -924,7 +924,7 @@
 	 */
 	setup_APIC_timer((void *)(u64)calibration_result);
 
-	__sti();
+	local_irq_enable();
 
 	/* and update all other cpus */
 	smp_call_function(setup_APIC_timer, (void *)(u64)calibration_result, 1, 1);
diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
--- a/arch/x86_64/kernel/irq.c	Wed Jul 24 14:03:38 2002
+++ b/arch/x86_64/kernel/irq.c	Wed Jul 24 14:03:38 2002
@@ -254,7 +254,7 @@
 # define SYNC_OTHER_CORES(x) udelay(x+1)
 #else
 /*
- * We have to allow irqs to arrive between __sti and __cli
+ * We have to allow irqs to arrive between local_irq_enable and local_irq_disable
  */
 # define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
 #endif
@@ -282,9 +282,9 @@
 				show("wait_on_irq");
 				count = ~0;
 			}
-			__sti();
+			local_irq_enable();
 			SYNC_OTHER_CORES(cpu);
-			__cli();
+			local_irq_disable();
 			if (irqs_running())
 				continue;
 			if (global_irq_lock)
@@ -356,10 +356,10 @@
 {
 	unsigned long flags;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	if (flags & (1 << EFLAGS_IF_SHIFT)) {
 		int cpu = smp_processor_id();
-		__cli();
+		local_irq_disable();
 		if (!local_irq_count(cpu))
 			get_irqlock(cpu);
 	}
@@ -371,7 +371,7 @@
 
 	if (!local_irq_count(cpu))
 		release_irqlock(cpu);
-	__sti();
+	local_irq_enable();
 }
 
 /*
@@ -388,7 +388,7 @@
 	unsigned long flags;
 	int cpu = smp_processor_id();
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
 	/* default to local */
 	retval = 2 + local_enabled;
@@ -413,10 +413,10 @@
 		__global_sti();
 		break;
 	case 2:
-		__cli();
+		local_irq_disable();
 		break;
 	case 3:
-		__sti();
+		local_irq_enable();
 		break;
 	default:
 		printk("global_restore_flags: %08lx (%08lx)\n",
@@ -442,7 +442,7 @@
 	status = 1;	/* Force the "do bottom halves" bit */
 
 	if (!(action->flags & SA_INTERRUPT))
-		__sti();
+		local_irq_enable();
 
 	do {
 		status |= action->flags;
@@ -451,7 +451,7 @@
 	} while (action);
 	if (status & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	__cli();
+	local_irq_disable();
 
 	irq_exit(0, irq);
 
diff -Nru a/arch/x86_64/kernel/ldt.c b/arch/x86_64/kernel/ldt.c
--- a/arch/x86_64/kernel/ldt.c	Wed Jul 24 14:03:39 2002
+++ b/arch/x86_64/kernel/ldt.c	Wed Jul 24 14:03:39 2002
@@ -132,7 +132,8 @@
 void release_segments(struct mm_struct *mm)
 {
 	if (mm->context.size) {
-		clear_LDT();
+		if (mm == current->active_mm)
+			clear_LDT();
 		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
 			vfree(mm->context.ldt);
 		else
diff -Nru a/arch/x86_64/kernel/mtrr.c b/arch/x86_64/kernel/mtrr.c
--- a/arch/x86_64/kernel/mtrr.c	Wed Jul 24 14:03:37 2002
+++ b/arch/x86_64/kernel/mtrr.c	Wed Jul 24 14:03:37 2002
@@ -117,8 +117,8 @@
 	u64 cr0;
 
 	/* Disable interrupts locally */
-	__save_flags(ctxt->flags);
-	__cli();
+	local_save_flags(ctxt->flags);
+	local_irq_disable();
 
     /*  Save value of CR4 and clear Page Global Enable (bit 7)  */
 	if (cpu_has_pge) { 
@@ -156,7 +156,7 @@
 		write_cr4 (ctxt->cr4val);
 
     /*  Re-enable interrupts locally (if enabled previously)  */
-	__restore_flags(ctxt->flags);
+	local_irq_restore(ctxt->flags);
 }
 
 
diff -Nru a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
--- a/arch/x86_64/kernel/process.c	Wed Jul 24 14:03:35 2002
+++ b/arch/x86_64/kernel/process.c	Wed Jul 24 14:03:35 2002
@@ -89,11 +89,11 @@
 void default_idle(void)
 {
 	if (!hlt_counter) {
-		__cli();
+		local_irq_disable();
 		if (!need_resched())
 			safe_halt();
 		else
-			__sti();
+			local_irq_enable();
 	}
 }
 
@@ -106,7 +106,7 @@
 {
 	int oldval;
 
-	__sti();
+	local_irq_enable();
 
 	/*
 	 * Deal with another CPU just having chosen a thread to
diff -Nru a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
--- a/arch/x86_64/kernel/smp.c	Wed Jul 24 14:03:36 2002
+++ b/arch/x86_64/kernel/smp.c	Wed Jul 24 14:03:36 2002
@@ -97,8 +97,8 @@
 	unsigned long cfg;
 	unsigned long flags;
 
-	__save_flags(flags);
-	__cli();
+	local_save_flags(flags);
+	local_irq_disable();
 
 	/*
 	 * Wait for idle.
@@ -120,7 +120,7 @@
 	 * Send the IPI. The write to APIC_ICR fires this off.
 	 */
 	apic_write_around(APIC_ICR, cfg);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
@@ -438,7 +438,7 @@
 	 * Remove this CPU:
 	 */
 	clear_bit(smp_processor_id(), &cpu_online_map);
-	__cli();
+	local_irq_disable();
 	disable_local_APIC();
 	for(;;) __asm__("hlt");
 	for (;;);
@@ -453,9 +453,9 @@
 	smp_call_function(stop_this_cpu, NULL, 1, 0);
 	smp_num_cpus = 1;
 
-	__cli();
+	local_irq_disable();
 	disable_local_APIC();
-	__sti();
+	local_irq_enable();
 }
 
 /*
diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
--- a/arch/x86_64/kernel/traps.c	Wed Jul 24 14:03:35 2002
+++ b/arch/x86_64/kernel/traps.c	Wed Jul 24 14:03:35 2002
@@ -344,7 +344,7 @@
 	printk("%s: %04lx\n", str, err & 0xffff);
 	cpu = smp_processor_id(); 
 	/* racy, but better than risking deadlock. */ 
-	__cli();
+	local_irq_disable();
 	if (!spin_trylock(&die_lock)) { 
 		if (cpu == die_owner) 
 			/* nested oops. should stop eventually */;
diff -Nru a/arch/x86_64/pci/direct.c b/arch/x86_64/pci/direct.c
--- a/arch/x86_64/pci/direct.c	Wed Jul 24 14:03:39 2002
+++ b/arch/x86_64/pci/direct.c	Wed Jul 24 14:03:39 2002
@@ -306,7 +306,7 @@
 	unsigned int tmp;
 	unsigned long flags;
 
-	__save_flags(flags); __cli();
+	local_save_flags(flags); local_irq_disable();
 
 	/*
 	 * Check if configuration type 1 works.
@@ -318,7 +318,7 @@
 		if (inl (0xCF8) == 0x80000000 &&
 		    pci_sanity_check(&pci_direct_conf1)) {
 			outl (tmp, 0xCF8);
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			printk(KERN_INFO "PCI: Using configuration type 1\n");
 			if (!request_region(0xCF8, 8, "PCI conf1"))
 				return NULL;
@@ -336,7 +336,7 @@
 		outb (0x00, 0xCFA);
 		if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 &&
 		    pci_sanity_check(&pci_direct_conf2)) {
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			printk(KERN_INFO "PCI: Using configuration type 2\n");
 			if (!request_region(0xCF8, 4, "PCI conf2"))
 				return NULL;
@@ -344,7 +344,7 @@
 		}
 	}
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	return NULL;
 }
 
diff -Nru a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile	Wed Jul 24 14:03:39 2002
+++ b/drivers/Makefile	Wed Jul 24 14:03:39 2002
@@ -8,7 +8,7 @@
 obj-$(CONFIG_PCI)		+= pci/
 obj-$(CONFIG_ACPI)		+= acpi/
 obj-$(CONFIG_PARPORT)		+= parport/
-obj-y 				+= base/ char/ block/ misc/ net/ media/
+obj-y				+= base/ serial/ char/ block/ misc/ net/ media/
 obj-$(CONFIG_NUBUS)		+= nubus/
 obj-$(CONFIG_ATM)		+= atm/
 obj-$(CONFIG_IDE)		+= ide/
diff -Nru a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
--- a/drivers/acorn/block/mfmhd.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/acorn/block/mfmhd.c	Wed Jul 24 14:03:36 2002
@@ -184,8 +184,6 @@
 #define NEED_1_RECAL -2
 #define NEED_2_RECAL -3
 		 int cylinder;
-	unsigned int access_count;
-	unsigned int busy;
 	struct {
 		char recal;
 		char report;
@@ -197,7 +195,6 @@
 
 static struct hd_struct mfm[MFM_MAXDRIVES << 6];
 static int mfm_sizes[MFM_MAXDRIVES << 6];
-static DECLARE_WAIT_QUEUE_HEAD(mfm_wait_open);
 
 /* Stuff from the assembly routines */
 extern unsigned int hdc63463_baseaddress;	/* Controller base address */
@@ -1195,22 +1192,11 @@
 			return -EFAULT;
 		return 0;
 
-	case BLKSECTGET:
-		return put_user(max_sectors[major][minor], (long *) arg);
-
 	case BLKRRPART:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 		return mfm_reread_partitions(dev);
 
-	case BLKGETSIZE:
-	case BLKGETSIZE64:
-	case BLKFLSBUF:
-	case BLKROSET:
-	case BLKROGET:
-	case BLKPG:
-		return blk_ioctl(inode->i_bdev, cmd, arg);
-
 	default:
 		return -EINVAL;
 	}
@@ -1219,24 +1205,8 @@
 static int mfm_open(struct inode *inode, struct file *file)
 {
 	int dev = DEVICE_NR(minor(inode->i_rdev));
-
 	if (dev >= mfm_drives)
 		return -ENODEV;
-
-	while (mfm_info[dev].busy)
-		sleep_on (&mfm_wait_open);
-
-	mfm_info[dev].access_count++;
-	return 0;
-}
-
-/*
- * Releasing a block device means we sync() it, so that it can safely
- * be forgotten about...
- */
-static int mfm_release(struct inode *inode, struct file *file)
-{
-	mfm_info[DEVICE_NR(minor(inode->i_rdev))].access_count--;
 	return 0;
 }
 
@@ -1254,10 +1224,11 @@
  * since if there are any non-ADFS partitions on the disk, this won't work!
  * Hence, I want to get rid of this...
  */
-void xd_set_geometry(kdev_t dev, unsigned char secsptrack, unsigned char heads,
-		     unsigned long discsize, unsigned int secsize)
+void xd_set_geometry(struct block_device *bdev, unsigned char secsptrack,
+			unsigned char heads, unsigned int secsize)
 {
-	int drive = minor(dev) >> 6;
+	int drive = MINOR(bdev->bd_dev) >> 6;
+	unsigned long disksize = bdev->bd_inode->i_size;
 
 	if (mfm_info[drive].cylinders == 1) {
 		mfm_info[drive].sectors = secsptrack;
@@ -1265,7 +1236,7 @@
 		mfm_info[drive].cylinders = discsize / (secsptrack * heads * secsize);
 
 		if ((heads < 1) || (mfm_info[drive].cylinders > 1024)) {
-			printk("mfm%c: Insane disc shape! Setting to 512/4/32\n",'a' + (dev >> 6));
+			printk("mfm%c: Insane disc shape! Setting to 512/4/32\n",'a' + drive);
 
 			/* These values are fairly arbitary, but are there so that if your
 			 * lucky you can pick apart your disc to find out what is going on -
@@ -1295,7 +1266,6 @@
 {
 	owner:		THIS_MODULE,
 	open:		mfm_open,
-	release:	mfm_release,
 	ioctl:		mfm_ioctl,
 };
 
@@ -1424,38 +1394,19 @@
 /*
  * This routine is called to flush all partitions and partition tables
  * for a changed MFM disk, and then re-read the new partition table.
- * If we are revalidating due to an ioctl, we have USAGE == 1.
  */
 static int mfm_reread_partitions(kdev_t dev)
 {
-	unsigned int start, i, maxp, target = DEVICE_NR(minor(dev));
-	unsigned long flags;
-
-	local_irq_save(flags);
-	if (mfm_info[target].busy || mfm_info[target].access_count > 1) {
-		local_irq_restore (flags);
-		return -EBUSY;
-	}
-	mfm_info[target].busy = 1;
-	local_irq_restore (flags);
-
-	maxp = 1 << mfm_gendisk.minor_shift;
-	start = target << mfm_gendisk.minor_shift;
-
-	for (i = maxp - 1; i >= 0; i--) {
-		int minor = start + i;
-		invalidate_device (mk_kdev(MAJOR_NR, minor), 1);
-		mfm_gendisk.part[minor].start_sect = 0;
-		mfm_gendisk.part[minor].nr_sects = 0;
-	}
-
+	unsigned int unit = DEVICE_NR(minor(dev));
+	kdev_t device = mk_kdev(MAJOR_NR, unit << mfm_gendisk.minor_shift);
+	int err = dev_lock_part(device);
+	if (err)
+		return err;
+	wipe_partitions(device);
 	/* Divide by 2, since sectors are 2 times smaller than usual ;-) */
-
-	grok_partitions(&mfm_gendisk, target, 1<<6, mfm_info[target].heads *
-		    mfm_info[target].cylinders * mfm_info[target].sectors / 2);
-
-	mfm_info[target].busy = 0;
-	wake_up (&mfm_wait_open);
+	grok_partitions(device, mfm_info[unit].heads *
+		    mfm_info[unit].cylinders * mfm_info[unit].sectors / 2);
+	dev_unlock_part(device);
 	return 0;
 }
 
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/acpi/processor.c	Wed Jul 24 14:03:38 2002
@@ -416,7 +416,7 @@
 	 * Interrupts must be disabled during bus mastering calculations and
 	 * for C2/C3 transitions.
 	 */
-	__cli();
+	local_irq_disable();
 
 	cx = &(pr->power.states[pr->power.state]);
 
@@ -461,7 +461,7 @@
 		 *      issues (e.g. floppy DMA transfer overrun/underrun).
 		 */
 		if (pr->power.bm_activity & cx->demotion.threshold.bm) {
-			__sti();
+			local_irq_enable();
 			next_state = cx->demotion.state;
 			goto end;
 		}
@@ -497,7 +497,7 @@
 		/* Get end time (ticks) */
 		t2 = inl(acpi_fadt.Xpm_tmr_blk.address);
 		/* Re-enable interrupts */
-		__sti();
+		local_irq_enable();
 		/* Compute time (ticks) that we were actually asleep */
 		sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
 		break;
@@ -516,13 +516,13 @@
 		/* Enable bus master arbitration */
 		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
 		/* Re-enable interrupts */
-		__sti();
+		local_irq_enable();
 		/* Compute time (ticks) that we were actually asleep */
 		sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
 		break;
 
 	default:
-		__sti();
+		local_irq_enable();
 		return;
 	}
 
@@ -1170,7 +1170,7 @@
 
 	pr->throttling.state = 0;
 
-	__cli();
+	local_irq_disable();
 
 	duty_mask = pr->throttling.state_count - 1;
 
@@ -1192,7 +1192,7 @@
 
 	pr->throttling.state = state;
 
-	__sti();
+	local_irq_enable();
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 		"Throttling state is T%d (%d%% throttling applied)\n",
@@ -1225,7 +1225,7 @@
 	if (state == pr->throttling.state)
 		return_VALUE(0);
 
-	__cli();
+	local_irq_disable();
 
 	/*
 	 * Calculate the duty_value and duty_mask.
@@ -1267,7 +1267,7 @@
 
 	pr->throttling.state = state;
 
-	__sti();
+	local_irq_enable();
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 		"Throttling state set to T%d (%d%%)\n", state, 
diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c
--- a/drivers/block/DAC960.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/block/DAC960.c	Wed Jul 24 14:03:39 2002
@@ -2055,29 +2055,20 @@
 static void DAC960_RegisterDisk(DAC960_Controller_T *Controller,
 				int LogicalDriveNumber)
 {
-  if (Controller->FirmwareType == DAC960_V1_Controller)
-    {
+  long size;
+  if (Controller->FirmwareType == DAC960_V1_Controller) {
       if (LogicalDriveNumber > Controller->LogicalDriveCount - 1) return;
-      register_disk(&Controller->GenericDiskInfo,
-		    DAC960_KernelDevice(Controller->ControllerNumber,
-					LogicalDriveNumber, 0),
-		    DAC960_MaxPartitions,
-		    &DAC960_BlockDeviceOperations,
-		    Controller->V1.LogicalDriveInformation
-				   [LogicalDriveNumber].LogicalDriveSize);
-    }
-  else
-    {
+      size = Controller->V1.LogicalDriveInformation
+				   [LogicalDriveNumber].LogicalDriveSize;
+  } else {
       DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
 	Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
       if (LogicalDeviceInfo == NULL) return;
-      register_disk(&Controller->GenericDiskInfo,
-		    DAC960_KernelDevice(Controller->ControllerNumber,
-					LogicalDriveNumber, 0),
-		    DAC960_MaxPartitions,
-		    &DAC960_BlockDeviceOperations,
-		    LogicalDeviceInfo->ConfigurableDeviceSize);
-    }
+      size = LogicalDeviceInfo->ConfigurableDeviceSize;
+  }
+  register_disk(&Controller->GenericDiskInfo,
+    DAC960_KernelDevice(Controller->ControllerNumber, LogicalDriveNumber, 0),
+    DAC960_MaxPartitions, &DAC960_BlockDeviceOperations, size);
 }
 
 
@@ -5399,15 +5390,9 @@
 	    LogicalDeviceInfo->ConfigurableDeviceSize
 	    / (Geometry.heads * Geometry.sectors);
 	}
-      Geometry.start = get_start_sect(Inode->i_rdev);
+      Geometry.start = get_start_sect(Inode->i_bdev);
       return (copy_to_user(UserGeometry, &Geometry,
 			   sizeof(DiskGeometry_T)) ? -EFAULT : 0);
-    case BLKGETSIZE:
-    case BLKGETSIZE64:
-    case BLKFLSBUF:
-    case BLKBSZGET:
-    case BLKBSZSET:
-      return blk_ioctl(Inode->i_bdev, Request, Argument);
 
     case BLKRRPART:
       /* Re-Read Partition Table. */
diff -Nru a/drivers/block/acsi.c b/drivers/block/acsi.c
--- a/drivers/block/acsi.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/block/acsi.c	Wed Jul 24 14:03:38 2002
@@ -68,6 +68,7 @@
 #include <scsi/scsi_ioctl.h>
 #include <linux/hdreg.h> /* for HDIO_GETGEO */
 #include <linux/blkpg.h>
+#include <linux/buffer_head.h>
 
 #include <asm/setup.h>
 #include <asm/pgtable.h>
@@ -248,8 +249,6 @@
 static int				acsi_sizes[MAX_DEV<<4] = { 0, };
 static struct hd_struct	acsi_part[MAX_DEV<<4] = { {0,0}, };
 static int 				access_count[MAX_DEV] = { 0, };
-static char 			busy[MAX_DEV] = { 0, };
-static DECLARE_WAIT_QUEUE_HEAD(busy_wait);
 
 static int				CurrentNReq;
 static int				CurrentNSect;
@@ -372,13 +371,13 @@
 static int acsi_change_blk_size( int target, int lun);
 static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
 static void acsi_geninit(void);
-static int revalidate_acsidisk( int dev, int maxusage );
-static int acsi_revalidate (dev_t);
+static int revalidate_acsidisk( kdev_t dev, int maxusage );
+static int acsi_revalidate (kdev_t);
 
 /************************* End of Prototypes **************************/
 
 
-struct timer_list acsi_timer = { NULL, NULL, 0, 0, acsi_times_out };
+struct timer_list acsi_timer = { function: acsi_times_out };
 
 
 #ifdef CONFIG_ATARI_SLM
@@ -786,7 +785,7 @@
 	
 	status = acsi_getstatus();
 	if (status != 0) {
-		int dev = DEVICE_NR(minor(CURRENT->rq_dev));
+		int dev = minor(CURRENT->rq_dev);
 		printk( KERN_ERR "ad%c: ", dev+'a' );
 		if (!acsi_reqsense( acsi_buffer, acsi_info[dev].target, 
 					acsi_info[dev].lun))
@@ -817,7 +816,7 @@
 
 	status = acsi_getstatus();
 	if (status != 0) {
-		int	dev = DEVICE_NR(minor(CURRENT->rq_dev));
+		int	dev = minor(CURRENT->rq_dev);
 		printk( KERN_ERR "ad%c: ", dev+'a' );
 		if (!acsi_reqsense( acsi_buffer, acsi_info[dev].target,
 					acsi_info[dev].lun))
@@ -969,7 +968,7 @@
 		return;
 	}
 
-	if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
+	if (major(CURRENT->rq_dev) != MAJOR_NR)
 		panic(DEVICE_NAME ": request list destroyed");
 	if (CURRENT->bh) {
 		if (!CURRENT->bh && !buffer_locked(CURRENT->bh))
@@ -978,26 +977,26 @@
 
 	dev = minor(CURRENT->rq_dev);
 	block = CURRENT->sector;
-	if (DEVICE_NR(dev) >= NDevices ||
+	if (dev >= NDevices ||
 		block+CURRENT->nr_sectors >= acsi_part[dev].nr_sects) {
 #ifdef DEBUG
 		printk( "ad%c: attempted access for blocks %d...%ld past end of device at block %ld.\n",
-		       DEVICE_NR(dev)+'a',
+		       dev+'a',
 		       block, block + CURRENT->nr_sectors - 1,
 		       acsi_part[dev].nr_sects);
 #endif
 		end_request(CURRENT, 0);
 		goto repeat;
 	}
-	if (acsi_info[DEVICE_NR(dev)].changed) {
+	if (acsi_info[dev].changed) {
 		printk( KERN_NOTICE "ad%c: request denied because cartridge has "
-				"been changed.\n", DEVICE_NR(dev)+'a' );
+				"been changed.\n", dev+'a' );
 		end_request(CURRENT, 0);
 		goto repeat;
 	}
 	
-	target = acsi_info[DEVICE_NR(dev)].target;
-	lun    = acsi_info[DEVICE_NR(dev)].lun;
+	target = acsi_info[dev].target;
+	lun    = acsi_info[dev].lun;
 
 	/* Find out how many sectors should be transferred from/to
 	 * consecutive buffers and thus can be done with a single command.
@@ -1045,7 +1044,7 @@
 	CurrentBuffer = buffer;
 	CurrentNSect  = nsect;
 
-	if (CURRENT->cmd == WRITE) {
+	if (rq_data_dir(CURRENT) == WRITE) {
 		CMDSET_TARG_LUN( write_cmd, target, lun );
 		CMDSET_BLOCK( write_cmd, block );
 		CMDSET_LEN( write_cmd, nsect );
@@ -1062,7 +1061,7 @@
 		SET_TIMER();
 		return;
 	}
-	if (CURRENT->cmd == READ) {
+	if (rq_data_dir(CURRENT) == READ) {
 		CMDSET_TARG_LUN( read_cmd, target, lun );
 		CMDSET_BLOCK( read_cmd, block );
 		CMDSET_LEN( read_cmd, nsect );
@@ -1090,11 +1089,12 @@
 
 static int acsi_ioctl( struct inode *inode, struct file *file,
 					   unsigned int cmd, unsigned long arg )
-{	int dev;
+{
+	dev_t dev;
 
 	if (!inode)
 		return -EINVAL;
-	dev = DEVICE_NR(minor(inode->i_rdev));
+	dev = minor(inode->i_rdev);
 	if (dev >= NDevices)
 		return -EINVAL;
 	switch (cmd) {
@@ -1107,7 +1107,7 @@
 	    put_user( 64, &geo->heads );
 	    put_user( 32, &geo->sectors );
 	    put_user( acsi_info[dev].size >> 11, &geo->cylinders );
-		put_user(get_start_sect(inode->i_rdev), &geo->start);
+		put_user(get_start_sect(inode->i_bdev), &geo->start);
 		return 0;
 	  }
 		
@@ -1118,14 +1118,6 @@
 		put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id );
 		return 0;
 		
-	  case BLKGETSIZE:
-	  case BLKGETSIZE64:
-	  case BLKROSET:
-	  case BLKROGET:
-	  case BLKFLSBUF:
-	  case BLKPG:
-		return blk_ioctl(inode->i_bdev, cmd, arg);
-
 	  case BLKRRPART: /* Re-read partition tables */
 	        if (!capable(CAP_SYS_ADMIN)) 
 			return -EACCES;
@@ -1157,12 +1149,10 @@
 	int  device;
 	struct acsi_info_struct *aip;
 
-	device = DEVICE_NR(minor(inode->i_rdev));
+	device = minor(inode->i_rdev);
 	if (device >= NDevices)
 		return -ENXIO;
 	aip = &acsi_info[device];
-	while (busy[device])
-		sleep_on(&busy_wait);
 
 	if (access_count[device] == 0 && aip->removable) {
 #if 0
@@ -1195,7 +1185,7 @@
 
 static int acsi_release( struct inode * inode, struct file * file )
 {
-	int device = DEVICE_NR(minor(inode->i_rdev));
+	int device = minor(inode->i_rdev);
 	if (--access_count[device] == 0 && acsi_info[device].removable)
 		acsi_prevent_removal(device, 0);
 	return( 0 );
@@ -1221,9 +1211,9 @@
 	stdma_release();
 }
 
-static int acsi_media_change (dev_t dev)
+static int acsi_media_change (kdev_t dev)
 {
-	int device = DEVICE_NR(minor(dev));
+	int device = minor(dev);
 	struct acsi_info_struct *aip;
 
 	aip = &acsi_info[device];
@@ -1803,10 +1793,6 @@
 }
 #endif
 
-#define DEVICE_BUSY busy[device]
-#define USAGE access_count[device]
-#define GENDISK_STRUCT acsi_gendisk
-
 /*
  * This routine is called to flush all partitions and partition tables
  * for a changed scsi disk, and then re-read the new partition table.
@@ -1826,26 +1812,17 @@
  *
  */
 
-static int revalidate_acsidisk( int dev, int maxusage )
+static int revalidate_acsidisk(kdev_t dev, int maxusage )
 {
-	int device;
-	struct gendisk * gdev;
-	int res;
-	struct acsi_info_struct *aip;
-	
-	device = DEVICE_NR(minor(dev));
-	aip = &acsi_info[device];
-	gdev = &GENDISK_STRUCT;
+	int unit = DEVICE_NR(minor(dev));
+	struct acsi_info_struct *aip = &acsi_info[unit];
+	kdev_t device = mk_kdev(MAJOR_NR, unit<<4);
+	int res = dev_lock_part(device);
 
-	cli();
-	if (DEVICE_BUSY || USAGE > maxusage) {
-		sti();
-		return -EBUSY;
-	};
-	DEVICE_BUSY = 1;
-	sti();
+	if (res < 0)
+		return res;
 
-	res = wipe_partitions(dev);
+	res = wipe_partitions(device);
 
 	stdma_lock( NULL, NULL );
 
@@ -1862,15 +1839,14 @@
 	stdma_release();
 
 	if (!res)
-		grok_partitions(dev, aip->size);
+		grok_partitions(device, aip->size);
 
-	DEVICE_BUSY = 0;
-	wake_up(&busy_wait);
+	dev_unlock_part(device);
 	return res;
 }
 
 
-static int acsi_revalidate (dev_t dev)
+static int acsi_revalidate (kdev_t dev)
 {
   return revalidate_acsidisk (dev, 0);
 }
diff -Nru a/drivers/block/amiflop.c b/drivers/block/amiflop.c
--- a/drivers/block/amiflop.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/block/amiflop.c	Wed Jul 24 14:03:38 2002
@@ -71,6 +71,7 @@
 #include <linux/amifdreg.h>
 #include <linux/amifd.h>
 #include <linux/ioport.h>
+#include <linux/buffer_head.h>
 
 #include <asm/setup.h>
 #include <asm/uaccess.h>
@@ -1849,8 +1850,6 @@
 
 	/* init ms timer */
 	ciaa.crb = 8; /* one-shot, stop */
-
-	(void)do_floppy; /* avoid warning about unused variable */
 	return 0;
 }
 
diff -Nru a/drivers/block/ataflop.c b/drivers/block/ataflop.c
--- a/drivers/block/ataflop.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/block/ataflop.c	Wed Jul 24 14:03:36 2002
@@ -76,6 +76,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/buffer_head.h>		/* for invalidate_buffers() */
 
 #include <asm/setup.h>
 #include <asm/system.h>
@@ -358,7 +359,7 @@
 static void fd_select_drive( int drive );
 static void fd_deselect( void );
 static void fd_motor_off_timer( unsigned long dummy );
-static void check_change( void );
+static void check_change( unsigned long dummy );
 static __inline__ void set_head_settle_flag( void );
 static __inline__ int get_head_settle_flag( void );
 static void floppy_irq (int irq, void *dummy, struct pt_regs *fp);
@@ -378,7 +379,6 @@
 static void fd_times_out( unsigned long dummy );
 static void finish_fdc( void );
 static void finish_fdc_done( int dummy );
-static void floppy_off( unsigned int nr);
 static __inline__ void copy_buffer( void *from, void *to);
 static void setup_req_params( int drive );
 static void redo_fd_request( void);
@@ -539,7 +539,7 @@
  * as possible) and keep track of the current state of the write protection.
  */
 
-static void check_change( void )
+static void check_change( unsigned long dummy )
 {
 	static int    drive = 0;
 
@@ -1339,9 +1339,6 @@
 static int fd_ref[4] = { 0,0,0,0 };
 static int fd_device[4] = { 0,0,0,0 };
 
-/* dummy for blk.h */
-static void floppy_off( unsigned int nr) {}
-
 
 /* The detection of disk changes is a dark chapter in Atari history :-(
  * Because the "Drive ready" signal isn't present in the Atari
@@ -1458,9 +1455,6 @@
 	if (major(CURRENT->rq_dev) != MAJOR_NR)
 		panic(DEVICE_NAME ": request list destroyed");
 
-	if (CURRENT->bh && !buffer_locked(CURRENT->bh))
-		panic(DEVICE_NAME ": block not locked");
-
 	device = minor(CURRENT->rq_dev);
 	drive = device & 3;
 	type = device >> 2;
@@ -1507,7 +1501,7 @@
 	del_timer( &motor_off_timer );
 		
 	ReqCnt = 0;
-	ReqCmd = CURRENT->cmd;
+	ReqCmd = rq_data_dir(CURRENT);
 	ReqBlock = CURRENT->sector;
 	ReqBuffer = CURRENT->buffer;
 	setup_req_params( drive );
@@ -1559,12 +1553,6 @@
 	struct floppy_struct setprm;
 
 	device = inode->i_rdev;
-	switch (cmd) {
-		case BLKROSET:
-		case BLKROGET:
-		case BLKFLSBUF:
-			return blk_ioctl(inode->i_bdev, cmd, param);
-	}
 	drive = minor (device);
 	type  = drive >> 2;
 	drive &= 3;
@@ -2008,7 +1996,6 @@
 	       UseTrackbuffer ? "" : "no ");
 	config_types();
 
-	(void)do_floppy; /* avoid warning about unused variable */
 	return 0;
 }
 
diff -Nru a/drivers/block/blkpg.c b/drivers/block/blkpg.c
--- a/drivers/block/blkpg.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/block/blkpg.c	Wed Jul 24 14:03:35 2002
@@ -69,8 +69,9 @@
 	struct gendisk *g;
 	long long ppstart, pplength;
 	long pstart, plength;
-	int i, drive, first_minor, end_minor, minor;
+	int i;
 	kdev_t dev = to_kdev_t(bdev->bd_dev);
+	struct hd_struct *part;
 
 	/* convert bytes to sectors, check for fit in a hd_struct */
 	ppstart = (p->start >> 9);
@@ -85,37 +86,32 @@
 	g = get_gendisk(dev);
 	if (!g)
 		return -ENXIO;
+	part = g->part + minor(dev);
 
 	/* existing drive? */
-	drive = (minor(dev) >> g->minor_shift);
-	first_minor = (drive << g->minor_shift);
-	end_minor   = first_minor + (1 << g->minor_shift);
-	if (drive >= g->nr_real)
-		return -ENXIO;
 
 	/* drive and partition number OK? */
-	if (first_minor != minor(dev))
+	if (bdev != bdev->bd_contains)
 		return -EINVAL;
 	if (p->pno <= 0 || p->pno >= (1 << g->minor_shift))
 		return -EINVAL;
 
 	/* partition number in use? */
-	minor = first_minor + p->pno;
-	if (g->part[minor].nr_sects != 0)
+	if (part[p->pno].nr_sects != 0)
 		return -EBUSY;
 
 	/* overlap? */
-	for (i=first_minor+1; i<end_minor; i++)
-		if (!(pstart+plength <= g->part[i].start_sect ||
-		      pstart >= g->part[i].start_sect + g->part[i].nr_sects))
+	for (i = 1; i < (1<<g->minor_shift); i++)
+		if (!(pstart+plength <= part[i].start_sect ||
+		      pstart >= part[i].start_sect + part[i].nr_sects))
 			return -EBUSY;
 
 	/* all seems OK */
-	g->part[minor].start_sect = pstart;
-	g->part[minor].nr_sects = plength;
+	part[p->pno].start_sect = pstart;
+	part[p->pno].nr_sects = plength;
 	if (g->sizes)
-		g->sizes[minor] = (plength >> (BLOCK_SIZE_BITS - 9));
-	devfs_register_partitions (g, first_minor, 0);
+		g->sizes[minor(dev)+p->pno] = (plength >> (BLOCK_SIZE_BITS-9));
+	devfs_register_partitions (g, minor(dev), 0);
 	return 0;
 }
 
@@ -133,33 +129,27 @@
 {
 	kdev_t dev = to_kdev_t(bdev->bd_dev);
 	struct gendisk *g;
-	kdev_t devp;
 	struct block_device *bdevp;
-	int drive, first_minor, minor;
+	struct hd_struct *part;
 	int holder;
 
 	/* find the drive major */
 	g = get_gendisk(dev);
 	if (!g)
 		return -ENXIO;
+	part = g->part + minor(dev);
 
-	/* drive and partition number OK? */
-	drive = (minor(dev) >> g->minor_shift);
-	first_minor = (drive << g->minor_shift);
-
-	if (first_minor != minor(dev))
+	if (bdev != bdev->bd_contains)
 		return -EINVAL;
 	if (p->pno <= 0 || p->pno >= (1 << g->minor_shift))
   		return -EINVAL;
 
 	/* existing drive and partition? */
-	minor = first_minor + p->pno;
-	if (drive >= g->nr_real || g->part[minor].nr_sects == 0)
+	if (part[p->pno].nr_sects == 0)
 		return -ENXIO;
 
 	/* partition in use? Incomplete check for now. */
-	devp = mk_kdev(major(dev), minor);
-	bdevp = bdget(kdev_t_to_nr(devp));
+	bdevp = bdget(MKDEV(major(dev), minor(dev) + p->pno));
 	if (!bdevp)
 		return -ENOMEM;
 	if (bd_claim(bdevp, &holder) < 0) {
@@ -171,11 +161,11 @@
 	fsync_bdev(bdevp);
 	invalidate_bdev(bdevp, 0);
 
-	g->part[minor].start_sect = 0;
-	g->part[minor].nr_sects = 0;
+	part[p->pno].start_sect = 0;
+	part[p->pno].nr_sects = 0;
 	if (g->sizes)
-		g->sizes[minor] = 0;
-	devfs_register_partitions (g, first_minor, 0);
+		g->sizes[minor(dev) + p->pno] = 0;
+	devfs_register_partitions (g, minor(dev), 0);
 	bd_release(bdevp);
 	bdput(bdevp);
 
@@ -223,10 +213,6 @@
 	int holder;
 	struct backing_dev_info *bdi;
 
-	intval = block_ioctl(bdev, cmd, arg);
-	if (intval != -ENOTTY)
-		return intval;
-
 	switch (cmd) {
 		case BLKROSET:
 			if (!capable(CAP_SYS_ADMIN))
@@ -296,14 +282,6 @@
 
 		case BLKPG:
 			return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg *) arg);
-			
-		/*
-		 * deprecated, use the /proc/iosched interface instead
-		 */
-		case BLKELVGET:
-		case BLKELVSET:
-			return -ENOTTY;
-
 		case BLKBSZGET:
 			/* get the logical block size (cf. BLKSSZGET) */
 			intval = block_size(bdev);
@@ -330,5 +308,3 @@
 			return -EINVAL;
 	}
 }
-
-EXPORT_SYMBOL(blk_ioctl);
diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c
--- a/drivers/block/cciss.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/block/cciss.c	Wed Jul 24 14:03:39 2002
@@ -440,15 +440,6 @@
 
 	case BLKRRPART:
 		return revalidate_logvol(inode->i_rdev, 1);
-	case BLKGETSIZE:
-	case BLKGETSIZE64:
-	case BLKFLSBUF:
-	case BLKBSZSET:
-	case BLKBSZGET:
-	case BLKROSET:
-	case BLKROGET:
-	case BLKPG:
-		return blk_ioctl(inode->i_bdev, cmd, arg);
 	case CCISS_GETPCIINFO:
 	{
 		cciss_pci_info_struct pciinfo;
@@ -735,6 +726,10 @@
 }
 
 /* Borrowed and adapted from sd.c */
+/*
+ * FIXME: we are missing the exclusion with ->open() here - it can happen
+ * just as we are rereading partition tables.
+ */
 static int revalidate_logvol(kdev_t dev, int maxusage)
 {
         int ctlr, target;
@@ -860,18 +855,9 @@
 	/* invalidate the devices and deregister the disk */ 
 	max_p = 1 << gdev->minor_shift;
 	start = logvol << gdev->minor_shift;
+	wipe_partitions(mk_kdev(MAJOR_NR+ctlr, start));
 	for (i=max_p-1; i>=0; i--)
-	{
-		int minor = start+i;
-		kdev_t kdev = mk_kdev(MAJOR_NR+ctlr, minor);
-		// printk("invalidating( %d %d)\n", ctlr, minor);
-		invalidate_device(kdev, 1);
-		/* so open will now fail */
-		h->sizes[minor] = 0;
-		/* so it will no longer appear in /proc/partitions */ 
-		gdev->part[minor].start_sect = 0;
-		gdev->part[minor].nr_sects = 0;	
-	}
+		h->sizes[start + i] = 0;
 	/* check to see if it was the last disk */
 	if (logvol == h->highest_lun)
 	{
@@ -1313,19 +1299,12 @@
 	hba[ctlr]->drv[logvol].usage_count = 0;
 	max_p = 1 << gdev->minor_shift;
         start = logvol<< gdev->minor_shift;
+	kdev = mk_kdev(MAJOR_NR + ctlr, logvol<< gdev->minor_shift);
 
-        for(i=max_p-1; i>=0; i--) {
-                int minor = start+i;
-		kdev = mk_kdev(MAJOR_NR + ctlr, minor);
-                invalidate_device(kdev, 1);
-                gdev->part[minor].start_sect = 0;
-                gdev->part[minor].nr_sects = 0;
-        }
-
+	wipe_partitions(kdev);
 	++hba[ctlr]->num_luns;
 	gdev->nr_real = hba[ctlr]->highest_lun + 1;
 	/* setup partitions per disk */
-	kdev = mk_kdev(MAJOR_NR + ctlr, logvol<< gdev->minor_shift);
 	grok_partitions(kdev, hba[ctlr]->drv[logvol].nr_blocks);
 	
 	kfree(ld_buff);
@@ -1884,7 +1863,7 @@
 
 	goto queue;
 startio:
-	blk_stop_queue(q);
+	__blk_stop_queue(q);
 	start_io(h);
 }
 
diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/block/cpqarray.c	Wed Jul 24 14:03:36 2002
@@ -918,7 +918,7 @@
 	goto queue_next;
 
 startio:
-	blk_stop_queue(q);
+	__blk_stop_queue(q);
 	start_io(h);
 }
 
@@ -1116,7 +1116,7 @@
 		put_user(diskinfo[0], &geo->heads);
 		put_user(diskinfo[1], &geo->sectors);
 		put_user(diskinfo[2], &geo->cylinders);
-		put_user(get_start_sect(inode->i_rdev), &geo->start);
+		put_user(get_start_sect(inode->i_bdev), &geo->start);
 		return 0;
 	case IDAGETDRVINFO:
 		if (copy_to_user(&io->c.drv, &hba[ctlr]->drv[dsk],
@@ -1157,16 +1157,6 @@
 		return(0);
 	}	
 
-	case BLKGETSIZE:
-	case BLKGETSIZE64:
-	case BLKFLSBUF:
-	case BLKBSZSET:
-	case BLKBSZGET:
-	case BLKROSET:
-	case BLKROGET:
-	case BLKPG:
-		return blk_ioctl(inode->i_bdev, cmd, arg);
-
 	default:
 		return -EINVAL;
 	}
@@ -1533,6 +1523,9 @@
 }
 
 /* Borrowed and adapted from sd.c */
+/*
+ * FIXME: exclusion with ->open()
+ */
 static int revalidate_logvol(kdev_t dev, int maxusage)
 {
 	int ctlr, target;
diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c
--- a/drivers/block/floppy.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/block/floppy.c	Wed Jul 24 14:03:36 2002
@@ -3468,12 +3468,6 @@
 	const char *outparam; /* parameters passed back to user space */
 
 	device = inode->i_rdev;
-	switch (cmd) {
-		case BLKROSET:
-		case BLKROGET:
-		case BLKFLSBUF:
-			return blk_ioctl(inode->i_bdev, cmd, param);
-	}
 	type = TYPE(device);
 	drive = DRIVE(device);
 
@@ -4260,9 +4254,12 @@
 		CLEARSTRUCT(FDCS);
 		FDCS->dtr = -1;
 		FDCS->dor = 0x4;
-#ifdef __sparc__
-		/*sparcs don't have a DOR reset which we can fall back on to*/
-		FDCS->version = FDC_82072A;
+#if defined(__sparc__) || defined(__mc68000__)
+		/*sparcs/sun3x don't have a DOR reset which we can fall back on to*/
+#ifdef __mc68000__
+		if (MACH_IS_SUN3X)
+#endif
+			FDCS->version = FDC_82072A;		
 #endif
 	}
 
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/block/genhd.c	Wed Jul 24 14:03:38 2002
@@ -117,31 +117,6 @@
 
 EXPORT_SYMBOL(get_gendisk);
 
-
-unsigned long
-get_start_sect(kdev_t dev)
-{
-	struct gendisk *gp;
-
-	gp = get_gendisk(dev);
-	if (gp)
-		return gp->part[minor(dev)].start_sect;
-	return 0;
-}
-
-EXPORT_SYMBOL(get_start_sect);
-
-unsigned long
-get_nr_sects(kdev_t dev)
-{
-	struct gendisk *gp;
-
-	gp = get_gendisk(dev);
-	if (gp)
-		return gp->part[minor(dev)].nr_sects;
-	return 0;
-}
-
 #ifdef CONFIG_PROC_FS
 /* iterator */
 static void *part_start(struct seq_file *part, loff_t *pos)
@@ -209,7 +184,6 @@
 {
 	rwlock_init(&gendisk_lock);
 	blk_dev_init();
-	sti();
 #ifdef CONFIG_I2O
 	i2o_init();
 #endif
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/block/ll_rw_blk.c	Wed Jul 24 14:03:36 2002
@@ -900,7 +900,8 @@
  * Description:
  *   blk_start_queue() will clear the stop flag on the queue, and call
  *   the request_fn for the queue if it was in a stopped state when
- *   entered. Also see blk_stop_queue()
+ *   entered. Also see blk_stop_queue(). Must not be called from driver
+ *   request function due to recursion issues.
  **/
 void blk_start_queue(request_queue_t *q)
 {
@@ -915,6 +916,18 @@
 }
 
 /**
+ * __blk_stop_queue: see blk_stop_queue()
+ *
+ * Description:
+ *  Like blk_stop_queue(), bust queue_lock must be held
+ **/
+void __blk_stop_queue(request_queue_t *q)
+{
+	blk_remove_plug(q);
+	set_bit(QUEUE_FLAG_STOPPED, &q->queue_flags);
+}
+
+/**
  * blk_stop_queue - stop a queue
  * @q:    The &request_queue_t in question
  *
@@ -933,10 +946,8 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(q->queue_lock, flags);
-	blk_remove_plug(q);
+	__blk_stop_queue(q);
 	spin_unlock_irqrestore(q->queue_lock, flags);
-
-	set_bit(QUEUE_FLAG_STOPPED, &q->queue_flags);
 }
 
 /**
@@ -1573,16 +1584,10 @@
 static inline void blk_partition_remap(struct bio *bio)
 {
 	struct block_device *bdev = bio->bi_bdev;
-	struct gendisk *g;
-
 	if (bdev == bdev->bd_contains)
 		return;
 
-	g = get_gendisk(to_kdev_t(bdev->bd_dev));
-	if (!g)
-		BUG();
-
-	bio->bi_sector += g->part[minor(to_kdev_t((bdev->bd_dev)))].start_sect;
+	bio->bi_sector += bdev->bd_offset;
 	bio->bi_bdev = bdev->bd_contains;
 	/* lots of checks are possible */
 }
@@ -2047,9 +2052,6 @@
 #if defined(CONFIG_IDE) && defined(CONFIG_BLK_DEV_HD)
 	hd_init();
 #endif
-#if defined(__i386__)	/* Do we even need this? */
-	outb_p(0xc, 0x3f2);
-#endif
 
 	return 0;
 };
@@ -2098,4 +2100,5 @@
 
 EXPORT_SYMBOL(blk_start_queue);
 EXPORT_SYMBOL(blk_stop_queue);
+EXPORT_SYMBOL(__blk_stop_queue);
 EXPORT_SYMBOL(blk_run_queues);
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/block/loop.c	Wed Jul 24 14:03:35 2002
@@ -912,10 +912,6 @@
 		}
 		err = put_user((u64)loop_sizes[lo->lo_number] << 10, (u64*)arg);
 		break;
-	case BLKBSZGET:
-	case BLKBSZSET:
-		err = blk_ioctl(inode->i_bdev, cmd, arg);
-		break;
 	default:
 		err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
 	}
diff -Nru a/drivers/block/paride/Makefile b/drivers/block/paride/Makefile
--- a/drivers/block/paride/Makefile	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/paride/Makefile	Wed Jul 24 14:03:37 2002
@@ -5,14 +5,9 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-export-objs := paride.o bpck6.o
+export-objs := paride.o
 
 obj-$(CONFIG_PARIDE)		+= paride.o
-obj-$(CONFIG_PARIDE_PD)		+= pd.o
-obj-$(CONFIG_PARIDE_PCD)	+= pcd.o
-obj-$(CONFIG_PARIDE_PF)		+= pf.o
-obj-$(CONFIG_PARIDE_PT)		+= pt.o
-obj-$(CONFIG_PARIDE_PG)		+= pg.o
 obj-$(CONFIG_PARIDE_ATEN)	+= aten.o
 obj-$(CONFIG_PARIDE_BPCK)	+= bpck.o
 obj-$(CONFIG_PARIDE_COMM)	+= comm.o
@@ -20,13 +15,18 @@
 obj-$(CONFIG_PARIDE_KBIC)	+= kbic.o
 obj-$(CONFIG_PARIDE_EPAT)	+= epat.o
 obj-$(CONFIG_PARIDE_EPIA)	+= epia.o
-obj-$(CONFIG_PARIDE_FIT2)	+= fit2.o
-obj-$(CONFIG_PARIDE_FIT3)	+= fit3.o
 obj-$(CONFIG_PARIDE_FRPW)	+= frpw.o
 obj-$(CONFIG_PARIDE_FRIQ)	+= friq.o
+obj-$(CONFIG_PARIDE_FIT2)	+= fit2.o
+obj-$(CONFIG_PARIDE_FIT3)	+= fit3.o
 obj-$(CONFIG_PARIDE_ON20)	+= on20.o
 obj-$(CONFIG_PARIDE_ON26)	+= on26.o
 obj-$(CONFIG_PARIDE_KTTI)	+= ktti.o
 obj-$(CONFIG_PARIDE_BPCK6)	+= bpck6.o
+obj-$(CONFIG_PARIDE_PD)		+= pd.o
+obj-$(CONFIG_PARIDE_PCD)	+= pcd.o
+obj-$(CONFIG_PARIDE_PF)		+= pf.o
+obj-$(CONFIG_PARIDE_PT)		+= pt.o
+obj-$(CONFIG_PARIDE_PG)		+= pg.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/block/paride/aten.c b/drivers/block/paride/aten.c
--- a/drivers/block/paride/aten.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/block/paride/aten.c	Wed Jul 24 14:03:35 2002
@@ -18,6 +18,7 @@
 #define ATEN_VERSION      "1.01"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/wait.h>
@@ -140,35 +141,33 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol aten = {"aten",0,2,2,1,1,
-                           aten_write_regr,
-                           aten_read_regr,
-                           aten_write_block,
-                           aten_read_block,
-                           aten_connect,
-                           aten_disconnect,
-                           0,
-                           0,
-                           0,
-                           aten_log_adapter,
-                           aten_init_proto,
-                           aten_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &aten ) - 1;
+static struct pi_protocol aten = {
+	.name		= "aten",
+	.max_mode	= 2,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= aten_write_regr,
+	.read_regr	= aten_read_regr,
+	.write_block	= aten_write_block,
+	.read_block	= aten_read_block,
+	.connect	= aten_connect,
+	.disconnect	= aten_disconnect,
+	.log_adapter	= aten_log_adapter,
+	.init_proto	= aten_init_proto,
+	.release_proto	= aten_release_proto,
+};
+
+static int __init aten_init(void)
+{
+	return pi_register(&aten)-1;
+}
+
+static void __exit aten_exit(void)
+{
+	pi_unregister( &aten );
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &aten );
-}
-
-#endif
-
-/* end of aten.c */
 MODULE_LICENSE("GPL");
+module_init(aten_init)
+module_exit(aten_exit)
diff -Nru a/drivers/block/paride/bpck.c b/drivers/block/paride/bpck.c
--- a/drivers/block/paride/bpck.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/block/paride/bpck.c	Wed Jul 24 14:03:39 2002
@@ -17,6 +17,7 @@
 #define	BPCK_VERSION	"1.02" 
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -452,34 +453,36 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol bpck = { "bpck",0,5,2,4,256,
-			  bpck_write_regr,
-			  bpck_read_regr,
-			  bpck_write_block,
-			  bpck_read_block,
-			  bpck_connect,
-			  bpck_disconnect,
-			  bpck_test_port,
-			  bpck_probe_unit,
-		          bpck_test_proto,
-			  bpck_log_adapter,
-			  bpck_init_proto,
-			  bpck_release_proto
-			};
-
-#ifdef MODULE
-
-int	init_module(void)
-
-{	return pi_register(&bpck) - 1;
+static struct pi_protocol bpck = {
+	.name		= "bpck",
+	.max_mode	= 5,
+	.epp_first	= 2,
+	.default_delay	= 4,
+	.max_units	= 255,
+	.write_regr	= bpck_write_regr,
+	.read_regr	= bpck_read_regr,
+	.write_block	= bpck_write_block,
+	.read_block	= bpck_read_block,
+	.connect	= bpck_connect,
+	.disconnect	= bpck_disconnect,
+	.test_port	= bpck_test_port,
+	.probe_unit	= bpck_probe_unit,
+	.test_proto	= bpck_test_proto,
+	.log_adapter	= bpck_log_adapter,
+	.init_proto	= bpck_init_proto,
+	.release_proto	= bpck_release_proto,
+};
+
+static int __init bpck_init(void)
+{
+	return pi_register(&bpck)-1;
+}
+
+static void __exit bpck_exit(void)
+{
+	pi_unregister(&bpck);
 }
 
-void	cleanup_module(void)
-
-{	pi_unregister(&bpck);
-}
-
-#endif
-
-/* end of bpck.c */
 MODULE_LICENSE("GPL");
+module_init(bpck_init)
+module_exit(bpck_exit)
diff -Nru a/drivers/block/paride/bpck6.c b/drivers/block/paride/bpck6.c
--- a/drivers/block/paride/bpck6.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/block/paride/bpck6.c	Wed Jul 24 14:03:38 2002
@@ -26,6 +26,7 @@
 #define BACKPACK_VERSION "2.0.2"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -252,65 +253,41 @@
 	kfree((void *)(pi->private)); 
 }
 
-struct pi_protocol bpck6 = { "bpck6", /* name for proto*/
-				0, /* index into proto table */
-				5, /* max mode =5 */
-				2, /* 2-5 use epp (need 8 ports) */
-				0, /* no delay (not used anyway) */
-				255, /* we can have units  up to 255 */
-				bpck6_write_regr,
-				bpck6_read_regr,
-				bpck6_write_block,
-				bpck6_read_block,
-				bpck6_connect,
-				bpck6_disconnect,
-				bpck6_test_port,
- 				bpck6_probe_unit,
-				0,
-				bpck6_log_adapter,
-				bpck6_init_proto,
-				bpck6_release_proto
-                        };
-
-
-EXPORT_SYMBOL(bpck6_write_regr);
-EXPORT_SYMBOL(bpck6_read_regr);
-EXPORT_SYMBOL(bpck6_write_block);
-EXPORT_SYMBOL(bpck6_read_block);
-EXPORT_SYMBOL(bpck6_connect);
-EXPORT_SYMBOL(bpck6_disconnect);
-EXPORT_SYMBOL(bpck6_test_port);
-EXPORT_SYMBOL(bpck6_probe_unit);
-EXPORT_SYMBOL(bpck6_log_adapter);
-EXPORT_SYMBOL(bpck6_init_proto);
-EXPORT_SYMBOL(bpck6_release_proto);
+static struct pi_protocol bpck6 = {
+	.name		= "bpck6",
+	.max_mode	= 5,
+	.epp_first	= 2, /* 2-5 use epp (need 8 ports) */
+	.max_units	= 255,
+	.write_regr	= bpck6_write_regr,
+	.read_regr	= bpck6_read_regr,
+	.write_block	= bpck6_write_block,
+	.read_block	= bpck6_read_block,
+	.connect	= bpck6_connect,
+	.disconnect	= bpck6_disconnect,
+	.test_port	= bpck6_test_port,
+	.probe_unit	= bpck6_probe_unit,
+	.log_adapter	= bpck6_log_adapter,
+	.init_proto	= bpck6_init_proto,
+	.release_proto	= bpck6_release_proto,
+};
 
-/*---------------------------MODULE STUFF-----------------------*/
-
-#ifdef MODULE
-/*module information*/
-
-static int init_module(void)
+static int __init bpck6_init(void)
 {
 	printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
 	printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
-
 	if(verbose)
-	{
 		printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
-	}
-
 	return pi_register(&bpck6) - 1;  
 }
 
-void    cleanup_module(void)
+static void __exit bpck6_exit(void)
 {
 	pi_unregister(&bpck6);
 }
 
+MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Micro Solutions Inc.");
 MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
 MODULE_PARM(verbose,"i");
-
-#endif
-
+module_init(bpck6_init)
+module_exit(bpck6_exit)
diff -Nru a/drivers/block/paride/comm.c b/drivers/block/paride/comm.c
--- a/drivers/block/paride/comm.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/paride/comm.c	Wed Jul 24 14:03:37 2002
@@ -17,6 +17,7 @@
 #define COMM_VERSION      "1.01"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -196,35 +197,33 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol comm = {"comm",0,5,2,1,1,
-                           comm_write_regr,
-                           comm_read_regr,
-                           comm_write_block,
-                           comm_read_block,
-                           comm_connect,
-                           comm_disconnect,
-                           0,
-                           0,
-                           0,
-                           comm_log_adapter,
-                           comm_init_proto,
-                           comm_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &comm ) - 1;
+static struct pi_protocol comm = {
+	.name		= "comm",
+	.max_mode	= 5,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= comm_write_regr,
+	.read_regr	= comm_read_regr,
+	.write_block	= comm_write_block,
+	.read_block	= comm_read_block,
+	.connect	= comm_connect,
+	.disconnect	= comm_disconnect,
+	.log_adapter	= comm_log_adapter,
+	.init_proto	= comm_init_proto,
+	.release_proto	= comm_release_proto,
+};
+
+static int __init comm_init(void)
+{
+	return pi_register(&comm)-1;
+}
+
+static void __exit comm_exit(void)
+{
+	pi_unregister(&comm);
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &comm );
-}
-
-#endif
-
-/* end of comm.c */
 MODULE_LICENSE("GPL");
+module_init(comm_init)
+module_exit(comm_exit)
diff -Nru a/drivers/block/paride/dstr.c b/drivers/block/paride/dstr.c
--- a/drivers/block/paride/dstr.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/paride/dstr.c	Wed Jul 24 14:03:37 2002
@@ -16,6 +16,7 @@
 #define DSTR_VERSION      "1.01"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -211,35 +212,33 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol dstr = {"dstr",0,5,2,1,1,
-                           dstr_write_regr,
-                           dstr_read_regr,
-                           dstr_write_block,
-                           dstr_read_block,
-                           dstr_connect,
-                           dstr_disconnect,
-                           0,
-                           0,
-                           0,
-                           dstr_log_adapter,
-                           dstr_init_proto,
-                           dstr_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &dstr ) - 1;
+static struct pi_protocol dstr = {
+	.name		= "dstr",
+	.max_mode	= 5,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= dstr_write_regr,
+	.read_regr	= dstr_read_regr,
+	.write_block	= dstr_write_block,
+	.read_block	= dstr_read_block,
+	.connect	= dstr_connect,
+	.disconnect	= dstr_disconnect,
+	.log_adapter	= dstr_log_adapter,
+	.init_proto	= dstr_init_proto,
+	.release_proto	= dstr_release_proto,
+};
+
+static int __init dstr_init(void)
+{
+	return pi_register(&dstr)-1;
+}
+
+static void __exit dstr_exit(void)
+{
+	pi_unregister(&dstr);
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &dstr );
-}
-
-#endif
-
-/* end of dstr.c */
 MODULE_LICENSE("GPL");
+module_init(dstr_init)
+module_exit(dstr_exit)
diff -Nru a/drivers/block/paride/epat.c b/drivers/block/paride/epat.c
--- a/drivers/block/paride/epat.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/block/paride/epat.c	Wed Jul 24 14:03:39 2002
@@ -19,6 +19,7 @@
 #define EPAT_VERSION      "1.02"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -311,35 +312,34 @@
 {	MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol epat = {"epat",0,6,3,1,1,
-			   epat_write_regr,
-			   epat_read_regr,
-			   epat_write_block,
-			   epat_read_block,
-			   epat_connect,
-			   epat_disconnect,
-			   0,
-			   0,
-			   epat_test_proto,
-			   epat_log_adapter,
-			   epat_init_proto,
-			   epat_release_proto
-			  };
-
-
-#ifdef MODULE
-
-int	init_module(void)
-
-{	return pi_register( &epat) - 1;
+static struct pi_protocol epat = {
+	.name		= "epat",
+	.max_mode	= 6,
+	.epp_first	= 3,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= epat_write_regr,
+	.read_regr	= epat_read_regr,
+	.write_block	= epat_write_block,
+	.read_block	= epat_read_block,
+	.connect	= epat_connect,
+	.disconnect	= epat_disconnect,
+	.test_proto	= epat_test_proto,
+	.log_adapter	= epat_log_adapter,
+	.init_proto	= epat_init_proto,
+	.release_proto	= epat_release_proto,
+};
+
+static int __init epat_init(void)
+{
+	return pi_register(&epat)-1;
+}
+
+static void __exit epat_exit(void)
+{
+	pi_unregister(&epat);
 }
 
-void	cleanup_module(void)
-
-{	pi_unregister( &epat);
-}
-
-#endif
-
-/* end of epat.c */
 MODULE_LICENSE("GPL");
+module_init(epat_init)
+module_exit(epat_exit)
diff -Nru a/drivers/block/paride/epia.c b/drivers/block/paride/epia.c
--- a/drivers/block/paride/epia.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/paride/epia.c	Wed Jul 24 14:03:37 2002
@@ -20,6 +20,7 @@
 #define EPIA_VERSION      "1.02"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -293,36 +294,34 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol epia = {"epia",0,6,3,1,1,
-                           epia_write_regr,
-                           epia_read_regr,
-                           epia_write_block,
-                           epia_read_block,
-                           epia_connect,
-                           epia_disconnect,
-                           0,
-                           0,
-                           epia_test_proto,
-                           epia_log_adapter,
-                           epia_init_proto,
-                           epia_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &epia ) - 1;
+static struct pi_protocol epia = {
+	.name		= "epia",
+	.max_mode	= 6,
+	.epp_first	= 3,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= epia_write_regr,
+	.read_regr	= epia_read_regr,
+	.write_block	= epia_write_block,
+	.read_block	= epia_read_block,
+	.connect	= epia_connect,
+	.disconnect	= epia_disconnect,
+	.test_proto	= epia_test_proto,
+	.log_adapter	= epia_log_adapter,
+	.init_proto	= epia_init_proto,
+	.release_proto	= epia_release_proto,
+};
+
+static int __init epia_init(void)
+{
+	return pi_register(&epia)-1;
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &epia );
+static void __exit epia_exit(void)
+{
+	pi_unregister(&epia);
 }
 
-#endif
-
-/* end of epia.c */
-
 MODULE_LICENSE("GPL");
+module_init(epia_init)
+module_exit(epia_exit)
diff -Nru a/drivers/block/paride/fit2.c b/drivers/block/paride/fit2.c
--- a/drivers/block/paride/fit2.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/block/paride/fit2.c	Wed Jul 24 14:03:38 2002
@@ -16,6 +16,7 @@
 #define FIT2_VERSION      "1.0"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -129,35 +130,33 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol fit2 = {"fit2",0,1,2,1,1,
-                           fit2_write_regr,
-                           fit2_read_regr,
-                           fit2_write_block,
-                           fit2_read_block,
-                           fit2_connect,
-                           fit2_disconnect,
-                           0,
-                           0,
-                           0,
-                           fit2_log_adapter,
-                           fit2_init_proto,
-                           fit2_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &fit2 ) - 1;
+static struct pi_protocol fit2 = {
+	.name		= "fit2",
+	.max_mode	= 1,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= fit2_write_regr,
+	.read_regr	= fit2_read_regr,
+	.write_block	= fit2_write_block,
+	.read_block	= fit2_read_block,
+	.connect	= fit2_connect,
+	.disconnect	= fit2_disconnect,
+	.log_adapter	= fit2_log_adapter,
+	.init_proto	= fit2_init_proto,
+	.release_proto	= fit2_release_proto,
+};
+
+static int __init fit2_init(void)
+{
+	return pi_register(&fit2)-1;
+}
+
+static void __exit fit2_exit(void)
+{
+	pi_unregister(&fit2);
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &fit2 );
-}
-
-#endif
-
-/* end of fit2.c */
 MODULE_LICENSE("GPL");
+module_init(fit2_init)
+module_exit(fit2_exit)
diff -Nru a/drivers/block/paride/fit3.c b/drivers/block/paride/fit3.c
--- a/drivers/block/paride/fit3.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/paride/fit3.c	Wed Jul 24 14:03:37 2002
@@ -20,6 +20,7 @@
 #define FIT3_VERSION      "1.0"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -189,35 +190,33 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol fit3 = {"fit3",0,3,2,1,1,
-                           fit3_write_regr,
-                           fit3_read_regr,
-                           fit3_write_block,
-                           fit3_read_block,
-                           fit3_connect,
-                           fit3_disconnect,
-                           0,
-                           0,
-                           0,
-                           fit3_log_adapter,
-                           fit3_init_proto,
-                           fit3_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &fit3 ) - 1;
+static struct pi_protocol fit3 = {
+	.name		= "fit3",
+	.max_mode	= 3,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= fit3_write_regr,
+	.read_regr	= fit3_read_regr,
+	.write_block	= fit3_write_block,
+	.read_block	= fit3_read_block,
+	.connect	= fit3_connect,
+	.disconnect	= fit3_disconnect,
+	.log_adapter	= fit3_log_adapter,
+	.init_proto	= fit3_init_proto,
+	.release_proto	= fit3_release_proto,
+};
+
+static int __init fit3_init(void)
+{
+	return pi_register(&fit3)-1;
+}
+
+static void __exit fit3_exit(void)
+{
+	pi_unregister(&fit3);
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &fit3 );
-}
-
-#endif
-
-/* end of fit3.c */
 MODULE_LICENSE("GPL");
+module_init(fit3_init)
+module_exit(fit3_exit)
diff -Nru a/drivers/block/paride/friq.c b/drivers/block/paride/friq.c
--- a/drivers/block/paride/friq.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/block/paride/friq.c	Wed Jul 24 14:03:39 2002
@@ -28,6 +28,7 @@
 #define	FRIQ_VERSION	"1.01" 
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -250,35 +251,34 @@
 	MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol friq = {"friq",0,5,2,1,1,
-                           friq_write_regr,
-                           friq_read_regr,
-                           friq_write_block,
-                           friq_read_block,
-                           friq_connect,
-                           friq_disconnect,
-                           0,
-                           0,
-                           friq_test_proto,
-                           friq_log_adapter,
-                           friq_init_proto,
-                           friq_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &friq ) - 1;
+static struct pi_protocol friq = {
+	.name		= "friq",
+	.max_mode	= 5,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= friq_write_regr,
+	.read_regr	= friq_read_regr,
+	.write_block	= friq_write_block,
+	.read_block	= friq_read_block,
+	.connect	= friq_connect,
+	.disconnect	= friq_disconnect,
+	.test_proto	= friq_test_proto,
+	.log_adapter	= friq_log_adapter,
+	.init_proto	= friq_init_proto,
+	.release_proto	= friq_release_proto,
+};
+
+static int __init friq_init(void)
+{
+	return pi_register(&friq)-1;
+}
+
+static void __exit friq_exit(void)
+{
+	pi_unregister(&friq);
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &friq );
-}
-
-#endif
-
-/* end of friq.c */
 MODULE_LICENSE("GPL");
+module_init(friq_init)
+module_exit(friq_exit)
diff -Nru a/drivers/block/paride/frpw.c b/drivers/block/paride/frpw.c
--- a/drivers/block/paride/frpw.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/block/paride/frpw.c	Wed Jul 24 14:03:39 2002
@@ -26,6 +26,7 @@
 #define	FRPW_VERSION	"1.03" 
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -291,35 +292,34 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol frpw = {"frpw",0,6,2,2,1,
-                           frpw_write_regr,
-                           frpw_read_regr,
-                           frpw_write_block,
-                           frpw_read_block,
-                           frpw_connect,
-                           frpw_disconnect,
-                           0,
-                           0,
-                           frpw_test_proto,
-                           frpw_log_adapter,
-                           frpw_init_proto,
-                           frpw_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &frpw ) - 1;
+static struct pi_protocol frpw = {
+	.name		= "frpw",
+	.max_mode	= 6,
+	.epp_first	= 2,
+	.default_delay	= 2,
+	.max_units	= 1,
+	.write_regr	= frpw_write_regr,
+	.read_regr	= frpw_read_regr,
+	.write_block	= frpw_write_block,
+	.read_block	= frpw_read_block,
+	.connect	= frpw_connect,
+	.disconnect	= frpw_disconnect,
+	.test_proto	= frpw_test_proto,
+	.log_adapter	= frpw_log_adapter,
+	.init_proto	= frpw_init_proto,
+	.release_proto	= frpw_release_proto,
+};
+
+static int __init frpw_init(void)
+{
+	return pi_register(&frpw)-1;
+}
+
+static void __exit frpw_exit(void)
+{
+	pi_unregister(&frpw);
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &frpw );
-}
-
-#endif
-
-/* end of frpw.c */
 MODULE_LICENSE("GPL");
+module_init(frpw_init)
+module_exit(frpw_exit)
diff -Nru a/drivers/block/paride/kbic.c b/drivers/block/paride/kbic.c
--- a/drivers/block/paride/kbic.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/block/paride/kbic.c	Wed Jul 24 14:03:39 2002
@@ -21,6 +21,7 @@
 #define KBIC_VERSION      "1.01"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -258,56 +259,51 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol k951 = {"k951",0,6,3,1,1,
-                           kbic_write_regr,
-                           kbic_read_regr,
-                           kbic_write_block,
-                           kbic_read_block,
-                           k951_connect,
-                           k951_disconnect,
-                           0,
-                           0,
-                           0,
-                           k951_log_adapter,
-                           kbic_init_proto,
-                           kbic_release_proto
-  			  };
-
-
-struct pi_protocol k971 = {"k971",0,6,3,1,1,
-                           kbic_write_regr,
-                           kbic_read_regr,
-                           kbic_write_block,
-                           kbic_read_block,
-                           k971_connect,
-                           k971_disconnect,
-                           0,
-                           0,
-                           0,
-                           k971_log_adapter,
-                           kbic_init_proto,
-                           kbic_release_proto
-                          };
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       int s5,s7;
-
-	s5 = pi_register(&k951);
-	s7 = pi_register(&k971);
-
-	return (s5 || s7) - 1;
-}
-
-void    cleanup_module(void)
-
-{       pi_unregister( &k951 );
-	pi_unregister( &k971 );
+static struct pi_protocol k951 = {
+	.name		= "k951",
+	.max_mode	= 6,
+	.epp_first	= 3,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= kbic_write_regr,
+	.read_regr	= kbic_read_regr,
+	.write_block	= kbic_write_block,
+	.read_block	= kbic_read_block,
+	.connect	= k951_connect,
+	.disconnect	= k951_disconnect,
+	.log_adapter	= k951_log_adapter,
+	.init_proto	= kbic_init_proto,
+	.release_proto	= kbic_release_proto
+};
+
+static struct pi_protocol k971 = {
+	.name		= "k971",
+	.max_mode	= 6,
+	.epp_first	= 3,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= kbic_write_regr,
+	.read_regr	= kbic_read_regr,
+	.write_block	= kbic_write_block,
+	.read_block	= kbic_read_block,
+	.connect	= k971_connect,
+	.disconnect	= k971_disconnect,
+	.log_adapter	= k971_log_adapter,
+	.init_proto	= kbic_init_proto,
+	.release_proto	= kbic_release_proto
+};
+
+static int __init kbic_init(void)
+{
+	return (pi_register(&k951)||pi_register(&k971))-1;
+}
+
+static void __exit kbic_exit(void)
+{
+	pi_unregister(&k951);
+	pi_unregister(&k971);
 }
 
-#endif
-
-/* end of kbic.c */
 MODULE_LICENSE("GPL");
+module_init(kbic_init)
+module_exit(kbic_exit)
diff -Nru a/drivers/block/paride/ktti.c b/drivers/block/paride/ktti.c
--- a/drivers/block/paride/ktti.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/paride/ktti.c	Wed Jul 24 14:03:37 2002
@@ -12,6 +12,7 @@
 #define KTTI_VERSION      "1.0"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -106,35 +107,33 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol ktti = {"ktti",0,1,2,1,1,
-                           ktti_write_regr,
-                           ktti_read_regr,
-                           ktti_write_block,
-                           ktti_read_block,
-                           ktti_connect,
-                           ktti_disconnect,
-                           0,
-                           0,
-                           0,
-                           ktti_log_adapter,
-                           ktti_init_proto,
-                           ktti_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &ktti ) - 1;
+static struct pi_protocol ktti = {
+	.name		= "ktti",
+	.max_mode	= 1,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= ktti_write_regr,
+	.read_regr	= ktti_read_regr,
+	.write_block	= ktti_write_block,
+	.read_block	= ktti_read_block,
+	.connect	= ktti_connect,
+	.disconnect	= ktti_disconnect,
+	.log_adapter	= ktti_log_adapter,
+	.init_proto	= ktti_init_proto,
+	.release_proto	= ktti_release_proto,
+};
+
+static int __init ktti_init(void)
+{
+	return pi_register(&ktti)-1;
+}
+
+static void __exit ktti_exit(void)
+{
+	pi_unregister(&ktti);
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &ktti );
-}
-
-#endif
-
-/* end of ktti.c */
 MODULE_LICENSE("GPL");
+module_init(ktti_init)
+module_exit(ktti_exit)
diff -Nru a/drivers/block/paride/on20.c b/drivers/block/paride/on20.c
--- a/drivers/block/paride/on20.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/paride/on20.c	Wed Jul 24 14:03:37 2002
@@ -15,6 +15,7 @@
 #define	ON20_VERSION	"1.01"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -131,35 +132,33 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol on20 = {"on20",0,2,2,1,1,
-                           on20_write_regr,
-                           on20_read_regr,
-                           on20_write_block,
-                           on20_read_block,
-                           on20_connect,
-                           on20_disconnect,
-                           0,
-                           0,
-                           0,
-                           on20_log_adapter,
-                           on20_init_proto,
-                           on20_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &on20 ) - 1;
+static struct pi_protocol on20 = {
+	.name		= "on20",
+	.max_mode	= 2,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= on20_write_regr,
+	.read_regr	= on20_read_regr,
+	.write_block	= on20_write_block,
+	.read_block	= on20_read_block,
+	.connect	= on20_connect,
+	.disconnect	= on20_disconnect,
+	.log_adapter	= on20_log_adapter,
+	.init_proto	= on20_init_proto,
+	.release_proto	= on20_release_proto,
+};
+
+static int __init on20_init(void)
+{
+	return pi_register(&on20)-1;
+}
+
+static void __exit on20_exit(void)
+{
+	pi_unregister(&on20);
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &on20 );
-}
-
-#endif
-
-/* end of on20.c */
 MODULE_LICENSE("GPL");
+module_init(on20_init)
+module_exit(on20_exit)
diff -Nru a/drivers/block/paride/on26.c b/drivers/block/paride/on26.c
--- a/drivers/block/paride/on26.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/paride/on26.c	Wed Jul 24 14:03:37 2002
@@ -19,6 +19,7 @@
 #define ON26_VERSION      "1.04"
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -296,36 +297,34 @@
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol on26 = {"on26",0,5,2,1,1,
-                           on26_write_regr,
-                           on26_read_regr,
-                           on26_write_block,
-                           on26_read_block,
-                           on26_connect,
-                           on26_disconnect,
-                           on26_test_port,
-                           0,
-                           0,
-                           on26_log_adapter,
-                           on26_init_proto,
-                           on26_release_proto
-                          };
-
-
-#ifdef MODULE
-
-int     init_module(void)
-
-{       return pi_register( &on26 ) - 1;
+static struct pi_protocol on26 = {
+	.name		= "on26",
+	.max_mode	= 5,
+	.epp_first	= 2,
+	.default_delay	= 1,
+	.max_units	= 1,
+	.write_regr	= on26_write_regr,
+	.read_regr	= on26_read_regr,
+	.write_block	= on26_write_block,
+	.read_block	= on26_read_block,
+	.connect	= on26_connect,
+	.disconnect	= on26_disconnect,
+	.test_port	= on26_test_port,
+	.log_adapter	= on26_log_adapter,
+	.init_proto	= on26_init_proto,
+	.release_proto	= on26_release_proto,
+};
+
+static int __init on26_init(void)
+{
+	return pi_register(&on26)-1;
 }
 
-void    cleanup_module(void)
-
-{       pi_unregister( &on26 );
+static void __exit on26_exit(void)
+{
+	pi_unregister(&on26);
 }
 
-#endif
-
-/* end of on26.c */
-
 MODULE_LICENSE("GPL");
+module_init(on26_init)
+module_exit(on26_exit)
diff -Nru a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c
--- a/drivers/block/paride/paride.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/block/paride/paride.c	Wed Jul 24 14:03:36 2002
@@ -431,136 +431,3 @@
 }
 
 EXPORT_SYMBOL(pi_init);
-
-#ifdef MODULE
-
-int	init_module(void)
-
-{
-	int k;
-	const char *indicate_pp = "";
-#ifdef CONFIG_PARPORT
-	indicate_pp = " (parport)";
-#endif
-
-	for (k=0;k<MAX_PROTOS;k++) protocols[k] = 0;
-
-	printk("paride: version %s installed%s\n",PI_VERSION,indicate_pp);
-	return 0;
-}
-
-void	cleanup_module(void)
-
-{
-}
-
-#else
-
-void	paride_init( void )
-
-{
-
-#ifdef CONFIG_PARIDE_ATEN
-	{ extern struct pi_protocol aten;
-	  pi_register(&aten);
-	};
-#endif
-#ifdef CONFIG_PARIDE_BPCK
-        { extern struct pi_protocol bpck;
-          pi_register(&bpck);
-        };
-#endif
-#ifdef CONFIG_PARIDE_COMM
-        { extern struct pi_protocol comm;
-          pi_register(&comm);
-        };
-#endif
-#ifdef CONFIG_PARIDE_DSTR
-        { extern struct pi_protocol dstr;
-          pi_register(&dstr);
-        };
-#endif
-#ifdef CONFIG_PARIDE_EPAT
-        { extern struct pi_protocol epat;
-          pi_register(&epat);
-        };
-#endif
-#ifdef CONFIG_PARIDE_EPIA
-        { extern struct pi_protocol epia;
-          pi_register(&epia);
-        };
-#endif
-#ifdef CONFIG_PARIDE_FRPW
-        { extern struct pi_protocol frpw;
-          pi_register(&frpw);
-        };
-#endif
-#ifdef CONFIG_PARIDE_FRIQ
-        { extern struct pi_protocol friq;
-          pi_register(&friq);
-        };
-#endif 
-#ifdef CONFIG_PARIDE_FIT2
-        { extern struct pi_protocol fit2;
-          pi_register(&fit2);
-        };
-#endif
-#ifdef CONFIG_PARIDE_FIT3
-        { extern struct pi_protocol fit3;
-          pi_register(&fit3);
-        };
-#endif
-#ifdef CONFIG_PARIDE_KBIC
-        { extern struct pi_protocol k951;
-          extern struct pi_protocol k971;
-          pi_register(&k951);
-          pi_register(&k971);
-        };
-#endif
-#ifdef CONFIG_PARIDE_KTTI
-        { extern struct pi_protocol ktti;
-          pi_register(&ktti);
-        };
-#endif
-#ifdef CONFIG_PARIDE_ON20
-        { extern struct pi_protocol on20;
-          pi_register(&on20);
-        };
-#endif
-#ifdef CONFIG_PARIDE_ON26
-        { extern struct pi_protocol on26;
-          pi_register(&on26);
-        };
-#endif
-
-#ifdef CONFIG_PARIDE_PD
-	{ extern int pd_init(void);
-	  pd_init();
-	};
-#endif
-#ifdef CONFIG_PARIDE_PCD
-        { extern int pcd_init(void);
-          pcd_init();
-        };
-#endif
-#ifdef CONFIG_PARIDE_PF
-        { extern int pf_init(void);
-          pf_init();
-        };
-#endif
-#ifdef CONFIG_PARIDE_PT
-        { extern int pt_init(void);
-          pt_init();
-        };
-#endif
-#ifdef CONFIG_PARIDE_PG
-        { extern int pg_init(void);
-          pg_init();
-        };
-#endif
-}
-
-#endif
-
-/* end of paride.c */
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
--- a/drivers/block/paride/pcd.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/block/paride/pcd.c	Wed Jul 24 14:03:38 2002
@@ -137,6 +137,7 @@
 /* end of parameters */
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
@@ -200,9 +201,6 @@
 #define IDE_READY       0x40
 #define IDE_BUSY        0x80
 
-int pcd_init(void);
-void cleanup_module( void );
-
 static int pcd_open(struct cdrom_device_info *cdi, int purpose);
 static void pcd_release(struct cdrom_device_info *cdi);
 static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
@@ -327,84 +325,18 @@
         }
 }
 
-int pcd_init (void)	/* preliminary initialisation */
-{
-	int unit;
-
-	if (disable) return -1;
-
-	pcd_init_units();
-
-	if (pcd_detect()) return -1;
-
-	/* get the atapi capabilities page */
-	pcd_probe_capabilities();
-
-	if (register_blkdev(MAJOR_NR,name,&pcd_bdops)) {
-		printk("pcd: unable to get major number %d\n",MAJOR_NR);
-		return -1;
-	}
-
-	for (unit=0;unit<PCD_UNITS;unit++) {
-		if (PCD.present) {
-			register_cdrom(&PCD.info);
-			devfs_plain_cdrom(&PCD.info, &pcd_bdops);
-		}
-	}
-
-	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_pcd_request, &pcd_lock);
-
-	return 0;
-}
-
 static int pcd_open(struct cdrom_device_info *cdi, int purpose)
-
-{	int unit = DEVICE_NR(cdi->dev);
-
-	if  ((unit >= PCD_UNITS) || (!PCD.present)) return -ENODEV;
-
+{
+	int unit = DEVICE_NR(cdi->dev);
+	if  ((unit >= PCD_UNITS) || (!PCD.present))
+		return -ENODEV;
 	return 0;
 }
 
 static void pcd_release(struct cdrom_device_info *cdi)
-
 {
 }
 
-#ifdef MODULE
-
-/* Glue for modules ... */
-
-int	init_module(void)
-
-{	int	err;
-
-#ifdef PARIDE_JUMBO
-       { extern paride_init();
-         paride_init();
-       } 
-#endif
-
-	err = pcd_init();
-
-	return err;
-}
-
-void	cleanup_module(void)
-
-{	int unit;
-	
-        for (unit=0;unit<PCD_UNITS;unit++) 
-           if (PCD.present) {
-		pi_release(PI);
-		unregister_cdrom(&PCD.info);
-	   }
-
-	unregister_blkdev(MAJOR_NR,name);
-}
-
-#endif
-
 #define WR(c,r,v)       pi_write_regr(PI,c,r,v)
 #define RR(c,r)         (pi_read_regr(PI,c,r))
 
@@ -950,6 +882,50 @@
 	return 0;
 }
 
-/* end of pcd.c */
+
+static int __init pcd_init(void)
+{
+	int unit;
+
+	if (disable)
+		return -1;
+
+	pcd_init_units();
+
+	if (pcd_detect())
+		return -1;
+
+	/* get the atapi capabilities page */
+	pcd_probe_capabilities();
+
+	if (register_blkdev(MAJOR_NR,name,&pcd_bdops)) {
+		printk("pcd: unable to get major number %d\n",MAJOR_NR);
+		return -1;
+	}
+
+	for (unit=0;unit<PCD_UNITS;unit++) {
+		if (PCD.present) {
+			register_cdrom(&PCD.info);
+			devfs_plain_cdrom(&PCD.info, &pcd_bdops);
+		}
+	}
+
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_pcd_request, &pcd_lock);
+
+	return 0;
+}
+
+static void __exit pcd_exit(void)
+{
+	int unit;
+	for (unit=0;unit<PCD_UNITS;unit++) 
+		if (PCD.present) {
+			pi_release(PI);
+			unregister_cdrom(&PCD.info);
+		}
+	unregister_blkdev(MAJOR_NR,name);
+}
 
 MODULE_LICENSE("GPL");
+module_init(pcd_init)
+module_exit(pcd_exit)
diff -Nru a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
--- a/drivers/block/paride/pd.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/block/paride/pd.c	Wed Jul 24 14:03:39 2002
@@ -153,16 +153,12 @@
 
 /* end of parameters */
 
+#include <linux/init.h>
 #include <linux/module.h>
-#include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/kernel.h>
 #include <linux/delay.h>
-#include <linux/genhd.h>
 #include <linux/hdreg.h>
 #include <linux/cdrom.h>	/* for the eject ioctl */
-#include <linux/spinlock.h>
 
 #include <asm/uaccess.h>
 
@@ -181,8 +177,8 @@
 		        {"nice",1,&nice}};
 
 void pd_setup( char *str, int *ints)
-
-{	generic_setup(pd_stt,7,str);
+{
+	generic_setup(pd_stt,7,str);
 }
 
 #endif
@@ -199,19 +195,15 @@
 
 #include "paride.h"
 
-#define PD_BITS    4
-
-/* set up defines for blk.h,  why don't all drivers do it this way ? */
-
 #define MAJOR_NR   major
-#define DEVICE_NR(device) (minor(device)>>PD_BITS)
-#define DEVICE_OFF(device)
 
 #include <linux/blk.h>
 #include <linux/blkpg.h>
 
 #include "pseudo.h"
 
+#define PD_BITS    4
+#define DEVICE_NR(device) (minor(device)>>PD_BITS)
 #define PD_PARTNS  	(1<<PD_BITS)
 #define PD_DEVS		PD_PARTNS*PD_UNITS
 
@@ -258,11 +250,7 @@
 #define IDE_IDENTIFY    	0xec
 #define IDE_EJECT		0xed
 
-int pd_init(void);
 void pd_setup(char * str, int * ints);
-#ifdef MODULE
-void cleanup_module( void );
-#endif
 static int pd_open(struct inode *inode, struct file *file);
 static void do_pd_request(request_queue_t * q);
 static int pd_ioctl(struct inode *inode,struct file *file,
@@ -296,6 +284,7 @@
 	int heads;                	/* physical geometry */
 	int sectors;
 	int cylinders;
+	int can_lba;
 	int drive;			/* master=0 slave=1 */
 	int changed;			/* Have we seen a disk change ? */
 	int removable;			/* removable media device  ?  */
@@ -303,7 +292,7 @@
 	int alt_geom;
 	int present;
 	char name[PD_NAMELEN];		/* pda, pdb, etc ... */
-	};
+};
 
 struct pd_unit pd[PD_UNITS];
 
@@ -312,7 +301,6 @@
 #define PD pd[unit]
 #define PI PD.pi
 
-static int pd_valid = 1;		/* serialise partition checks */
 static char pd_scratch[512];            /* scratch block buffer */
 
 /* the variables below are used mainly in the I/O request engine, which
@@ -379,47 +367,12 @@
 	}
 }
 
-int pd_init (void)
-{
-	request_queue_t * q;
-
-	if (disable) return -1;
-        if (devfs_register_blkdev(MAJOR_NR,name,&pd_fops)) {
-                printk("%s: unable to get major number %d\n",
-                        name,major);
-                return -1;
-        }
-	q = BLK_DEFAULT_QUEUE(MAJOR_NR);
-	blk_init_queue(q, do_pd_request, &pd_lock);
-	blk_queue_max_sectors(q, cluster);
-
-	pd_gendisk.major = major;
-	pd_gendisk.major_name = name;
-	add_gendisk(&pd_gendisk);
-
-	printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
-		name,name,PD_VERSION,major,cluster,nice);
-	pd_init_units();
-	pd_valid = 0;
-	pd_gendisk.nr_real = pd_detect();
-	pd_valid = 1;
-
-#ifdef MODULE
-        if (!pd_gendisk.nr_real) {
-		cleanup_module();
-		return -1;
-	}
-#endif
-        return 0;
-}
-
 static int pd_open (struct inode *inode, struct file *file)
+{
+	int unit = DEVICE_NR(inode->i_rdev);
 
-{       int unit = DEVICE_NR(inode->i_rdev);
-
-        if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;
-
-	wait_event (pd_wait_open, pd_valid);
+        if ((unit >= PD_UNITS) || (!PD.present))
+		return -ENODEV;
 
         PD.access++;
 
@@ -434,11 +387,8 @@
                     unsigned int cmd, unsigned long arg)
 {
 	struct hd_geometry *geo = (struct hd_geometry *) arg;
-	int err, unit;
+	int err, unit = DEVICE_NR(inode->i_rdev);
 
-	if (!inode || kdev_none(inode->i_rdev))
-		return -EINVAL;
-	unit = DEVICE_NR(inode->i_rdev);
 	if (!PD.present)
 		return -ENODEV;
 
@@ -461,50 +411,34 @@
 		    put_user(PD.heads, (char *) &geo->heads);
 		    put_user(PD.sectors, (char *) &geo->sectors);
 		}
-		put_user(get_start_sect(inode->i_rdev), (long *)&geo->start);
+		put_user(get_start_sect(inode->i_bdev), (long *)&geo->start);
 		return 0;
 	    case BLKRRPART:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 		return pd_revalidate(inode->i_rdev);
-	    case BLKGETSIZE:
-	    case BLKGETSIZE64:
-	    case BLKROSET:
-	    case BLKROGET:
-	    case BLKFLSBUF:
-	    case BLKPG:
-		return blk_ioctl(inode->i_bdev, cmd, arg);
 	    default:
 		return -EINVAL;
 	}
 }
 
 static int pd_release (struct inode *inode, struct file *file)
+{
+	int	unit = DEVICE_NR(inode->i_rdev);
 
-{       kdev_t devp;
-	int	unit;
-
-        devp = inode->i_rdev;
-	unit = DEVICE_NR(devp);
-
-	if ((unit >= PD_UNITS) || (PD.access <= 0)) 
-		return -EINVAL;
-
-	PD.access--;
-
-        if (!PD.access && PD.removable)
+        if (!--PD.access && PD.removable)
 		pd_doorlock(unit,IDE_DOORUNLOCK);
 
 	return 0;
 }
 
 static int pd_check_media( kdev_t dev)
-
-{       int r, unit;
-
-	unit = DEVICE_NR(dev);
-	if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;
-        if (!PD.removable) return 0;
+{
+	int r, unit = DEVICE_NR(dev);
+	if ((unit >= PD_UNITS) || (!PD.present))
+		return -ENODEV;
+        if (!PD.removable)
+		return 0;
 	pd_media_check(unit);
 	r = PD.changed;
 	PD.changed = 0;
@@ -513,64 +447,26 @@
 
 static int pd_revalidate(kdev_t dev)
 {
-	int unit, res;
-	long flags;
+	int unit = DEVICE_NR(dev);
+	kdev_t device = mk_kdev(MAJOR_NR, unit << PD_BITS);
+	int res;
 
-	unit = DEVICE_NR(dev);
 	if ((unit >= PD_UNITS) || !PD.present)
 		return -ENODEV;
 
-	save_flags(flags);
-	cli(); 
-	if (PD.access > 1) {
-		restore_flags(flags);
-		return -EBUSY;
-	}
-	pd_valid = 0;
-	restore_flags(flags);   
-
-	res = wipe_partitions(dev);
+	res = dev_lock_part(device);
+	if (res < 0)
+		return res;
+	res = wipe_partitions(device);
 
 	if (res == 0 && pd_identify(unit))
-		grok_partitions(dev, PD.capacity);
+		grok_partitions(device, PD.capacity);
 
-	pd_valid = 1;
-	wake_up(&pd_wait_open);
+	dev_unlock_part(device);
  
         return res;
 }
 
-#ifdef MODULE
-
-/* Glue for modules ... */
-
-void    cleanup_module(void);
-
-int     init_module(void)
-
-{
-
-#ifdef PARIDE_JUMBO
-       { extern paride_init();
-         paride_init();
-       } 
-#endif
-        return pd_init();
-}
-
-void    cleanup_module(void)
-{
-	int unit;
-
-	devfs_unregister_blkdev(MAJOR_NR, name);
-	del_gendisk(&pd_gendisk);
-
-	for (unit=0; unit<PD_UNITS; unit++) 
-		if (PD.present)
-			pi_release(PI);
-}
-#endif
-
 #define	WR(c,r,v)	pi_write_regr(PI,c,r,v)
 #define	RR(c,r)		(pi_read_regr(PI,c,r))
 
@@ -619,7 +515,6 @@
 
 static void pd_send_command( int unit, int n, int s, int h, 
 			     int c0, int c1, int func )
-
 {
         WR(0,6,DRIVE+h);
         WR(0,1,0);                /* the IDE task file */
@@ -633,16 +528,20 @@
 }
 
 static void pd_ide_command( int unit, int func, int block, int count )
+{
+	int c1, c0, h, s;
 
-/* Don't use this call if the capacity is zero. */
-
-{       int c1, c0, h, s;
-
-        s  = ( block % PD.sectors) + 1;
-        h  = ( block / PD.sectors) % PD.heads;
-        c0 = ( block / (PD.sectors*PD.heads)) % 256;
-        c1 = ( block / (PD.sectors*PD.heads*256));
-
+	if (PD.can_lba) {
+		s = block & 255;
+		c0 = (block >>= 8) & 255;
+		c1 = (block >>= 8) & 255;
+		h = ((block >>= 8) & 15) + 0x40;
+	} else {
+		s  = ( block % PD.sectors) + 1;
+		h  = ( block /= PD.sectors) % PD.heads;
+		c0 = ( block /= PD.heads) % 256;
+		c1 = (block >>= 8);
+	}
         pd_send_command(unit,count,s,h,c0,c1,func);
 }
 
@@ -742,10 +641,14 @@
         }
         pi_read_block(PI,pd_scratch,512);
         pi_disconnect(PI);
-        PD.sectors = word_val(6);
-        PD.heads = word_val(3);
-        PD.cylinders  = word_val(1);
-        PD.capacity = PD.sectors*PD.heads*PD.cylinders;
+	PD.can_lba = pd_scratch[99] & 2;
+	PD.sectors = le16_to_cpu(*(u16*)(pd_scratch+12));
+	PD.heads = le16_to_cpu(*(u16*)(pd_scratch+6));
+	PD.cylinders  = le16_to_cpu(*(u16*)(pd_scratch+2));
+	if (PD.can_lba)
+		PD.capacity = le32_to_cpu(*(u32*)(pd_scratch + 120));
+	else
+		PD.capacity = PD.sectors*PD.heads*PD.cylinders;
 
         for(j=0;j<PD_ID_LEN;j++) id[j^1] = pd_scratch[j+PD_ID_OFF];
         j = PD_ID_LEN-1;
@@ -763,7 +666,7 @@
 
         if (PD.capacity) pd_init_dev_parms(unit);
         if (!PD.standby) pd_standby_off(unit);
-	
+
         return 1;
 }
 
@@ -1031,6 +934,50 @@
 	spin_unlock_irqrestore(&pd_lock,saved_flags);
 }
 
-/* end of pd.c */
+static int __init pd_init(void)
+{
+	request_queue_t * q;
+	int unit;
+
+	if (disable) return -1;
+        if (devfs_register_blkdev(MAJOR_NR,name,&pd_fops)) {
+                printk("%s: unable to get major number %d\n",
+                        name,major);
+                return -1;
+        }
+	q = BLK_DEFAULT_QUEUE(MAJOR_NR);
+	blk_init_queue(q, do_pd_request, &pd_lock);
+	blk_queue_max_sectors(q, cluster);
+
+	pd_gendisk.major = major;
+	pd_gendisk.major_name = name;
+	add_gendisk(&pd_gendisk);
+
+	printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
+		name,name,PD_VERSION,major,cluster,nice);
+	pd_init_units();
+	pd_gendisk.nr_real = pd_detect();
+        if (!pd_gendisk.nr_real) {
+		devfs_unregister_blkdev(MAJOR_NR, name);
+		del_gendisk(&pd_gendisk);
+		for (unit=0; unit<PD_UNITS; unit++) 
+			if (PD.present)
+				pi_release(PI);
+		return -1;
+	}
+        return 0;
+}
+
+static void __exit pd_exit(void)
+{
+	int unit;
+	devfs_unregister_blkdev(MAJOR_NR, name);
+	del_gendisk(&pd_gendisk);
+	for (unit=0; unit<PD_UNITS; unit++) 
+		if (PD.present)
+			pi_release(PI);
+}
 
 MODULE_LICENSE("GPL");
+module_init(pd_init)
+module_exit(pd_exit)
diff -Nru a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
--- a/drivers/block/paride/pf.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/block/paride/pf.c	Wed Jul 24 14:03:36 2002
@@ -153,11 +153,9 @@
 
 
 #include <linux/module.h>
-#include <linux/errno.h>
+#include <linux/init.h>
 #include <linux/fs.h>
-#include <linux/kernel.h>
 #include <linux/delay.h>
-#include <linux/genhd.h>
 #include <linux/hdreg.h>
 #include <linux/cdrom.h>
 #include <linux/spinlock.h>
@@ -240,7 +238,6 @@
 #define ATAPI_READ_10		0x28
 #define ATAPI_WRITE_10		0x2a
 
-int pf_init(void);
 #ifdef MODULE
 void cleanup_module( void );
 #endif
@@ -337,34 +334,6 @@
         }
 } 
 
-int pf_init (void)      /* preliminary initialisation */
-
-{       int i;
-	request_queue_t * q; 
-
-	if (disable) return -1;
-
-	pf_init_units();
-
-	if (pf_detect()) return -1;
-	pf_busy = 0;
-
-        if (register_blkdev(MAJOR_NR,name,&pf_fops)) {
-                printk("pf_init: unable to get major number %d\n",
-                        major);
-                return -1;
-        }
-	q = BLK_DEFAULT_QUEUE(MAJOR_NR);
-	blk_init_queue(q, do_pf_request, &pf_spin_lock);
-	blk_queue_max_phys_segments(q, cluster);
-	blk_queue_max_hw_segments(q, cluster);
-
-	for (i=0;i<PF_UNITS;i++)
-		register_disk(NULL, mk_kdev(MAJOR_NR, i), 1, &pf_fops, 0);
-
-        return 0;
-}
-
 static int pf_open (struct inode *inode, struct file *file)
 
 {       int	unit = DEVICE_NR(inode->i_rdev);
@@ -423,10 +392,6 @@
                 return put_user(PF.capacity,(long *) arg);
             case BLKGETSIZE64:
                 return put_user((u64)PF.capacity << 9,(u64 *)arg);
-	    case BLKROSET:
-	    case BLKROGET:
-	    case BLKFLSBUF:
-		return blk_ioctl(inode->i_bdev, cmd, arg);
             default:
                 return -EINVAL;
         }
@@ -458,39 +423,6 @@
 {       return 1;
 }
 
-#ifdef MODULE
-
-/* Glue for modules ... */
-
-void    cleanup_module(void);
-
-int     init_module(void)
-
-{       int     err;
-
-#ifdef PARIDE_JUMBO
-       { extern paride_init();
-         paride_init();
-       } 
-#endif
-
-        err = pf_init();
-
-        return err;
-}
-
-void    cleanup_module(void)
-
-{       int unit;
-
-        unregister_blkdev(MAJOR_NR,name);
-
-	for (unit=0;unit<PF_UNITS;unit++)
-	  if (PF.present) pi_release(PI);
-}
-
-#endif
-
 #define	WR(c,r,v)	pi_write_regr(PI,c,r,v)
 #define	RR(c,r)		(pi_read_regr(PI,c,r))
 
@@ -1040,6 +972,44 @@
 	spin_unlock_irqrestore(&pf_spin_lock,saved_flags);
 }
 
-/* end of pf.c */
+static int __init pf_init(void)      /* preliminary initialisation */
+{
+	int i;
+	request_queue_t * q; 
+
+	if (disable)
+		return -1;
+
+	pf_init_units();
+
+	if (pf_detect())
+		return -1;
+	pf_busy = 0;
 
+	if (register_blkdev(MAJOR_NR,name,&pf_fops)) {
+		printk("pf_init: unable to get major number %d\n", major);
+		return -1;
+	}
+	q = BLK_DEFAULT_QUEUE(MAJOR_NR);
+	blk_init_queue(q, do_pf_request, &pf_spin_lock);
+	blk_queue_max_phys_segments(q, cluster);
+	blk_queue_max_hw_segments(q, cluster);
+
+	for (i=0;i<PF_UNITS;i++)
+		register_disk(NULL, mk_kdev(MAJOR_NR, i), 1, &pf_fops, 0);
+
+	return 0;
+}
+
+static void __exit pf_exit(void)
+{
+	int unit;
+	unregister_blkdev(MAJOR_NR,name);
+	for (unit=0;unit<PF_UNITS;unit++)
+		if (PF.present)
+			pi_release(PI);
+}
+ 
 MODULE_LICENSE("GPL");
+module_init(pf_init)
+module_exit(pf_exit)
diff -Nru a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
--- a/drivers/block/paride/pg.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/block/paride/pg.c	Wed Jul 24 14:03:39 2002
@@ -162,16 +162,13 @@
 
 
 #include <linux/module.h>
-#include <linux/errno.h>
+#include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/devfs_fs_kernel.h>
-#include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/mtio.h>
 #include <linux/pg.h>
-#include <linux/wait.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 
@@ -218,11 +215,6 @@
 
 #define ATAPI_IDENTIFY		0x12
 
-int pg_init(void);
-#ifdef MODULE
-void cleanup_module( void );
-#endif
-
 static int pg_open(struct inode *inode, struct file *file);
 static int pg_release (struct inode *inode, struct file *file);
 static ssize_t pg_read(struct file * filp, char * buf, 
@@ -291,64 +283,6 @@
 
 static devfs_handle_t devfs_handle;
 
-int pg_init (void)      /* preliminary initialisation */
-
-{       int unit;
-
-	if (disable) return -1;
-
-	pg_init_units();
-
-	if (pg_detect()) return -1;
-
-	if (devfs_register_chrdev(major,name,&pg_fops)) {
-		printk("pg_init: unable to get major number %d\n",
-			major);
-		for (unit=0;unit<PG_UNITS;unit++)
-		  if (PG.present) pi_release(PI);
-		return -1;
-	}
-	devfs_handle = devfs_mk_dir (NULL, "pg", NULL);
-	devfs_register_series (devfs_handle, "%u", 4, DEVFS_FL_DEFAULT,
-			       major, 0, S_IFCHR | S_IRUSR | S_IWUSR,
-			       &pg_fops, NULL);
-	return 0;
-}
-
-#ifdef MODULE
-
-/* Glue for modules ... */
-
-void    cleanup_module(void);
-
-int     init_module(void)
-
-{       int     err;
-
-#ifdef PARIDE_JUMBO
-       { extern paride_init();
-         paride_init();
-       } 
-#endif
-
-	err = pg_init();
-
-	return err;
-}
-
-void    cleanup_module(void)
-
-{       int unit;
-
-	devfs_unregister (devfs_handle);
-	devfs_unregister_chrdev(major,name);
-
-	for (unit=0;unit<PG_UNITS;unit++)
-	  if (PG.present) pi_release(PI);
-}
-
-#endif
-
 #define	WR(c,r,v)	pi_write_regr(PI,c,r,v)
 #define	RR(c,r)		(pi_read_regr(PI,c,r))
 
@@ -691,6 +625,43 @@
 	return copy+hs;
 }
 
-/* end of pg.c */
+static int __init pg_init(void)
+{
+	int unit;
+
+	if (disable)
+		return -1;
+
+	pg_init_units();
+
+	if (pg_detect())
+		return -1;
+
+	if (devfs_register_chrdev(major,name,&pg_fops)) {
+		printk("pg_init: unable to get major number %d\n",
+			major);
+		for (unit=0;unit<PG_UNITS;unit++)
+		  if (PG.present) pi_release(PI);
+		return -1;
+	}
+	devfs_handle = devfs_mk_dir (NULL, "pg", NULL);
+	devfs_register_series (devfs_handle, "%u", 4, DEVFS_FL_DEFAULT,
+			       major, 0, S_IFCHR | S_IRUSR | S_IWUSR,
+			       &pg_fops, NULL);
+	return 0;
+}
+
+static void __exit pg_exit(void)
+{
+	int unit;
+
+	devfs_unregister (devfs_handle);
+	devfs_unregister_chrdev(major,name);
+
+	for (unit=0;unit<PG_UNITS;unit++)
+		if (PG.present) pi_release(PI);
+}
 
 MODULE_LICENSE("GPL");
+module_init(pg_init)
+module_exit(pg_exit)
diff -Nru a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
--- a/drivers/block/paride/pt.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/paride/pt.c	Wed Jul 24 14:03:37 2002
@@ -141,15 +141,12 @@
 
 
 #include <linux/module.h>
-#include <linux/errno.h>
+#include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/devfs_fs_kernel.h>
-#include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/mtio.h>
-#include <linux/wait.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 
@@ -209,11 +206,6 @@
 #define ATAPI_MODE_SENSE	0x1a
 #define ATAPI_LOG_SENSE		0x4d
 
-int pt_init(void);
-#ifdef MODULE
-void cleanup_module( void );
-#endif
-
 static int pt_open(struct inode *inode, struct file *file);
 static int pt_ioctl(struct inode *inode,struct file *file,
                     unsigned int cmd, unsigned long arg);
@@ -291,71 +283,9 @@
                 PT.name[j] = 0;
                 if (DU[D_PRT]) pt_drive_count++;
         }
-} 
-
-static devfs_handle_t devfs_handle;
-
-int pt_init (void)      /* preliminary initialisation */
-
-{       int unit;
-
-	if (disable) return -1;
-
-	pt_init_units();
-
-	if (pt_detect()) return -1;
-
-	if (devfs_register_chrdev(major,name,&pt_fops)) {
-                printk("pt_init: unable to get major number %d\n",
-                        major);
-	        for (unit=0;unit<PT_UNITS;unit++)
-        	  if (PT.present) pi_release(PI);
-                return -1;
-        }
-
-	devfs_handle = devfs_mk_dir (NULL, "pt", NULL);
-	devfs_register_series (devfs_handle, "%u", 4, DEVFS_FL_DEFAULT,
-			       major, 0, S_IFCHR | S_IRUSR | S_IWUSR,
-			       &pt_fops, NULL);
-	devfs_register_series (devfs_handle, "%un", 4, DEVFS_FL_DEFAULT,
-			       major, 128, S_IFCHR | S_IRUSR | S_IWUSR,
-			       &pt_fops, NULL);
-        return 0;
 }
 
-#ifdef MODULE
-
-/* Glue for modules ... */
-
-void    cleanup_module(void);
-
-int     init_module(void)
-
-{       int     err;
-
-#ifdef PARIDE_JUMBO
-       { extern paride_init();
-         paride_init();
-       } 
-#endif
-
-        err = pt_init();
-
-        return err;
-}
-
-void    cleanup_module(void)
-
-{	int unit;
-
-	devfs_unregister (devfs_handle);
-	devfs_unregister_chrdev(major,name);
-
-	for (unit=0;unit<PT_UNITS;unit++)
-	  if (PT.present) pi_release(PI);
-}
-
-#endif
+static devfs_handle_t devfs_handle;
 
 #define	WR(c,r,v)	pi_write_regr(PI,c,r,v)
 #define	RR(c,r)		(pi_read_regr(PI,c,r))
@@ -965,6 +895,46 @@
 	return t;
 }
 
-/* end of pt.c */
+static int __init pt_init(void)
+{
+	int unit;
+
+	if (disable)
+		return -1;
+
+	pt_init_units();
+
+	if (pt_detect())
+		return -1;
+
+	if (devfs_register_chrdev(major,name,&pt_fops)) {
+		printk("pt_init: unable to get major number %d\n",
+			major);
+		for (unit=0;unit<PT_UNITS;unit++)
+			if (PT.present) pi_release(PI);
+		return -1;
+	}
+
+	devfs_handle = devfs_mk_dir (NULL, "pt", NULL);
+	devfs_register_series (devfs_handle, "%u", 4, DEVFS_FL_DEFAULT,
+			       major, 0, S_IFCHR | S_IRUSR | S_IWUSR,
+			       &pt_fops, NULL);
+	devfs_register_series (devfs_handle, "%un", 4, DEVFS_FL_DEFAULT,
+			       major, 128, S_IFCHR | S_IRUSR | S_IWUSR,
+			       &pt_fops, NULL);
+	return 0;
+}
+
+static void __exit pt_exit(void)
+{
+	int unit;
+	devfs_unregister (devfs_handle);
+	devfs_unregister_chrdev(major,name);
+	for (unit=0;unit<PT_UNITS;unit++)
+		if (PT.present)
+			pi_release(PI);
+}
 
 MODULE_LICENSE("GPL");
+module_init(pt_init)
+module_exit(pt_exit)
diff -Nru a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
--- a/drivers/block/ps2esdi.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/block/ps2esdi.c	Wed Jul 24 14:03:35 2002
@@ -93,8 +93,6 @@
 
 static int ps2esdi_open(struct inode *inode, struct file *file);
 
-static int ps2esdi_release(struct inode *inode, struct file *file);
-
 static int ps2esdi_ioctl(struct inode *inode, struct file *file,
 			 u_int cmd, u_long arg);
 
@@ -111,11 +109,8 @@
 static u_int dma_arb_level;		/* DMA arbitration level */
 
 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
-static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_wait_open);
 
 static int no_int_yet;
-static int access_count[MAX_HD];
-static char ps2esdi_valid[MAX_HD];
 static int ps2esdi_sizes[MAX_HD << 6];
 static int ps2esdi_drives;
 static struct hd_struct ps2esdi[MAX_HD << 6];
@@ -152,7 +147,6 @@
 {
 	owner:		THIS_MODULE,
 	open:		ps2esdi_open,
-	release:	ps2esdi_release,
 	ioctl:		ps2esdi_ioctl,
 };
 
@@ -441,13 +435,11 @@
 	}
 	blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), 128);
 
-	for (i = 0; i < ps2esdi_drives; i++) {
+	for (i = 0; i < ps2esdi_drives; i++)
 		register_disk(&ps2esdi_gendisk,mk_kdev(MAJOR_NR,i<<6),1<<6,
 				&ps2esdi_fops,
 				ps2esdi_info[i].head * ps2esdi_info[i].sect *
 				ps2esdi_info[i].cyl);
-		ps2esdi_valid[i] = 1;
-	}
 	return 0;
 
 err_out3:
@@ -1083,32 +1075,11 @@
 static int ps2esdi_open(struct inode *inode, struct file *file)
 {
 	int dev = DEVICE_NR(inode->i_rdev);
-
-	if (dev < ps2esdi_drives) {
-		while (!ps2esdi_valid[dev])
-			sleep_on(&ps2esdi_wait_open);
-
-		access_count[dev]++;
-
-		return (0);
-	} else
-		return (-ENODEV);
-}
-
-
-
-static int ps2esdi_release(struct inode *inode, struct file *file)
-{
-	int dev = DEVICE_NR(inode->i_rdev);
-
-	if (dev < ps2esdi_drives) {
-		access_count[dev]--;
-	}
+	if (dev >= ps2esdi_drives)
+		return -ENODEV;
 	return 0;
 }
 
-
-
 static int ps2esdi_ioctl(struct inode *inode,
 			 struct file *file, u_int cmd, u_long arg)
 {
@@ -1125,7 +1096,7 @@
 				put_user(ps2esdi_info[dev].head, (char *) &geometry->heads);
 				put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors);
 				put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders);
-				put_user(get_start_sect(inode->i_rdev),
+				put_user(get_start_sect(inode->b_rdev),
 					    (long *) &geometry->start);
 
 				return 0;
@@ -1136,16 +1107,6 @@
                         if (!capable(CAP_SYS_ADMIN)) 
 				return -EACCES;
 			return (ps2esdi_reread_partitions(inode->i_rdev));
-
-		case BLKGETSIZE:
-		case BLKGETSIZE64:
-		case BLKROSET:
-		case BLKROGET:
-		case BLKFLSBUF:
-		case BLKBSZGET:
-		case BLKBSZSET:
-		case BLKPG:
-			return blk_ioctl(inode->i_bdev, cmd, arg);
 		}
 	return (-EINVAL);
 }
@@ -1155,24 +1116,20 @@
 static int ps2esdi_reread_partitions(kdev_t dev)
 {
 	int target = DEVICE_NR(dev);
-	int res;
+	kdev_t device = mk_kdev(MAJOR_NR, target << 6);
+	int res = dev_lock_part(device);
 
-	cli();
-	ps2esdi_valid[target] = (access_count[target] != 1);
-	sti();
-	if (ps2esdi_valid[target])
-		return (-EBUSY);
+	if (res < 0)
+		return res;
 
-	res = wipe_partitions(dev);
+	res = wipe_partitions(device);
 	if (res == 0)
-		grok_partitions(dev, ps2esdi_info[target].head
+		grok_partitions(device, ps2esdi_info[target].head
 				* ps2esdi_info[target].cyl
 				* ps2esdi_info[target].sect);
  
-	ps2esdi_valid[target] = 1;
-	wake_up(&ps2esdi_wait_open);
-
-	return (res);
+	dev_unlock_part(device);
+	return res;
 }
 
 static void ps2esdi_reset_timer(unsigned long unused)
diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c
--- a/drivers/block/rd.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/block/rd.c	Wed Jul 24 14:03:38 2002
@@ -303,12 +303,6 @@
 			}
 			up(&inode->i_bdev->bd_sem);
 			break;
-         	case BLKGETSIZE:
-         	case BLKGETSIZE64:
-		case BLKROSET:
-		case BLKROGET:
-		case BLKSSZGET:
-			error = blk_ioctl(inode->i_bdev, cmd, arg);
 	}
 out:
 	return error;
diff -Nru a/drivers/block/umem.c b/drivers/block/umem.c
--- a/drivers/block/umem.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/block/umem.c	Wed Jul 24 14:03:39 2002
@@ -65,7 +65,7 @@
 #define MM_BLKSIZE 1024  /* 1k blocks */
 #define MM_HARDSECT 512  /* 512-byte hardware sectors */
 #define MM_SHIFT 6       /* max 64 partitions on 4 cards  */
-#define DEVICE_NR(device) (MINOR(device)>>MM_SHIFT)
+#define DEVICE_NR(device) (minor(device)>>MM_SHIFT)
 
 /*
  * Version Information
@@ -150,7 +150,6 @@
 		unsigned long	last_change;
 	} battery[2];
 
-	atomic_t	 usage;
 	spinlock_t 	lock;
 	int		check_batteries;
 
@@ -813,31 +812,21 @@
  * Note no locks taken out here.  In a worst case scenario, we could drop
  * a chunk of system memory.  But that should never happen, since validation
  * happens at open or mount time, when locks are held.
+ *
+ *	That's crap, since doing that while some partitions are opened
+ * or mounted will give you really nasty results.
  */
 static int mm_revalidate(kdev_t i_rdev)
 {
-	int i;
-
-	int card_number = DEVICE_NR(kdev_val(i_rdev));
-	/* first partition, # of partitions */
-	int part1 = (card_number << MM_SHIFT) + 1;
-	int npart = (1 << MM_SHIFT) -1;
-
-	/* first clear old partition information */
-	for (i=0; i<npart ;i++) {
-		mm_gendisk.sizes[part1+i]=0;
-		mm_gendisk.part[part1+i].start_sect = 0;
-		mm_gendisk.part[part1+i].nr_sects = 0;
-	}
-
-	mm_gendisk.part[card_number << MM_SHIFT].nr_sects =
-		cards[card_number].mm_size << 1;
-
-
-	/* then fill new info */
+	int card_number = DEVICE_NR(i_rdev);
+	kdev_t device = mk_mdev(MAJOR_NR, card_number << MM_SHIFT);
+	int res = dev_lock_part(device);
+	if (res < 0)
+		return res;
+	wipe_partitions(device);
 	printk(KERN_INFO "mm partition check: (%d)\n", card_number);
-	grok_partitions(mk_kdev(major_nr,part1-1),
-			mm_gendisk.sizes[card_number<<MM_SHIFT]);
+	grok_partitions(device, cards[card_number].mm_size << 1);
+	dev_unlock_part(device);
 	return 0;
 }
 /*
@@ -859,16 +848,6 @@
 
 
 	switch(cmd) {
-
-	case BLKGETSIZE:
-		/* Return the device size, expressed in sectors */
-		err = ! access_ok (VERIFY_WRITE, arg, sizeof(long));
-		if (err) return -EFAULT;
-		size = mm_gendisk.part[minor].nr_sects;
-		if (copy_to_user((long *) arg, &size, sizeof (long)))
-			return -EFAULT;
-		return 0;
-
 	case BLKRRPART:
 		return (mm_revalidate(i->i_rdev));
 
@@ -883,16 +862,15 @@
 		size = cards[card_number].mm_size * (1024 / MM_HARDSECT);
 		geo.heads     = 64;
 		geo.sectors   = 32;
-		geo.start     = mm_gendisk.part[minor].start_sect;
+		geo.start     = get_start_sect(inode->i_bdev);
 		geo.cylinders = size / (geo.heads * geo.sectors);
 
 		if (copy_to_user((void *) arg, &geo, sizeof(geo)))
 			return -EFAULT;
 		return 0;
 
-
 	default:
-		return blk_ioctl(i->i_bdev, cmd, arg);
+		return -EINVAL;
 	}
 
 	return -ENOTTY; /* unknown command */
@@ -905,7 +883,7 @@
 */
 static int mm_check_change(kdev_t i_rdev)
 {
-	int card_number = DEVICE_NR(kdev_val(i_rdev));
+	int card_number = DEVICE_NR(i_rdev);
 /*  struct cardinfo *dev = cards + card_number; */
 	if (card_number >= num_cards) /* paranoid */
 		return 0;
@@ -920,38 +898,8 @@
 */
 static int mm_open(struct inode *i, struct file *filp)
 {
-	int num;
-	struct cardinfo *card;
-
-	num = DEVICE_NR(kdev_val(i->i_rdev));
-	if (num >= num_cards)
+	if (DEVICE_NR(i->i_rdev) >= num_cards)
 		return -ENXIO;
-
-	card = cards + num;
-
-	atomic_inc(&card->usage);
-	MOD_INC_USE_COUNT;
-
-	return 0;
-}
-/*
------------------------------------------------------------------------------------
---                              mm_do_release
------------------------------------------------------------------------------------
-*/
-static int mm_do_release(struct inode *i, struct file *filp)
-{
-	int num;
-	struct cardinfo *card;
-
-	num = DEVICE_NR(kdev_val(i->i_rdev));
-
-	card = cards + num;
-
-	if (atomic_dec_and_test(&card->usage))
-		invalidate_device(i->i_rdev, 1);
-
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 /*
@@ -962,7 +910,6 @@
 static struct block_device_operations mm_fops = {
 	owner:		THIS_MODULE,
 	open:		mm_open,
-	release:	mm_do_release,
 	ioctl:		mm_ioctl,
 	revalidate:	mm_revalidate,
 	check_media_change: mm_check_change,
@@ -1243,7 +1190,7 @@
 
 static request_queue_t * mm_queue_proc(kdev_t dev)
 {
-	int c = DEVICE_NR(kdev_val(dev));
+	int c = DEVICE_NR(dev);
 
 	if (c < MM_MAXCARDS)
 		return &cards[c].queue;
@@ -1293,7 +1240,6 @@
 	blk_dev[MAJOR_NR].queue = mm_queue_proc;
 	add_gendisk(&mm_gendisk);
 
-        blk_size[MAJOR_NR]      = mm_gendisk.sizes;
         for (i = 0; i < num_cards; i++) {
 		register_disk(&mm_gendisk, mk_kdev(MAJOR_NR, i<<MM_SHIFT), MM_SHIFT,
 			      &mm_fops, cards[i].mm_size << 1);
@@ -1324,9 +1270,6 @@
 	pci_unregister_driver(&mm_pci_driver);
 
 	unregister_blkdev(MAJOR_NR, "umem");
-
-        for (i = 0; i < (num_cards << MM_SHIFT); i++)
-		invalidate_device (mk_kdev(MAJOR_NR,i), 1);
 
 	blk_size     [MAJOR_NR] = NULL;
 
diff -Nru a/drivers/block/xd.c b/drivers/block/xd.c
--- a/drivers/block/xd.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/xd.c	Wed Jul 24 14:03:37 2002
@@ -122,7 +122,7 @@
 };
 
 static struct hd_struct xd_struct[XD_MAXDRIVES << 6];
-static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES];
+static int xd_sizes[XD_MAXDRIVES << 6];
 
 static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED;
 
@@ -140,12 +140,9 @@
 static struct block_device_operations xd_fops = {
 	owner:		THIS_MODULE,
 	open:		xd_open,
-	release:	xd_release,
 	ioctl:		xd_ioctl,
 };
 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
-static DECLARE_WAIT_QUEUE_HEAD(xd_wait_open);
-static u_char xd_valid[XD_MAXDRIVES] = { 0,0 };
 static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
 static u_char xd_override __initdata = 0, xd_type __initdata = 0;
 static u_short xd_iobase = 0x320;
@@ -244,14 +241,11 @@
 	/* xd_maxsectors depends on controller - so set after detection */
 	blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), xd_maxsectors);
 
-	for (i = 0; i < xd_drives; i++) {
-		xd_valid[i] = 1;
+	for (i = 0; i < xd_drives; i++)
 		register_disk(&xd_gendisk, mk_kdev(MAJOR_NR,i<<6), 1<<6,
 				&xd_fops,
 				xd_info[i].heads * xd_info[i].cylinders *
 				xd_info[i].sectors);
-	}
-
 	xd_gendisk.nr_real = xd_drives;
 }
 
@@ -259,17 +253,9 @@
 static int xd_open (struct inode *inode,struct file *file)
 {
 	int dev = DEVICE_NR(inode->i_rdev);
-
-	if (dev < xd_drives) {
-		while (!xd_valid[dev])
-			sleep_on(&xd_wait_open);
-
-		xd_access[dev]++;
-
-		return (0);
-	}
-
-	return -ENXIO;
+	if (dev >= xd_drives)
+		return -ENXIO;
+	return 0;
 }
 
 /* do_xd_request: handle an incoming request */
@@ -329,7 +315,7 @@
 			g.heads = xd_info[dev].heads;
 			g.sectors = xd_info[dev].sectors;
 			g.cylinders = xd_info[dev].cylinders;
-			g.start = get_start_sect(inode->i_rdev);
+			g.start = get_start_sect(inode->i_bdev);
 			return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
 		}
 		case HDIO_SET_DMA:
@@ -351,50 +337,28 @@
 				return -EACCES;
 			return xd_reread_partitions(inode->i_rdev);
 
-		case BLKGETSIZE:
-		case BLKGETSIZE64:
-		case BLKFLSBUF:
-		case BLKROSET:
-		case BLKROGET:
-		case BLKPG:
-			return blk_ioctl(inode->i_bdev, cmd, arg);
-
 		default:
 			return -EINVAL;
 	}
 }
 
-/* xd_release: release the device */
-static int xd_release (struct inode *inode, struct file *file)
-{
-	int target = DEVICE_NR(inode->i_rdev);
-	if (target < xd_drives)
-		xd_access[target]--;
-	return 0;
-}
-
 /* xd_reread_partitions: rereads the partition table from a drive */
 static int xd_reread_partitions(kdev_t dev)
 {
-	int target;
-	int res;
+	int target = DEVICE_NR(dev);
+	kdev_t device = mk_kdev(MAJOR_NR, target << 6);
+	int res = dev_lock_part(device);
 	
-	target = DEVICE_NR(dev);
-
-	cli();
-	xd_valid[target] = (xd_access[target] != 1);
-        sti();
-	if (xd_valid[target])
-		return -EBUSY;
+	if (res < 0)
+		return 0;
 
-	res = wipe_partitions(dev);
+	res = wipe_partitions(device);
 	if (!res)
-		grok_partitions(dev, xd_info[target].heads
+		grok_partitions(device, xd_info[target].heads
 				* xd_info[target].cylinders
 				* xd_info[target].sectors);
 
-	xd_valid[target] = 1;
-	wake_up(&xd_wait_open);
+	dev_unlock_part(device);
 
 	return res;
 }
diff -Nru a/drivers/block/xd.h b/drivers/block/xd.h
--- a/drivers/block/xd.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/block/xd.h	Wed Jul 24 14:03:37 2002
@@ -113,7 +113,6 @@
 static int xd_open (struct inode *inode,struct file *file);
 static void do_xd_request (request_queue_t * q);
 static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
-static int xd_release (struct inode *inode,struct file *file);
 static int xd_reread_partitions (kdev_t dev);
 static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count);
 static void xd_recalibrate (u_char drive);
diff -Nru a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
--- a/drivers/cdrom/cdrom.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/cdrom/cdrom.c	Wed Jul 24 14:03:36 2002
@@ -1732,11 +1732,6 @@
 	   because they fill up the sys log when CD players poll
 	   the drive. */
 	switch (cmd) {
-	case BLKROSET:
-	case BLKROGET:
-	case BLKFLSBUF:
-	case BLKSSZGET:
-		return blk_ioctl(ip->i_bdev, cmd, arg);
 	case CDROMSUBCHNL: {
 		struct cdrom_subchnl q;
 		u_char requested, back;
diff -Nru a/drivers/char/Config.in b/drivers/char/Config.in
--- a/drivers/char/Config.in	Wed Jul 24 14:03:36 2002
+++ b/drivers/char/Config.in	Wed Jul 24 14:03:36 2002
@@ -8,25 +8,6 @@
 if [ "$CONFIG_VT" = "y" ]; then
    bool '  Support for console on virtual terminal' CONFIG_VT_CONSOLE
 fi
-tristate 'Standard/generic (8250/16550 and compatible UARTs) serial support' CONFIG_SERIAL
-if [ "$CONFIG_SERIAL" = "y" ]; then
-   bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE
-   if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
-      tristate '   Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL
-      tristate '   Dual serial port support' CONFIG_DUALSP_SERIAL
-   fi
-fi
-if [ "$CONFIG_ACPI" = "y" -a "$CONFIG_IA64" = "y" ]; then
-   bool '  Support for serial ports defined by ACPI tables' CONFIG_SERIAL_ACPI
-fi
-dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL
-if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
-   bool '  Support more than 4 serial ports' CONFIG_SERIAL_MANY_PORTS
-   bool '  Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ
-   bool '  Autodetect IRQ on standard ports (unsafe)' CONFIG_SERIAL_DETECT_IRQ
-   bool '  Support special multiport boards' CONFIG_SERIAL_MULTIPORT
-   bool '  Support the Bell Technologies HUB6 card' CONFIG_HUB6
-fi
 bool 'Non-standard serial port support' CONFIG_SERIAL_NONSTANDARD
 if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then
    tristate '  Computone IntelliPort Plus serial support' CONFIG_COMPUTONE
@@ -85,15 +66,9 @@
 if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then
    tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
 fi
-if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
-   bool 'DC21285 serial port support' CONFIG_SERIAL_21285
-   if [ "$CONFIG_SERIAL_21285" = "y" ]; then
-      if [ "$CONFIG_OBSOLETE" = "y" ]; then
-         bool '  Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD
-      fi
-      bool '  Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE
-   fi
-fi
+
+source drivers/serial/Config.in
+
 bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
 if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
    int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Wed Jul 24 14:03:39 2002
+++ b/drivers/char/Makefile	Wed Jul 24 14:03:39 2002
@@ -13,20 +13,18 @@
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
 export-objs     :=	busmouse.o console.o keyboard.o sysrq.o \
-			misc.o pty.o random.o selection.o serial.o \
+			misc.o pty.o random.o selection.o \
 			sonypi.o tty_io.o tty_ioctl.o generic_serial.o rtc.o \
 			ip2main.o
 
 KEYMAP   =defkeymap.o
 KEYBD    =pc_keyb.o
 CONSOLE  =console.o
-SERIAL   =serial.o
 
 ifeq ($(ARCH),s390)
   KEYMAP   =
   KEYBD    =
   CONSOLE  =
-  SERIAL   =
 endif
 
 ifeq ($(ARCH),mips)
@@ -39,7 +37,6 @@
   KEYMAP   =
   KEYBD    =
   CONSOLE  =
-  SERIAL   =
 endif
 
 ifeq ($(ARCH),m68k)
@@ -48,7 +45,15 @@
    else
       KEYBD =
    endif
-   SERIAL   =
+endif
+
+ifdef CONFIG_Q40
+  KEYBD += q40_keyb.o
+  SERIAL = serial.o
+endif
+
+ifdef CONFIG_APOLLO
+  KEYBD += dn_keyb.o
 endif
 
 ifeq ($(ARCH),arm)
@@ -96,15 +101,6 @@
 
 ifeq ($(CONFIG_BAGET_MIPS),y)
   KEYBD    =
-  SERIAL   =
-endif
-
-ifeq ($(CONFIG_NINO),y)
-  SERIAL   =
-endif
-
-ifneq ($(CONFIG_SUN_SERIAL),)
-  SERIAL   =
 endif
 
 ifeq ($(CONFIG_QTRONIX_KEYBOARD),y)
@@ -113,11 +109,7 @@
 endif
 
 obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o
-obj-$(CONFIG_SERIAL) += $(SERIAL)
-obj-$(CONFIG_SERIAL_ACPI) += acpi_serial.o
-obj-$(CONFIG_SERIAL_21285) += serial_21285.o
-obj-$(CONFIG_SERIAL_SA1100) += serial_sa1100.o
-obj-$(CONFIG_SERIAL_AMBA) += serial_amba.o
+#obj-$(CONFIG_SERIAL) += $(SERIAL) # Fix for decserial.o
 
 ifndef CONFIG_SUN_KEYBOARD
   obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD)
diff -Nru a/drivers/char/acpi_serial.c b/drivers/char/acpi_serial.c
--- a/drivers/char/acpi_serial.c	Wed Jul 24 14:03:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,203 +0,0 @@
-/*
- *  linux/drivers/char/acpi_serial.c
- *
- *  Copyright (C) 2000  Hewlett-Packard Co.
- *  Copyright (C) 2000  Khalid Aziz <khalid_aziz@hp.com>
- *
- *  Detect and initialize the headless console serial port defined in 
- *  SPCR table and debug serial port defined in DBGP table
- *
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/acpi.h>
-#include <linux/init.h>
-#include <linux/serial.h>
-#include <asm/serial.h>
-#include <asm/io.h>
-#include <linux/acpi_serial.h>
-/*#include <asm/acpi-ext.h>*/
-
-#undef SERIAL_DEBUG_ACPI
-
-/*
- * Query ACPI tables for a debug and a headless console serial
- * port. If found, add them to rs_table[]. A pointer to either SPCR
- * or DBGP table is passed as parameter. This function should be called 
- * before serial_console_init() is called to make sure the SPCR serial 
- * console will be available for use. IA-64 kernel calls this function
- * from within acpi.c when it encounters SPCR or DBGP tables as it parses 
- * the ACPI 2.0 tables during bootup.
- *
- */
-void __init setup_serial_acpi(void *tablep) 
-{
-	acpi_ser_t *acpi_ser_p;
-	struct serial_struct serial_req;
-	unsigned long iobase;
-	int global_sys_irq;
-
-#ifdef SERIAL_DEBUG_ACPI
-	printk("Entering setup_serial_acpi()\n");
-#endif
-
-	/* Now get the table */
-	if (tablep == NULL) {
-		return;
-	}
-
-	acpi_ser_p = (acpi_ser_t *)tablep;
-
-	/*
-	 * Perform a sanity check on the table. Table should have a 
-	 * signature of "SPCR" or "DBGP" and it should be atleast 52 bytes
-	 * long.
-	 */
-	if ((strncmp(acpi_ser_p->signature, ACPI_SPCRT_SIGNATURE, 
-					ACPI_SIG_LEN) != 0) && 
-		(strncmp(acpi_ser_p->signature, ACPI_DBGPT_SIGNATURE, 
-					ACPI_SIG_LEN) != 0)) {
-		return;
-	}
-	if (acpi_ser_p->length < 52) {
-		return;
-	}
-
-	iobase = (((u64) acpi_ser_p->base_addr.addrh) << 32) | acpi_ser_p->base_addr.addrl;
-	global_sys_irq = (acpi_ser_p->global_int[3] << 24) | 
-			(acpi_ser_p->global_int[2] << 16) |
-			(acpi_ser_p->global_int[1] << 8) |
-			acpi_ser_p->global_int[0];
-
-#ifdef SERIAL_DEBUG_ACPI
-	printk("setup_serial_acpi(): table pointer = 0x%p\n", acpi_ser_p);
-	printk("                     sig = '%c%c%c%c'\n",
-			acpi_ser_p->signature[0],
-			acpi_ser_p->signature[1],
-			acpi_ser_p->signature[2],
-			acpi_ser_p->signature[3]);
-	printk("                     length = %d\n", acpi_ser_p->length);
-	printk("                     Rev = %d\n", acpi_ser_p->rev);
-	printk("                     Interface type = %d\n", acpi_ser_p->intfc_type);
-	printk("                     Base address = 0x%lX\n", iobase);
-	printk("                     IRQ = %d\n", acpi_ser_p->irq);
-	printk("                     Global System Int = %d\n", global_sys_irq);
-	printk("                     Baud rate = ");
-	switch (acpi_ser_p->baud) {
-		case ACPI_SERIAL_BAUD_9600:
-			printk("9600\n");
-			break;
-
-		case ACPI_SERIAL_BAUD_19200:
-			printk("19200\n");
-			break;
-
-		case ACPI_SERIAL_BAUD_57600:
-			printk("57600\n");
-			break;
-
-		case ACPI_SERIAL_BAUD_115200:
-			printk("115200\n");
-			break;
-
-		default:
-			printk("Huh (%d)\n", acpi_ser_p->baud);
-			break;
-
-	}
-	if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_PCICONF_SPACE) {
-		printk("                     PCI serial port:\n");
-		printk("                         Bus %d, Device %d, Vendor ID 0x%x, Dev ID 0x%x\n",
-		acpi_ser_p->pci_bus, acpi_ser_p->pci_dev,
-		acpi_ser_p->pci_vendor_id, acpi_ser_p->pci_dev_id);
-	}
-#endif
-
-	/* 
-	 * Now build a serial_req structure to update the entry in
-	 * rs_table for the headless console port.
-	 */
-	switch (acpi_ser_p->intfc_type) {
- 		case ACPI_SERIAL_INTFC_16550:
-			serial_req.type = PORT_16550;
-			serial_req.baud_base = BASE_BAUD;
-			break;
-
- 		case ACPI_SERIAL_INTFC_16450:
-			serial_req.type = PORT_16450;
-			serial_req.baud_base = BASE_BAUD;
-			break;
-
-		default:
-			serial_req.type = PORT_UNKNOWN;
-			break;
-	}
-	if (strncmp(acpi_ser_p->signature, ACPI_SPCRT_SIGNATURE,
-					ACPI_SIG_LEN) == 0) {
-		serial_req.line = ACPI_SERIAL_CONSOLE_PORT;
-	}
-	else if (strncmp(acpi_ser_p->signature, ACPI_DBGPT_SIGNATURE, 
-					ACPI_SIG_LEN) == 0) {
-		serial_req.line = ACPI_SERIAL_DEBUG_PORT;
-	}
-	/*
-	 * Check if this is an I/O mapped address or a memory mapped address
-	 */
-	if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_MEM_SPACE) {
-		serial_req.port = 0;
-		serial_req.port_high = 0;
-		serial_req.iomem_base = (void *)ioremap(iobase, 64);
-		serial_req.io_type = SERIAL_IO_MEM;
-	}
-	else if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_IO_SPACE) {
-		serial_req.port = (unsigned long) iobase & 0xffffffff;
-		serial_req.port_high = (unsigned long)(((u64)iobase) >> 32);
-		serial_req.iomem_base = NULL;
-		serial_req.io_type = SERIAL_IO_PORT;
-	}
-	else if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_PCICONF_SPACE) {
-		printk("WARNING: No support for PCI serial console\n");
-		return;
-	}
-
-	/*
-	 * If the table does not have IRQ information, use 0 for IRQ. 
-	 * This will force rs_init() to probe for IRQ. 
-	 */
-	if (acpi_ser_p->length < 53) {
-		serial_req.irq = 0;
-	}
-	else {
-		serial_req.flags = ASYNC_SKIP_TEST | ASYNC_BOOT_AUTOCONF | 
-					ASYNC_AUTO_IRQ;
-		if (acpi_ser_p->int_type & 
-			(ACPI_SERIAL_INT_APIC | ACPI_SERIAL_INT_SAPIC)) {
-			serial_req.irq = global_sys_irq;
-		}
-		else if (acpi_ser_p->int_type & ACPI_SERIAL_INT_PCAT) {
-			serial_req.irq = acpi_ser_p->irq;
-		}
-		else {
-			/*
-			 * IRQ type not being set would mean UART will
-			 * run in polling mode. Do not probe for IRQ in
-			 * that case.
-			 */
-			serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF;
-		}
-	}
-
-	serial_req.xmit_fifo_size = serial_req.custom_divisor = 0;
-	serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0;
-	serial_req.iomem_reg_shift = 0;
-	if (early_serial_setup(&serial_req) < 0) {
-		printk("early_serial_setup() for ACPI serial console port failed\n");
-		return;
-	}
-
-#ifdef SERIAL_DEBUG_ACPI
-	printk("Leaving setup_serial_acpi()\n");
-#endif
-}
diff -Nru a/drivers/char/agp/agp.c b/drivers/char/agp/agp.c
--- a/drivers/char/agp/agp.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/char/agp/agp.c	Wed Jul 24 14:03:36 2002
@@ -751,396 +751,396 @@
 
 #ifdef CONFIG_AGP_ALI
 	{
-		device_id:	PCI_DEVICE_ID_AL_M1541_0,
-		vendor_id:	PCI_VENDOR_ID_AL,
-		chipset:	ALI_M1541,
-		vendor_name:	"Ali",
-		chipset_name:	"M1541",
-		chipset_setup:	ali_generic_setup,
-	},
-	{
-		device_id:	PCI_DEVICE_ID_AL_M1621_0,
-		vendor_id:	PCI_VENDOR_ID_AL,
-		chipset:	ALI_M1621,
-		vendor_name:	"Ali",
-		chipset_name:	"M1621",
-		chipset_setup:	ali_generic_setup,
-	},
-	{
-		device_id:	PCI_DEVICE_ID_AL_M1631_0,
-		vendor_id:	PCI_VENDOR_ID_AL,
-		chipset:	ALI_M1631,
-		vendor_name:	"Ali",
-		chipset_name:	"M1631",
-		chipset_setup:	ali_generic_setup,
-	},
-	{
-		device_id:	PCI_DEVICE_ID_AL_M1632_0,
-		vendor_id:	PCI_VENDOR_ID_AL,
-		chipset:	ALI_M1632,
-		vendor_name:	"Ali",
-		chipset_name:	"M1632",
-		chipset_setup:	ali_generic_setup,
-	},
-	{
-		device_id:	PCI_DEVICE_ID_AL_M1641_0,
-		vendor_id:	PCI_VENDOR_ID_AL,
-		chipset:	ALI_M1641,
-		vendor_name:	"Ali",
-		chipset_name:	"M1641",
-		chipset_setup:	ali_generic_setup,
-	},
-	{
-		device_id:	PCI_DEVICE_ID_AL_M1644_0,
-		vendor_id:	PCI_VENDOR_ID_AL,
-		chipset:	ALI_M1644,
-		vendor_name:	"Ali",
-		chipset_name:	"M1644",
-		chipset_setup:	ali_generic_setup,
-	},
-	{
-		device_id:	PCI_DEVICE_ID_AL_M1647_0,
-		vendor_id:	PCI_VENDOR_ID_AL,
-		chipset:	ALI_M1647,
-		vendor_name:	"Ali",
-		chipset_name:	"M1647",
-		chipset_setup:	ali_generic_setup,
-	},
-	{
-		device_id:	PCI_DEVICE_ID_AL_M1651_0,
-		vendor_id:	PCI_VENDOR_ID_AL,
-		chipset:	ALI_M1651,
-		vendor_name:	"Ali",
-		chipset_name:	"M1651",
-		chipset_setup:	ali_generic_setup,
-	},
-	{
-		device_id:	0,
-		vendor_id:	PCI_VENDOR_ID_AL,
-		chipset:	ALI_GENERIC,
-		vendor_name:	"Ali",
-		chipset_name:	"Generic",
-		chipset_setup:	ali_generic_setup,
+		.device_id	= PCI_DEVICE_ID_AL_M1541_0,
+		.vendor_id	= PCI_VENDOR_ID_AL,
+		.chipset	= ALI_M1541,
+		.vendor_name	= "Ali",
+		.chipset_name	= "M1541",
+		.chipset_setup	= ali_generic_setup,
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1621_0,
+		.vendor_id	= PCI_VENDOR_ID_AL,
+		.chipset	= ALI_M1621,
+		.vendor_name	= "Ali",
+		.chipset_name	= "M1621",
+		.chipset_setup	= ali_generic_setup,
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1631_0,
+		.vendor_id	= PCI_VENDOR_ID_AL,
+		.chipset	= ALI_M1631,
+		.vendor_name	= "Ali",
+		.chipset_name	= "M1631",
+		.chipset_setup	= ali_generic_setup,
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1632_0,
+		.vendor_id	= PCI_VENDOR_ID_AL,
+		.chipset	= ALI_M1632,
+		.vendor_name	= "Ali",
+		.chipset_name	= "M1632",
+		.chipset_setup	= ali_generic_setup,
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1641_0,
+		.vendor_id	= PCI_VENDOR_ID_AL,
+		.chipset	= ALI_M1641,
+		.vendor_name	= "Ali",
+		.chipset_name	= "M1641",
+		.chipset_setup	= ali_generic_setup,
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1644_0,
+		.vendor_id	= PCI_VENDOR_ID_AL,
+		.chipset	= ALI_M1644,
+		.vendor_name	= "Ali",
+		.chipset_name	= "M1644",
+		.chipset_setup	= ali_generic_setup,
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1647_0,
+		.vendor_id	= PCI_VENDOR_ID_AL,
+		.chipset	= ALI_M1647,
+		.vendor_name	= "Ali",
+		.chipset_name	= "M1647",
+		.chipset_setup	= ali_generic_setup,
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1651_0,
+		.vendor_id	= PCI_VENDOR_ID_AL,
+		.chipset	= ALI_M1651,
+		.vendor_name	= "Ali",
+		.chipset_name	= "M1651",
+		.chipset_setup	= ali_generic_setup,
+	},
+	{
+		.device_id	= 0,
+		.vendor_id	= PCI_VENDOR_ID_AL,
+		.chipset	= ALI_GENERIC,
+		.vendor_name	= "Ali",
+		.chipset_name	= "Generic",
+		.chipset_setup	= ali_generic_setup,
 	},
 #endif /* CONFIG_AGP_ALI */
 
 #ifdef CONFIG_AGP_AMD
 	{
-		device_id:	PCI_DEVICE_ID_AMD_IRONGATE_0,
-		vendor_id:	PCI_VENDOR_ID_AMD,
-		chipset:	AMD_IRONGATE,
-		vendor_name:	"AMD",
-		chipset_name:	"Irongate",
-		chipset_setup:	amd_irongate_setup,
-	},
-	{
-		device_id:	PCI_DEVICE_ID_AMD_761_0,
-		vendor_id:	PCI_VENDOR_ID_AMD,
-		chipset:	AMD_761,
-		vendor_name:	"AMD",
-		chipset_name:	"761",
-		chipset_setup:	amd_irongate_setup,
-	},
-	{
-		device_id:	PCI_DEVICE_ID_AMD_762_0,
-		vendor_id:	PCI_VENDOR_ID_AMD,
-		chipset:	AMD_762,
-		vendor_name:	"AMD",
-		chipset_name:	"760MP",
-		chipset_setup:	amd_irongate_setup,
-	},
-	{
-		device_id:	0,
-		vendor_id:	PCI_VENDOR_ID_AMD,
-		chipset:	AMD_GENERIC,
-		vendor_name:	"AMD",
-		chipset_name:	"Generic",
-		chipset_setup:	amd_irongate_setup,
+		.device_id	= PCI_DEVICE_ID_AMD_IRONGATE_0,
+		.vendor_id	= PCI_VENDOR_ID_AMD,
+		.chipset	= AMD_IRONGATE,
+		.vendor_name	= "AMD",
+		.chipset_name	= "Irongate",
+		.chipset_setup	= amd_irongate_setup,
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AMD_761_0,
+		.vendor_id	= PCI_VENDOR_ID_AMD,
+		.chipset	= AMD_761,
+		.vendor_name	= "AMD",
+		.chipset_name	= "761",
+		.chipset_setup	= amd_irongate_setup,
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AMD_762_0,
+		.vendor_id	= PCI_VENDOR_ID_AMD,
+		.chipset	= AMD_762,
+		.vendor_name	= "AMD",
+		.chipset_name	= "760MP",
+		.chipset_setup	= amd_irongate_setup,
+	},
+	{
+		.device_id	= 0,
+		.vendor_id	= PCI_VENDOR_ID_AMD,
+		.chipset	= AMD_GENERIC,
+		.vendor_name	= "AMD",
+		.chipset_name	= "Generic",
+		.chipset_setup	= amd_irongate_setup,
 	},
 #endif /* CONFIG_AGP_AMD */
 
 #ifdef CONFIG_AGP_INTEL
 	{
-		device_id:	PCI_DEVICE_ID_INTEL_82443LX_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_LX,
-		vendor_name:	"Intel",
-		chipset_name:	"440LX",
-		chipset_setup:	intel_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_82443BX_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_BX,
-		vendor_name:	"Intel",
-		chipset_name:	"440BX",
-		chipset_setup:	intel_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_82443GX_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_GX,
-		vendor_name:	"Intel",
-		chipset_name:	"440GX",
-		chipset_setup:	intel_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_815_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_I815,
-		vendor_name:	"Intel",
-		chipset_name:	"i815",
-		chipset_setup:	intel_815_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_820_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_I820,
-		vendor_name:	"Intel",
-		chipset_name:	"i820",
-		chipset_setup:	intel_820_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_820_UP_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_I820,
-		vendor_name:	"Intel",
-		chipset_name:	"i820",
-		chipset_setup:	intel_820_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_830_M_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_I830_M,
-		vendor_name:	"Intel",
-		chipset_name:	"i830M",
-		chipset_setup:	intel_830mp_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_845_G_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_I845_G,
-		vendor_name:	"Intel",
-		chipset_name:	"i845G",
-		chipset_setup:	intel_830mp_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_840_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_I840,
-		vendor_name:	"Intel",
-		chipset_name:	"i840",
-		chipset_setup:	intel_840_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_845_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_I845,
-		vendor_name:	"Intel",
-		chipset_name:	"i845",
-		chipset_setup:	intel_845_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_850_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_I850,
-		vendor_name:	"Intel",
-		chipset_name:	"i850",
-		chipset_setup:	intel_850_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_INTEL_860_0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_I860,
-		vendor_name:	"Intel",
-		chipset_name:	"i860",
-		chipset_setup:	intel_860_setup
-	},
-	{
-		device_id:	0,
-		vendor_id:	PCI_VENDOR_ID_INTEL,
-		chipset:	INTEL_GENERIC,
-		vendor_name:	"Intel",
-		chipset_name:	"Generic",
-		chipset_setup:	intel_generic_setup
+		.device_id	= PCI_DEVICE_ID_INTEL_82443LX_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_LX,
+		.vendor_name	= "Intel",
+		.chipset_name	= "440LX",
+		.chipset_setup	= intel_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82443BX_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_BX,
+		.vendor_name	= "Intel",
+		.chipset_name	= "440BX",
+		.chipset_setup	= intel_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82443GX_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_GX,
+		.vendor_name	= "Intel",
+		.chipset_name	= "440GX",
+		.chipset_setup	= intel_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_815_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_I815,
+		.vendor_name	= "Intel",
+		.chipset_name	= "i815",
+		.chipset_setup	= intel_815_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_820_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_I820,
+		.vendor_name	= "Intel",
+		.chipset_name	= "i820",
+		.chipset_setup	= intel_820_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_820_UP_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_I820,
+		.vendor_name	= "Intel",
+		.chipset_name	= "i820",
+		.chipset_setup	= intel_820_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_830_M_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_I830_M,
+		.vendor_name	= "Intel",
+		.chipset_name	= "i830M",
+		.chipset_setup	= intel_830mp_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_845_G_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_I845_G,
+		.vendor_name	= "Intel",
+		.chipset_name	= "i845G",
+		.chipset_setup	= intel_830mp_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_840_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_I840,
+		.vendor_name	= "Intel",
+		.chipset_name	= "i840",
+		.chipset_setup	= intel_840_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_845_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_I845,
+		.vendor_name	= "Intel",
+		.chipset_name	= "i845",
+		.chipset_setup	= intel_845_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_850_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_I850,
+		.vendor_name	= "Intel",
+		.chipset_name	= "i850",
+		.chipset_setup	= intel_850_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_860_0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_I860,
+		.vendor_name	= "Intel",
+		.chipset_name	= "i860",
+		.chipset_setup	= intel_860_setup
+	},
+	{
+		.device_id	= 0,
+		.vendor_id	= PCI_VENDOR_ID_INTEL,
+		.chipset	= INTEL_GENERIC,
+		.vendor_name	= "Intel",
+		.chipset_name	= "Generic",
+		.chipset_setup	= intel_generic_setup
 	},
 
 #endif /* CONFIG_AGP_INTEL */
 
 #ifdef CONFIG_AGP_SIS
 	{
-		device_id:	PCI_DEVICE_ID_SI_740,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"740",
-		chipset_setup:	sis_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_SI_650,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"650",
-		chipset_setup:	sis_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_SI_645,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"645",
-		chipset_setup:	sis_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_SI_735,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"735",
-		chipset_setup:	sis_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_SI_745,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"745",
-		chipset_setup:	sis_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_SI_730,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"730",
-		chipset_setup:	sis_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_SI_630,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"630",
-		chipset_setup:	sis_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_SI_540,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"540",
-		chipset_setup:	sis_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_SI_620,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"620",
-		chipset_setup:	sis_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_SI_530,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"530",
-		chipset_setup:	sis_generic_setup
+		.device_id	= PCI_DEVICE_ID_SI_740,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "740",
+		.chipset_setup	= sis_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_650,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "650",
+		.chipset_setup	= sis_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_645,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "645",
+		.chipset_setup	= sis_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_735,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "735",
+		.chipset_setup	= sis_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_745,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "745",
+		.chipset_setup	= sis_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_730,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "730",
+		.chipset_setup	= sis_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_630,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "630",
+		.chipset_setup	= sis_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_540,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "540",
+		.chipset_setup	= sis_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_620,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "620",
+		.chipset_setup	= sis_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_530,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "530",
+		.chipset_setup	= sis_generic_setup
 	},
         {
-		device_id:	PCI_DEVICE_ID_SI_550,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"550",
-		chipset_setup:	sis_generic_setup
+		.device_id	= PCI_DEVICE_ID_SI_550,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "550",
+		.chipset_setup	= sis_generic_setup
 	},
 	{
-		device_id:	0,
-		vendor_id:	PCI_VENDOR_ID_SI,
-		chipset:	SIS_GENERIC,
-		vendor_name:	"SiS",
-		chipset_name:	"Generic",
-		chipset_setup:	sis_generic_setup
+		.device_id	= 0,
+		.vendor_id	= PCI_VENDOR_ID_SI,
+		.chipset	= SIS_GENERIC,
+		.vendor_name	= "SiS",
+		.chipset_name	= "Generic",
+		.chipset_setup	= sis_generic_setup
 	},
 #endif /* CONFIG_AGP_SIS */
 
 #ifdef CONFIG_AGP_VIA
 	{
-		device_id:	PCI_DEVICE_ID_VIA_8501_0,
-		vendor_id:	PCI_VENDOR_ID_VIA,
-		chipset:	VIA_MVP4,
-		vendor_name:	"Via",
-		chipset_name:	"MVP4",
-		chipset_setup:	via_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_VIA_82C597_0,
-		vendor_id:	PCI_VENDOR_ID_VIA,
-		chipset:	VIA_VP3,
-		vendor_name:	"Via",
-		chipset_name:	"VP3",
-		chipset_setup:	via_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_VIA_82C598_0,
-		vendor_id:	PCI_VENDOR_ID_VIA,
-		chipset:	VIA_MVP3,
-		vendor_name:	"Via",
-		chipset_name:	"MVP3",
-		chipset_setup:	via_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_VIA_82C691_0,
-		vendor_id:	PCI_VENDOR_ID_VIA,
-		chipset:	VIA_APOLLO_PRO,
-		vendor_name:	"Via",
-		chipset_name:	"Apollo Pro",
-		chipset_setup:	via_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_VIA_8371_0,
-		vendor_id:	PCI_VENDOR_ID_VIA,
-		chipset:	VIA_APOLLO_KX133,
-		vendor_name:	"Via",
-		chipset_name:	"Apollo Pro KX133",
-		chipset_setup:	via_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_VIA_8363_0,
-		vendor_id:	PCI_VENDOR_ID_VIA,
-		chipset:	VIA_APOLLO_KT133,
-		vendor_name:	"Via",
-		chipset_name:	"Apollo Pro KT133",
-		chipset_setup:	via_generic_setup
-	},
-	{
-		device_id:	PCI_DEVICE_ID_VIA_8367_0,
-		vendor_id:	PCI_VENDOR_ID_VIA,
-		chipset:	VIA_APOLLO_KT133,
-		vendor_name:	"Via",
-		chipset_name:	"Apollo Pro KT266",
-		chipset_setup:	via_generic_setup
-	},
-	{
-		device_id:	0,
-		vendor_id:	PCI_VENDOR_ID_VIA,
-		chipset:	VIA_GENERIC,
-		vendor_name:	"Via",
-		chipset_name:	"Generic",
-		chipset_setup:	via_generic_setup
+		.device_id	= PCI_DEVICE_ID_VIA_8501_0,
+		.vendor_id	= PCI_VENDOR_ID_VIA,
+		.chipset	= VIA_MVP4,
+		.vendor_name	= "Via",
+		.chipset_name	= "MVP4",
+		.chipset_setup	= via_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_82C597_0,
+		.vendor_id	= PCI_VENDOR_ID_VIA,
+		.chipset	= VIA_VP3,
+		.vendor_name	= "Via",
+		.chipset_name	= "VP3",
+		.chipset_setup	= via_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_82C598_0,
+		.vendor_id	= PCI_VENDOR_ID_VIA,
+		.chipset	= VIA_MVP3,
+		.vendor_name	= "Via",
+		.chipset_name	= "MVP3",
+		.chipset_setup	= via_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_82C691_0,
+		.vendor_id	= PCI_VENDOR_ID_VIA,
+		.chipset	= VIA_APOLLO_PRO,
+		.vendor_name	= "Via",
+		.chipset_name	= "Apollo Pro",
+		.chipset_setup	= via_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8371_0,
+		.vendor_id	= PCI_VENDOR_ID_VIA,
+		.chipset	= VIA_APOLLO_KX133,
+		.vendor_name	= "Via",
+		.chipset_name	= "Apollo Pro KX133",
+		.chipset_setup	= via_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8363_0,
+		.vendor_id	= PCI_VENDOR_ID_VIA,
+		.chipset	= VIA_APOLLO_KT133,
+		.vendor_name	= "Via",
+		.chipset_name	= "Apollo Pro KT133",
+		.chipset_setup	= via_generic_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8367_0,
+		.vendor_id	= PCI_VENDOR_ID_VIA,
+		.chipset	= VIA_APOLLO_KT133,
+		.vendor_name	= "Via",
+		.chipset_name	= "Apollo Pro KT266",
+		.chipset_setup	= via_generic_setup
+	},
+	{
+		.device_id	= 0,
+		.vendor_id	= PCI_VENDOR_ID_VIA,
+		.chipset	= VIA_GENERIC,
+		.vendor_name	= "Via",
+		.chipset_name	= "Generic",
+		.chipset_setup	= via_generic_setup
 	},
 #endif /* CONFIG_AGP_VIA */
 
 #ifdef CONFIG_AGP_HP_ZX1
 	{
-		device_id:	PCI_DEVICE_ID_HP_ZX1_LBA,
-		vendor_id:	PCI_VENDOR_ID_HP,
-		chipset:	HP_ZX1,
-		vendor_name:	"HP",
-		chipset_name:	"ZX1",
-		chipset_setup:	hp_zx1_setup
+		.device_id	= PCI_DEVICE_ID_HP_ZX1_LBA,
+		.vendor_id	= PCI_VENDOR_ID_HP,
+		.chipset	= HP_ZX1,
+		.vendor_name	= "HP",
+		.chipset_name	= "ZX1",
+		.chipset_setup	= hp_zx1_setup
 	},
 #endif
 
@@ -1461,8 +1461,8 @@
 
 static struct agp_version agp_current_version =
 {
-	major:	AGPGART_VERSION_MAJOR,
-	minor:	AGPGART_VERSION_MINOR,
+	.major	= AGPGART_VERSION_MAJOR,
+	.minor	= AGPGART_VERSION_MINOR,
 };
 
 static int __init agp_backend_initialize(struct pci_dev *dev)
@@ -1614,12 +1614,12 @@
 
 static struct pci_device_id agp_pci_table[] __initdata = {
 	{
-	class:		(PCI_CLASS_BRIDGE_HOST << 8),
-	class_mask:	~0,
-	vendor:		PCI_ANY_ID,
-	device:		PCI_ANY_ID,
-	subvendor:	PCI_ANY_ID,
-	subdevice:	PCI_ANY_ID,
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_ANY_ID,
+	.device		= PCI_ANY_ID,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
 	},
 	{ }
 };
@@ -1627,9 +1627,9 @@
 MODULE_DEVICE_TABLE(pci, agp_pci_table);
 
 static struct pci_driver agp_pci_driver = {
-	name:		"agpgart",
-	id_table:	agp_pci_table,
-	probe:		agp_probe,
+	.name		= "agpgart",
+	.id_table	= agp_pci_table,
+	.probe		= agp_probe,
 };
 
 static int __init agp_init(void)
diff -Nru a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
--- a/drivers/char/agp/frontend.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/char/agp/frontend.c	Wed Jul 24 14:03:36 2002
@@ -1050,14 +1050,14 @@
 
 static struct file_operations agp_fops =
 {
-	owner:		THIS_MODULE,
-	llseek:		no_llseek,
-	read:		agp_read,
-	write:		agp_write,
-	ioctl:		agp_ioctl,
-	mmap:		agp_mmap,
-	open:		agp_open,
-	release:	agp_release,
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.read		= agp_read,
+	.write		= agp_write,
+	.ioctl		= agp_ioctl,
+	.mmap		= agp_mmap,
+	.open		= agp_open,
+	.release	= agp_release,
 };
 
 static struct miscdevice agp_miscdev =
diff -Nru a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
--- a/drivers/char/agp/i460-agp.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/char/agp/i460-agp.c	Wed Jul 24 14:03:38 2002
@@ -533,8 +533,8 @@
 static struct gatt_mask intel_i460_masks[] =
 {
 	{
-	  mask: INTEL_I460_GATT_VALID | INTEL_I460_GATT_COHERENT,
-	  type: 0
+	  .mask = INTEL_I460_GATT_VALID | INTEL_I460_GATT_COHERENT,
+	  .type = 0
 	}
 };
 
diff -Nru a/drivers/char/amiserial.c b/drivers/char/amiserial.c
--- a/drivers/char/amiserial.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/char/amiserial.c	Wed Jul 24 14:03:39 2002
@@ -2306,43 +2306,17 @@
 	custom.intena = IF_SETCLR | (intena & IF_TBE);
 }
 
-/*
- *	Receive character from the serial port
- */
-static int serial_console_wait_key(struct console *co)
-{
-	unsigned short intena = custom.intenar;
-	int ch;
-
-	custom.intena = IF_RBF;
-
-	while (!(custom.intreqr & IF_RBF))
-		barrier();
-	ch = custom.serdatr & 0xff;
-	custom.intreq = IF_RBF;
-
-	custom.intena = IF_SETCLR | (intena & IF_RBF);
-
-	return ch;
-}
-
 static kdev_t serial_console_device(struct console *c)
 {
 	return mk_kdev(TTY_MAJOR, 64);
 }
 
 static struct console sercons = {
-	"ttyS",
-	serial_console_write,
-	NULL,
-	serial_console_device,
-	serial_console_wait_key,
-	NULL,
-	NULL,
-	CON_PRINTBUFFER,
-	-1,
-	0,
-	NULL
+	.name =		"ttyS",
+	.write =	serial_console_write,
+	.device =	serial_console_device,
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
 };
 
 /*
diff -Nru a/drivers/char/dn_keyb.c b/drivers/char/dn_keyb.c
--- a/drivers/char/dn_keyb.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/char/dn_keyb.c	Wed Jul 24 14:03:37 2002
@@ -5,6 +5,7 @@
 #include <linux/delay.h>
 #include <linux/timer.h>
 #include <linux/kd.h>
+#include <linux/kbd_ll.h>
 #include <linux/random.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -19,8 +20,6 @@
 
 #include "busmouse.h"
 
-/* extern void handle_scancode(unsigned char,int ); */
-
 #define DNKEY_CAPS 0x7e
 #define BREAK_FLAG 0x80
 #define DNKEY_REPEAT_DELAY 50
@@ -336,7 +335,8 @@
 
 	static short mouse_byte_count=0;
 	static u_char mouse_packet[3];
-	short mouse_buttons;	
+	short buttons;
+	int dx, dy;
 
 	mouse_packet[mouse_byte_count++]=mouse_data;
 
@@ -347,24 +347,12 @@
 /*			printk("modechange: %d\n",mouse_packet[1]); */
 			if(kbd_mode==APOLLO_KBD_MODE_KEYB)
 				dn_keyb_process_key_event(mouse_packet[2]);
-		}				
+		}
 		if((mouse_packet[0] & 0x8f) == 0x80) {
-			if(mouse_update_allowed) {
-				mouse_ready=1;
-				mouse_buttons=(mouse_packet[0] >> 4) & 0x7;
-				mouse_dx+=mouse_packet[1] == 0xff ? 0 : (signed char)mouse_packet[1];
-				mouse_dy+=mouse_packet[2] == 0xff ? 0 : (signed char)mouse_packet[2];
-				wake_up_interruptible(&mouse_wait);
-				if (mouse_dx < -2048)
-              				mouse_dx = -2048;
-          			else if (mouse_dx >  2048)
-              				mouse_dx =  2048;
-         	 		if (mouse_dy < -2048)
-              				mouse_dy = -2048;
-          			else if (mouse_dy >  2048)
-             			 	mouse_dy =  2048;
-              			kill_fasync(&mouse_fasyncptr, SIGIO, POLL_IN);
-			}
+			buttons = (mouse_packet[0] >> 4) & 0x7;
+			dx = mouse_packet[1] == 0xff ? 0 : (signed char)mouse_packet[1];
+			dy = mouse_packet[2] == 0xff ? 0 : (signed char)mouse_packet[2];
+			busmouse_add_movementbuttons(msedev, dx, dy, buttons);
 			mouse_byte_count=0;
 /*			printk("mouse: %d, %d, %x\n",mouse_x,mouse_y,buttons); */
 		}
diff -Nru a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
--- a/drivers/char/hvc_console.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/char/hvc_console.c	Wed Jul 24 14:03:39 2002
@@ -22,6 +22,7 @@
 #include <linux/console.h>
 #include <linux/major.h>
 #include <linux/kernel.h>
+#include <linux/sysrq.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/sched.h>
@@ -46,6 +47,9 @@
 static struct termios *hvc_termios[MAX_NR_HVC_CONSOLES];
 static struct termios *hvc_termios_locked[MAX_NR_HVC_CONSOLES];
 static int hvc_offset;
+#ifdef CONFIG_MAGIC_SYSRQ
+static int sysrq_pressed;
+#endif
 
 #define N_OUTBUF	16
 
@@ -98,6 +102,14 @@
 	spin_unlock_irqrestore(&hp->lock, flags);
 }
 
+static void hvc_hangup(struct tty_struct *tty)
+{
+	struct hvc_struct *hp = tty->driver_data;
+
+	hp->count = 0;
+	hp->tty = NULL;
+}
+
 /* called with hp->lock held */
 static void hvc_push(struct hvc_struct *hp)
 {
@@ -186,8 +198,19 @@
 			n = hvc_get_chars(index + hvc_offset, buf, sizeof(buf));
 			if (n <= 0)
 				break;
-			for (i = 0; i < n; ++i)
+			for (i = 0; i < n; ++i) {
+#ifdef CONFIG_MAGIC_SYSRQ		/* Handle the SysRq Hack */
+				if (buf[i] == '\x0f') {	/* ^O -- should support a sequence */
+					sysrq_pressed = 1;
+					continue;
+				} else if (sysrq_pressed) {
+					handle_sysrq(buf[i], NULL, NULL, tty);
+					sysrq_pressed = 0;
+					continue;
+				}
+#endif
 				tty_insert_flip_char(tty, buf[i], 0);
+			}
 		}
 		if (tty->flip.count)
 			tty_schedule_flip(tty);
@@ -246,6 +269,7 @@
 	hvc_driver.open = hvc_open;
 	hvc_driver.close = hvc_close;
 	hvc_driver.write = hvc_write;
+	hvc_driver.hangup = hvc_hangup;
 	hvc_driver.write_room = hvc_write_room;
 	hvc_driver.chars_in_buffer = hvc_chars_in_buffer;
 
diff -Nru a/drivers/char/mem.c b/drivers/char/mem.c
--- a/drivers/char/mem.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/char/mem.c	Wed Jul 24 14:03:38 2002
@@ -324,7 +324,7 @@
  	return virtr + wrote;
 }
 
-#if !defined(__mc68000__)
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 static ssize_t read_port(struct file * file, char * buf,
 			 size_t count, loff_t *ppos)
 {
@@ -557,7 +557,7 @@
 	write:		write_null,
 };
 
-#if !defined(__mc68000__)
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 static struct file_operations port_fops = {
 	llseek:		memory_lseek,
 	read:		read_port,
@@ -591,7 +591,7 @@
 		case 3:
 			filp->f_op = &null_fops;
 			break;
-#if !defined(__mc68000__)
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 		case 4:
 			filp->f_op = &port_fops;
 			break;
@@ -628,7 +628,9 @@
 	{1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
 	{2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
 	{3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 	{4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
+#endif
 	{5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
 	{7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
 	{8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
diff -Nru a/drivers/char/n_tty.c b/drivers/char/n_tty.c
--- a/drivers/char/n_tty.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/char/n_tty.c	Wed Jul 24 14:03:35 2002
@@ -807,7 +807,7 @@
 	    I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) ||
 	    I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) ||
 	    I_PARMRK(tty)) {
-		cli();
+		local_irq_disable(); // FIXME: is this safe?
 		memset(tty->process_char_map, 0, 256/8);
 
 		if (I_IGNCR(tty) || I_ICRNL(tty))
@@ -843,7 +843,7 @@
 			set_bit(SUSP_CHAR(tty), tty->process_char_map);
 		}
 		clear_bit(__DISABLED_CHAR, tty->process_char_map);
-		sti();
+		local_irq_enable(); // FIXME: is this safe?
 		tty->raw = 0;
 		tty->real_raw = 0;
 	} else {
diff -Nru a/drivers/char/pcmcia/Config.in b/drivers/char/pcmcia/Config.in
--- a/drivers/char/pcmcia/Config.in	Wed Jul 24 14:03:35 2002
+++ b/drivers/char/pcmcia/Config.in	Wed Jul 24 14:03:35 2002
@@ -5,7 +5,6 @@
 mainmenu_option next_comment
 comment 'PCMCIA character devices'
 
-dep_tristate 'PCMCIA serial device support' CONFIG_PCMCIA_SERIAL_CS $CONFIG_PCMCIA $CONFIG_SERIAL
 dep_tristate 'SyncLink PC Card support' CONFIG_SYNCLINK_CS $CONFIG_PCMCIA
 
 endmenu
diff -Nru a/drivers/char/pcmcia/Makefile b/drivers/char/pcmcia/Makefile
--- a/drivers/char/pcmcia/Makefile	Wed Jul 24 14:03:36 2002
+++ b/drivers/char/pcmcia/Makefile	Wed Jul 24 14:03:36 2002
@@ -4,7 +4,6 @@
 # Makefile for the Linux PCMCIA char device drivers.
 #
 
-obj-$(CONFIG_PCMCIA_SERIAL_CS)	+= serial_cs.o
 obj-$(CONFIG_SYNCLINK_CS) += synclink_cs.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/char/pcmcia/serial_cs.c b/drivers/char/pcmcia/serial_cs.c
--- a/drivers/char/pcmcia/serial_cs.c	Wed Jul 24 14:03:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,667 +0,0 @@
-/*======================================================================
-
-    A driver for PCMCIA serial devices
-
-    serial_cs.c 1.123 2000/08/24 18:46:38
-
-    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/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.123 2000/08/24 18:46:38 (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;
-
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-MODULE_PARM(do_sound, "i");
-
-/*====================================================================*/
-
-/* Table of multi-port card ID's */
-
-typedef struct {
-    u_short	manfid;
-    u_short	prodid;
-    int		multi;		/* 1 = multifunction, > 1 = # ports */
-} multi_id_t;
-
-static multi_id_t 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(multi_id_t))
-
-typedef struct serial_info_t {
-    dev_link_t	link;
-    int		ndev;
-    int		multi;
-    int		slave;
-    int		manfid;
-    dev_node_t	node[4];
-    int		line[4];
-} serial_info_t;
-
-static void serial_config(dev_link_t *link);
-static void serial_release(u_long arg);
-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;
-
-/*====================================================================*/
-
-static void cs_error(client_handle_t handle, int func, int ret)
-{
-    error_info_t err = { func, ret };
-    CardServices(ReportError, handle, &err);
-}
-
-/*======================================================================
-
-    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)
-{
-    serial_info_t *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->release.function = &serial_release;
-    link->release.data = (u_long)link;
-    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;
-    link->conf.Vcc = 50;
-    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;
-} /* serial_attach */
-
-/*======================================================================
-
-    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)
-{
-    serial_info_t *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;
-
-    del_timer(&link->release);
-    if (link->state & DEV_CONFIG)
-	serial_release((u_long)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);
-    
-} /* serial_detach */
-
-/*====================================================================*/
-
-static int setup_serial(serial_info_t *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 = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
-    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 -1;
-    }
-    
-    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;
-    serial_info_t *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;
-    serial_info_t *info = link->priv;
-    tuple_t tuple;
-    u_char buf[256];
-    cisparse_t parse;
-    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-    int i, base2 = 0;
-
-    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;
-    }
-    
-    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;
-    serial_info_t *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_release((u_long)link);
-
-} /* serial_config */
-
-/*======================================================================
-
-    After a card is removed, serial_release() will unregister the net
-    device, and release the PCMCIA configuration.
-    
-======================================================================*/
-
-void serial_release(u_long arg)
-{
-    dev_link_t *link = (dev_link_t *)arg;
-    serial_info_t *info = link->priv;
-    int i;
-    
-    DEBUG(0, "serial_release(0x%p)\n", link);
-
-    for (i = 0; i < info->ndev; i++) {
-	unregister_serial(info->line[i]);
-    }
-    link->dev = NULL;
-
-    if (!info->slave) {
-	CardServices(ReleaseConfiguration, link->handle);
-	CardServices(ReleaseIO, link->handle, &link->io);
-	CardServices(ReleaseIRQ, link->handle, &link->irq);
-    }
-    
-    link->state &= ~DEV_CONFIG;
-
-} /* serial_release */
-
-/*======================================================================
-
-    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;
-    serial_info_t *info = link->priv;
-    
-    DEBUG(1, "serial_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    mod_timer(&link->release, jiffies + HZ/20);
-	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;
-} /* serial_event */
-
-/*====================================================================*/
-
-static int __init init_serial_cs(void)
-{
-    servinfo_t serv;
-    DEBUG(0, "%s\n", version);
-    CardServices(GetCardServicesInfo, &serv);
-    if (serv.Revision != CS_RELEASE_CODE) {
-	printk(KERN_NOTICE "serial_cs: Card Services release "
-	       "does not match!\n");
-	return -1;
-    }
-    register_pccard_driver(&dev_info, &serial_attach, &serial_detach);
-    return 0;
-}
-
-static void __exit exit_serial_cs(void)
-{
-    DEBUG(0, "serial_cs: unloading\n");
-    unregister_pccard_driver(&dev_info);
-    while (dev_list != NULL)
-	serial_detach(dev_list);
-}
-
-module_init(init_serial_cs);
-module_exit(exit_serial_cs);
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/char/q40_keyb.c b/drivers/char/q40_keyb.c
--- a/drivers/char/q40_keyb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/char/q40_keyb.c	Wed Jul 24 14:03:38 2002
@@ -31,9 +31,6 @@
 #include <asm/irq.h>
 #include <asm/q40ints.h>
 
-/* Some configuration switches are present in the include file... */
-
-#define KBD_REPORT_ERR
 
 /* Simple translation table for the SysRq keys */
 
@@ -215,7 +212,6 @@
   0, 0, 0, 0, 0, 0, 0, 0			      /* 0x78-0x7f */
 };
 
-static unsigned int prev_scancode = 0;   /* remember E0, E1 */
 
 int q40kbd_setkeycode(unsigned int scancode, unsigned int keycode)
 {
@@ -246,10 +242,21 @@
 int q40kbd_translate(unsigned char scancode, unsigned char *keycode,
 		    char raw_mode)
 {
-  	if (scancode == 0xe0 || scancode == 0xe1) {
+	static int prev_scancode;
+
+	/* special prefix scancodes.. */
+	if (scancode == 0xe0 || scancode == 0xe1) {
 		prev_scancode = scancode;
 		return 0;
- 	}
+	}
+
+	/* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
+	if (scancode == 0x00 || scancode == 0xff) {
+		prev_scancode = 0;
+		return 0;
+	}
+
+	scancode &= 0x7f;
 
 	if (prev_scancode) {
 	  /*
@@ -408,8 +415,6 @@
 	return retval;
 }
 
-extern void q40kbd_leds(unsigned char leds)
-{ /* nothing can be done */ }
 
 static void __init kbd_clear_input(void)
 {
@@ -422,12 +427,9 @@
 }
 
 
-void __init q40kbd_init_hw(void)
+int __init q40kbd_init_hw(void)
 {
-#if 0
-	/* Get the keyboard controller registers (incomplete decode) */
-	request_region(0x60, 16, "keyboard");
-#endif
+
 	/* Flush any pending input. */
 	kbd_clear_input();
 
@@ -436,5 +438,6 @@
 	master_outb(-1,KEYBOARD_UNLOCK_REG);
 	master_outb(1,KEY_IRQ_ENABLE_REG);
 
+	return 0;
 }
 
diff -Nru a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
--- a/drivers/char/ser_a2232.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/char/ser_a2232.c	Wed Jul 24 14:03:37 2002
@@ -90,6 +90,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/tty.h>
 
 #include <asm/setup.h>
 #include <asm/amigaints.h>
diff -Nru a/drivers/char/serial.c b/drivers/char/serial.c
--- a/drivers/char/serial.c	Wed Jul 24 14:03:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,6003 +0,0 @@
-/*
- *  linux/drivers/char/serial.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 
- * 		1998, 1999  Theodore Ts'o
- *
- *  Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92.  Now
- *  much more extensible to support other serial cards based on the
- *  16450/16550A UART's.  Added support for the AST FourPort and the
- *  Accent Async board.  
- *
- *  set_serial_info fixed to set the flags, custom divisor, and uart
- * 	type fields.  Fix suggested by Michael K. Johnson 12/12/92.
- *
- *  11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk>
- *
- *  03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk>
- *
- *  rs_set_termios fixed to look also for changes of the input
- *      flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
- *                                            Bernd Anhäupl 05/17/96.
- *
- *  1/97:  Extended dumb serial ports are a config option now.  
- *         Saves 4k.   Michael A. Griffith <grif@acm.org>
- * 
- *  8/97: Fix bug in rs_set_termios with RTS
- *        Stanislav V. Voronyi <stas@uanet.kharkov.ua>
- *
- *  3/98: Change the IRQ detection, use of probe_irq_o*(),
- *	  suppress TIOCSERGWILD and TIOCSERSWILD
- *	  Etienne Lorrain <etienne.lorrain@ibm.net>
- *
- *  4/98: Added changes to support the ARM architecture proposed by
- * 	  Russell King
- *
- *  5/99: Updated to include support for the XR16C850 and ST16C654
- *        uarts.  Stuart MacDonald <stuartm@connecttech.com>
- *
- *  8/99: Generalized PCI support added.  Theodore Ts'o
- * 
- *  3/00: Rid circular buffer of redundant xmit_cnt.  Fix a
- *	  few races on freeing buffers too.
- *	  Alan Modra <alan@linuxcare.com>
- *
- *  5/00: Support for the RSA-DV II/S card added.
- *	  Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
- * 
- *  6/00: Remove old-style timer, use timer_list
- *        Andrew Morton <andrewm@uow.edu.au>
- *
- *  7/00: Support Timedia/Sunix/Exsys PCI cards
- *
- *  7/00: fix some returns on failure not using MOD_DEC_USE_COUNT.
- *	  Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *
- * 10/00: add in optional software flow control for serial console.
- *	  Kanoj Sarcar <kanoj@sgi.com>  (Modified by Theodore Ts'o)
- *
- */
-
-static char *serial_version = "5.05c";
-static char *serial_revdate = "2001-07-08";
-
-/*
- * Serial driver configuration section.  Here are the various options:
- *
- * CONFIG_HUB6
- *		Enables support for the venerable Bell Technologies
- *		HUB6 card.
- *
- * CONFIG_SERIAL_MANY_PORTS
- * 		Enables support for ports beyond the standard, stupid
- * 		COM 1/2/3/4.
- *
- * CONFIG_SERIAL_MULTIPORT
- * 		Enables support for special multiport board support.
- *
- * CONFIG_SERIAL_SHARE_IRQ
- * 		Enables support for multiple serial ports on one IRQ
- *
- * CONFIG_SERIAL_DETECT_IRQ
- *		Enable the autodetection of IRQ on standart ports
- *
- * SERIAL_PARANOIA_CHECK
- * 		Check the magic number for the async_structure where
- * 		ever possible.
- *
- * CONFIG_SERIAL_ACPI
- *		Enable support for serial console port and serial 
- *		debug port as defined by the SPCR and DBGP tables in 
- *		ACPI 2.0.
- */
-
-#include <linux/config.h>
-#include <linux/version.h>
-
-#undef SERIAL_PARANOIA_CHECK
-#define CONFIG_SERIAL_NOPAUSE_IO
-#define SERIAL_DO_RESTART
-
-#if 0
-/* These defines are normally controlled by the autoconf.h */
-#define CONFIG_SERIAL_MANY_PORTS
-#define CONFIG_SERIAL_SHARE_IRQ
-#define CONFIG_SERIAL_DETECT_IRQ
-#define CONFIG_SERIAL_MULTIPORT
-#define CONFIG_HUB6
-#endif
-
-#ifdef CONFIG_PCI
-#define ENABLE_SERIAL_PCI
-#ifndef CONFIG_SERIAL_SHARE_IRQ
-#define CONFIG_SERIAL_SHARE_IRQ
-#endif
-#ifndef CONFIG_SERIAL_MANY_PORTS
-#define CONFIG_SERIAL_MANY_PORTS
-#endif
-#endif
-
-#ifdef CONFIG_SERIAL_ACPI
-#define ENABLE_SERIAL_ACPI
-#endif
-
-
-/* Set of debugging defines */
-
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-#undef SERIAL_DEBUG_PCI
-#undef SERIAL_DEBUG_AUTOCONF
-
-/* Sanity checks */
-
-#ifdef CONFIG_SERIAL_MULTIPORT
-#ifndef CONFIG_SERIAL_SHARE_IRQ
-#define CONFIG_SERIAL_SHARE_IRQ
-#endif
-#endif
-
-#ifdef CONFIG_HUB6
-#ifndef CONFIG_SERIAL_MANY_PORTS
-#define CONFIG_SERIAL_MANY_PORTS
-#endif
-#ifndef CONFIG_SERIAL_SHARE_IRQ
-#define CONFIG_SERIAL_SHARE_IRQ
-#endif
-#endif
-
-#ifdef MODULE
-#undef CONFIG_SERIAL_CONSOLE
-#endif
-
-#define CONFIG_SERIAL_RSA
-
-#define RS_STROBE_TIME (10*HZ)
-#define RS_ISR_PASS_LIMIT 256
-
-#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
-#define SERIAL_INLINE
-#endif
-  
-/*
- * End of serial driver configuration section.
- */
-
-#include <linux/module.h>
-
-#include <linux/types.h>
-#ifdef LOCAL_HEADERS
-#include "serial_local.h"
-#else
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <asm/serial.h>
-#define LOCAL_VERSTRING ""
-#endif
-
-#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/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#if (LINUX_VERSION_CODE >= 131343)
-#include <linux/init.h>
-#endif
-#if (LINUX_VERSION_CODE >= 131336)
-#include <asm/uaccess.h>
-#endif
-#include <linux/delay.h>
-#ifdef CONFIG_SERIAL_CONSOLE
-#include <linux/console.h>
-#endif
-#ifdef ENABLE_SERIAL_PCI
-#include <linux/pci.h>
-#endif
-
-#include <linux/isapnp.h>
-#ifdef __ISAPNP__
-#ifndef ENABLE_SERIAL_PNP
-#define ENABLE_SERIAL_PNP
-#endif
-#endif
-
-#ifdef CONFIG_MAGIC_SYSRQ
-#include <linux/sysrq.h>
-#endif
-
-/*
- * All of the compatibilty code so we can compile serial.c against
- * older kernels is hidden in serial_compat.h
- */
-#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
-#include "serial_compat.h"
-#endif
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/bitops.h>
-
-#ifdef CONFIG_MAC_SERIAL
-#define SERIAL_DEV_OFFSET	2
-#else
-#define SERIAL_DEV_OFFSET	0
-#endif
-
-#ifdef SERIAL_INLINE
-#define _INLINE_ inline
-#else
-#define _INLINE_
-#endif
-
-static char *serial_name = "Serial driver";
-
-static DECLARE_TASK_QUEUE(tq_serial);
-
-static struct tty_driver serial_driver, callout_driver;
-static int serial_refcount;
-
-static struct timer_list serial_timer;
-
-/* serial subtype definitions */
-#ifndef SERIAL_TYPE_NORMAL
-#define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
-#endif
-
-/* number of characters left in xmit buffer before we ask for more */
-#define WAKEUP_CHARS 256
-
-/*
- * IRQ_timeout		- How long the timeout should be for each IRQ
- * 				should be after the IRQ has been active.
- */
-
-static struct async_struct *IRQ_ports[NR_IRQS];
-#ifdef CONFIG_SERIAL_MULTIPORT
-static struct rs_multiport_struct rs_multiport[NR_IRQS];
-#endif
-static int IRQ_timeout[NR_IRQS];
-#ifdef CONFIG_SERIAL_CONSOLE
-static struct console sercons;
-static int lsr_break_flag;
-#endif
-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-static unsigned long break_pressed; /* break, really ... */
-#endif
-
-static unsigned detect_uart_irq (struct serial_state * state);
-static void autoconfig(struct serial_state * state);
-static void change_speed(struct async_struct *info, struct termios *old);
-static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
-
-/*
- * Here we define the default xmit fifo size used for each type of
- * UART
- */
-static struct serial_uart_config uart_config[] = {
-	{ "unknown", 1, 0 }, 
-	{ "8250", 1, 0 }, 
-	{ "16450", 1, 0 }, 
-	{ "16550", 1, 0 }, 
-	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, 
-	{ "cirrus", 1, 0 }, 	/* usurped by cyclades.c */
-	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH }, 
-	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
-		  UART_STARTECH }, 
-	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
-	{ "Startech", 1, 0},	/* usurped by cyclades.c */
-	{ "16C950/954", 128, UART_CLEAR_FIFO | UART_USE_FIFO},
-	{ "ST16654", 64, UART_CLEAR_FIFO | UART_USE_FIFO |
-		  UART_STARTECH }, 
-	{ "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO |
-		  UART_STARTECH },
-	{ "RSA", 2048, UART_CLEAR_FIFO | UART_USE_FIFO }, 
-	{ 0, 0}
-};
-
-#if defined(CONFIG_SERIAL_RSA) && defined(MODULE)
-
-#define PORT_RSA_MAX 4
-static int probe_rsa[PORT_RSA_MAX];
-static int force_rsa[PORT_RSA_MAX];
-
-MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
-MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
-MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
-MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA");
-#endif /* CONFIG_SERIAL_RSA  */
-
-static struct serial_state rs_table[RS_TABLE_SIZE] = {
-	SERIAL_PORT_DFNS	/* Defined in serial.h */
-};
-
-#define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
-
-#if (defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP))
-#define NR_PCI_BOARDS	8
-
-static struct pci_board_inst	serial_pci_board[NR_PCI_BOARDS];
-
-#ifndef IS_PCI_REGION_IOPORT
-#define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \
-				      IORESOURCE_IO)
-#endif
-#ifndef IS_PCI_REGION_IOMEM
-#define IS_PCI_REGION_IOMEM(dev, r) (pci_resource_flags((dev), (r)) & \
-				      IORESOURCE_MEM)
-#endif
-#ifndef PCI_IRQ_RESOURCE
-#define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq_resource[r].start)
-#endif
-#ifndef pci_get_subvendor
-#define pci_get_subvendor(dev) ((dev)->subsystem_vendor)
-#define pci_get_subdevice(dev)  ((dev)->subsystem_device)
-#endif
-#endif	/* ENABLE_SERIAL_PCI || ENABLE_SERIAL_PNP  */
-
-#ifndef PREPARE_FUNC
-#define PREPARE_FUNC(dev)  (dev->prepare)
-#define ACTIVATE_FUNC(dev)  (dev->activate)
-#define DEACTIVATE_FUNC(dev)  (dev->deactivate)
-#endif
-
-#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
-
-static struct tty_struct *serial_table[NR_PORTS];
-static struct termios *serial_termios[NR_PORTS];
-static struct termios *serial_termios_locked[NR_PORTS];
-
-
-#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
-#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
- kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
-#else
-#define DBG_CNT(s)
-#endif
-
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf;
-#ifdef DECLARE_MUTEX
-static DECLARE_MUTEX(tmp_buf_sem);
-#else
-static struct semaphore tmp_buf_sem = MUTEX;
-#endif
-
-
-static inline int serial_paranoia_check(struct async_struct *info,
-					kdev_t device, const char *routine)
-{
-#ifdef SERIAL_PARANOIA_CHECK
-	static const char *badmagic =
-		"Warning: bad magic number for serial struct (%s) in %s\n";
-	static const char *badinfo =
-		"Warning: null async_struct for (%s) in %s\n";
-
-	if (!info) {
-		printk(badinfo, kdevname(device), routine);
-		return 1;
-	}
-	if (info->magic != SERIAL_MAGIC) {
-		printk(badmagic, kdevname(device), routine);
-		return 1;
-	}
-#endif
-	return 0;
-}
-
-static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
-{
-	switch (info->io_type) {
-#ifdef CONFIG_HUB6
-	case SERIAL_IO_HUB6:
-		outb(info->hub6 - 1 + offset, info->port);
-		return inb(info->port+1);
-#endif
-	case SERIAL_IO_MEM:
-		return readb((unsigned long) info->iomem_base +
-			     (offset<<info->iomem_reg_shift));
-#ifdef CONFIG_SERIAL_GSC
-	case SERIAL_IO_GSC:
-		return gsc_readb(info->iomem_base + offset);
-#endif
-	default:
-		return inb(info->port + offset);
-	}
-}
-
-static _INLINE_ void serial_out(struct async_struct *info, int offset,
-				int value)
-{
-	switch (info->io_type) {
-#ifdef CONFIG_HUB6
-	case SERIAL_IO_HUB6:
-		outb(info->hub6 - 1 + offset, info->port);
-		outb(value, info->port+1);
-		break;
-#endif
-	case SERIAL_IO_MEM:
-		writeb(value, (unsigned long) info->iomem_base +
-			      (offset<<info->iomem_reg_shift));
-		break;
-#ifdef CONFIG_SERIAL_GSC
-	case SERIAL_IO_GSC:
-		gsc_writeb(value, info->iomem_base + offset);
-		break;
-#endif
-	default:
-		outb(value, info->port+offset);
-	}
-}
-
-/*
- * We used to support using pause I/O for certain machines.  We
- * haven't supported this for a while, but just in case it's badly
- * needed for certain old 386 machines, I've left these #define's
- * in....
- */
-#define serial_inp(info, offset)		serial_in(info, offset)
-#define serial_outp(info, offset, value)	serial_out(info, offset, value)
-
-
-/*
- * For the 16C950
- */
-void serial_icr_write(struct async_struct *info, int offset, int  value)
-{
-	serial_out(info, UART_SCR, offset);
-	serial_out(info, UART_ICR, value);
-}
-
-unsigned int serial_icr_read(struct async_struct *info, int offset)
-{
-	int	value;
-
-	serial_icr_write(info, UART_ACR, info->ACR | UART_ACR_ICRRD);
-	serial_out(info, UART_SCR, offset);
-	value = serial_in(info, UART_ICR);
-	serial_icr_write(info, UART_ACR, info->ACR);
-	return value;
-}
-
-/*
- * ------------------------------------------------------------
- * rs_stop() and rs_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * They enable or disable transmitter interrupts, as necessary.
- * ------------------------------------------------------------
- */
-static void rs_stop(struct tty_struct *tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "rs_stop"))
-		return;
-	
-	save_flags(flags); cli();
-	if (info->IER & UART_IER_THRI) {
-		info->IER &= ~UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-	}
-	if (info->state->type == PORT_16C950) {
-		info->ACR |= UART_ACR_TXDIS;
-		serial_icr_write(info, UART_ACR, info->ACR);
-	}
-	restore_flags(flags);
-}
-
-static void rs_start(struct tty_struct *tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-	
-	if (serial_paranoia_check(info, tty->device, "rs_start"))
-		return;
-	
-	save_flags(flags); cli();
-	if (info->xmit.head != info->xmit.tail
-	    && info->xmit.buf
-	    && !(info->IER & UART_IER_THRI)) {
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-	}
-	if (info->state->type == PORT_16C950) {
-		info->ACR &= ~UART_ACR_TXDIS;
-		serial_icr_write(info, UART_ACR, info->ACR);
-	}
-	restore_flags(flags);
-}
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines.  All of the following
- * subroutines are declared as inline and are folded into
- * rs_interrupt().  They were separated out for readability's sake.
- *
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off.  People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
- * possible.  After you are done making modifications, it is not a bad
- * idea to do:
- * 
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-/*
- * This routine is used by the interrupt handler to schedule
- * processing in the software interrupt portion of the driver.
- */
-static _INLINE_ void rs_sched_event(struct async_struct *info,
-				  int event)
-{
-	info->event |= 1 << event;
-	queue_task(&info->tqueue, &tq_serial);
-	mark_bh(SERIAL_BH);
-}
-
-static _INLINE_ void receive_chars(struct async_struct *info,
-				 int *status, struct pt_regs * regs)
-{
-	struct tty_struct *tty = info->tty;
-	unsigned char ch;
-	struct	async_icount *icount;
-	int	max_count = 256;
-
-	icount = &info->state->icount;
-	do {
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-			tty->flip.tqueue.routine((void *) tty);
-			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-				return;		// if TTY_DONT_FLIP is set
-		}
-		ch = serial_inp(info, UART_RX);
-		*tty->flip.char_buf_ptr = ch;
-		icount->rx++;
-		
-#ifdef SERIAL_DEBUG_INTR
-		printk("DR%02x:%02x...", ch, *status);
-#endif
-		*tty->flip.flag_buf_ptr = 0;
-		if (*status & (UART_LSR_BI | UART_LSR_PE |
-			       UART_LSR_FE | UART_LSR_OE)) {
-			/*
-			 * For statistics only
-			 */
-			if (*status & UART_LSR_BI) {
-				*status &= ~(UART_LSR_FE | UART_LSR_PE);
-				icount->brk++;
-				/*
-				 * We do the SysRQ and SAK checking
-				 * here because otherwise the break
-				 * may get masked by ignore_status_mask
-				 * or read_status_mask.
-				 */
-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-				if (info->line == sercons.index) {
-					if (!break_pressed) {
-						break_pressed = jiffies;
-						goto ignore_char;
-					}
-					break_pressed = 0;
-				}
-#endif
-				if (info->flags & ASYNC_SAK)
-					do_SAK(tty);
-			} else if (*status & UART_LSR_PE)
-				icount->parity++;
-			else if (*status & UART_LSR_FE)
-				icount->frame++;
-			if (*status & UART_LSR_OE)
-				icount->overrun++;
-
-			/*
-			 * Mask off conditions which should be ignored.
-			 */
-			*status &= info->read_status_mask;
-
-#ifdef CONFIG_SERIAL_CONSOLE
-			if (info->line == sercons.index) {
-				/* Recover the break flag from console xmit */
-				*status |= lsr_break_flag;
-				lsr_break_flag = 0;
-			}
-#endif
-			if (*status & (UART_LSR_BI)) {
-#ifdef SERIAL_DEBUG_INTR
-				printk("handling break....");
-#endif
-				*tty->flip.flag_buf_ptr = TTY_BREAK;
-			} else if (*status & UART_LSR_PE)
-				*tty->flip.flag_buf_ptr = TTY_PARITY;
-			else if (*status & UART_LSR_FE)
-				*tty->flip.flag_buf_ptr = TTY_FRAME;
-		}
-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-		if (break_pressed && info->line == sercons.index) {
-			if (ch != 0 &&
-			    time_before(jiffies, break_pressed + HZ*5)) {
-				handle_sysrq(ch, regs, NULL);
-				break_pressed = 0;
-				goto ignore_char;
-			}
-			break_pressed = 0;
-		}
-#endif
-		if ((*status & info->ignore_status_mask) == 0) {
-			tty->flip.flag_buf_ptr++;
-			tty->flip.char_buf_ptr++;
-			tty->flip.count++;
-		}
-		if ((*status & UART_LSR_OE) &&
-		    (tty->flip.count < TTY_FLIPBUF_SIZE)) {
-			/*
-			 * Overrun is special, since it's reported
-			 * immediately, and doesn't affect the current
-			 * character
-			 */
-			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
-			tty->flip.count++;
-			tty->flip.flag_buf_ptr++;
-			tty->flip.char_buf_ptr++;
-		}
-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-	ignore_char:
-#endif
-		*status = serial_inp(info, UART_LSR);
-	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
-#if (LINUX_VERSION_CODE > 131394) /* 2.1.66 */
-	tty_flip_buffer_push(tty);
-#else
-	queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
-#endif	
-}
-
-static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
-{
-	int count;
-
-	if (info->x_char) {
-		serial_outp(info, UART_TX, info->x_char);
-		info->state->icount.tx++;
-		info->x_char = 0;
-		if (intr_done)
-			*intr_done = 0;
-		return;
-	}
-	if (info->xmit.head == info->xmit.tail
-	    || info->tty->stopped
-	    || info->tty->hw_stopped) {
-		info->IER &= ~UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-		return;
-	}
-	
-	count = info->xmit_fifo_size;
-	do {
-		serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
-		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
-		info->state->icount.tx++;
-		if (info->xmit.head == info->xmit.tail)
-			break;
-	} while (--count > 0);
-	
-	if (CIRC_CNT(info->xmit.head,
-		     info->xmit.tail,
-		     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
-		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("THRE...");
-#endif
-	if (intr_done)
-		*intr_done = 0;
-
-	if (info->xmit.head == info->xmit.tail) {
-		info->IER &= ~UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-	}
-}
-
-static _INLINE_ void check_modem_status(struct async_struct *info)
-{
-	int	status;
-	struct	async_icount *icount;
-	
-	status = serial_in(info, UART_MSR);
-
-	if (status & UART_MSR_ANY_DELTA) {
-		icount = &info->state->icount;
-		/* update input line counters */
-		if (status & UART_MSR_TERI)
-			icount->rng++;
-		if (status & UART_MSR_DDSR)
-			icount->dsr++;
-		if (status & UART_MSR_DDCD) {
-			icount->dcd++;
-#ifdef CONFIG_HARD_PPS
-			if ((info->flags & ASYNC_HARDPPS_CD) &&
-			    (status & UART_MSR_DCD))
-				hardpps();
-#endif
-		}
-		if (status & UART_MSR_DCTS)
-			icount->cts++;
-		wake_up_interruptible(&info->delta_msr_wait);
-	}
-
-	if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
-#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
-		printk("ttys%d CD now %s...", info->line,
-		       (status & UART_MSR_DCD) ? "on" : "off");
-#endif		
-		if (status & UART_MSR_DCD)
-			wake_up_interruptible(&info->open_wait);
-		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
-#ifdef SERIAL_DEBUG_OPEN
-			printk("doing serial hangup...");
-#endif
-			if (info->tty)
-				tty_hangup(info->tty);
-		}
-	}
-	if (info->flags & ASYNC_CTS_FLOW) {
-		if (info->tty->hw_stopped) {
-			if (status & UART_MSR_CTS) {
-#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
-				printk("CTS tx start...");
-#endif
-				info->tty->hw_stopped = 0;
-				info->IER |= UART_IER_THRI;
-				serial_out(info, UART_IER, info->IER);
-				rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
-				return;
-			}
-		} else {
-			if (!(status & UART_MSR_CTS)) {
-#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
-				printk("CTS tx stop...");
-#endif
-				info->tty->hw_stopped = 1;
-				info->IER &= ~UART_IER_THRI;
-				serial_out(info, UART_IER, info->IER);
-			}
-		}
-	}
-}
-
-#ifdef CONFIG_SERIAL_SHARE_IRQ
-/*
- * This is the serial driver's generic interrupt routine
- */
-static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	int status;
-	struct async_struct * info;
-	int pass_counter = 0;
-	struct async_struct *end_mark = 0;
-#ifdef CONFIG_SERIAL_MULTIPORT	
-	int first_multi = 0;
-	struct rs_multiport_struct *multi;
-#endif
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("rs_interrupt(%d)...", irq);
-#endif
-
-	info = IRQ_ports[irq];
-	if (!info)
-		return;
-
-#ifdef CONFIG_SERIAL_MULTIPORT	
-	multi = &rs_multiport[irq];
-	if (multi->port_monitor)
-		first_multi = inb(multi->port_monitor);
-#endif
-
-	do {
-		if (!info->tty ||
-		    (serial_in(info, UART_IIR) & UART_IIR_NO_INT)) {
-			if (!end_mark)
-				end_mark = info;
-			goto next;
-		}
-#ifdef SERIAL_DEBUG_INTR
-		printk("IIR = %x...", serial_in(info, UART_IIR));
-#endif
-		end_mark = 0;
-
-		info->last_active = jiffies;
-
-		status = serial_inp(info, UART_LSR);
-#ifdef SERIAL_DEBUG_INTR
-		printk("status = %x...", status);
-#endif
-		if (status & UART_LSR_DR)
-			receive_chars(info, &status, regs);
-		check_modem_status(info);
-		if (status & UART_LSR_THRE)
-			transmit_chars(info, 0);
-
-	next:
-		info = info->next_port;
-		if (!info) {
-			info = IRQ_ports[irq];
-			if (pass_counter++ > RS_ISR_PASS_LIMIT) {
-#if 0
-				printk("rs loop break\n");
-#endif
-				break; 	/* Prevent infinite loops */
-			}
-			continue;
-		}
-	} while (end_mark != info);
-#ifdef CONFIG_SERIAL_MULTIPORT	
-	if (multi->port_monitor)
-		printk("rs port monitor (normal) irq %d: 0x%x, 0x%x\n",
-		       info->state->irq, first_multi,
-		       inb(multi->port_monitor));
-#endif
-#ifdef SERIAL_DEBUG_INTR
-	printk("end.\n");
-#endif
-}
-#endif /* #ifdef CONFIG_SERIAL_SHARE_IRQ */
-
-
-/*
- * This is the serial driver's interrupt routine for a single port
- */
-static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
-{
-	int status;
-	int pass_counter = 0;
-	struct async_struct * info;
-#ifdef CONFIG_SERIAL_MULTIPORT	
-	int first_multi = 0;
-	struct rs_multiport_struct *multi;
-#endif
-	
-#ifdef SERIAL_DEBUG_INTR
-	printk("rs_interrupt_single(%d)...", irq);
-#endif
-
-	info = IRQ_ports[irq];
-	if (!info || !info->tty)
-		return;
-
-#ifdef CONFIG_SERIAL_MULTIPORT	
-	multi = &rs_multiport[irq];
-	if (multi->port_monitor)
-		first_multi = inb(multi->port_monitor);
-#endif
-
-	do {
-		status = serial_inp(info, UART_LSR);
-#ifdef SERIAL_DEBUG_INTR
-		printk("status = %x...", status);
-#endif
-		if (status & UART_LSR_DR)
-			receive_chars(info, &status, regs);
-		check_modem_status(info);
-		if (status & UART_LSR_THRE)
-			transmit_chars(info, 0);
-		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
-#if 0
-			printk("rs_single loop break.\n");
-#endif
-			break;
-		}
-#ifdef SERIAL_DEBUG_INTR
-		printk("IIR = %x...", serial_in(info, UART_IIR));
-#endif
-	} while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT));
-	info->last_active = jiffies;
-#ifdef CONFIG_SERIAL_MULTIPORT	
-	if (multi->port_monitor)
-		printk("rs port monitor (single) irq %d: 0x%x, 0x%x\n",
-		       info->state->irq, first_multi,
-		       inb(multi->port_monitor));
-#endif
-#ifdef SERIAL_DEBUG_INTR
-	printk("end.\n");
-#endif
-}
-
-#ifdef CONFIG_SERIAL_MULTIPORT	
-/*
- * This is the serial driver's for multiport boards
- */
-static void rs_interrupt_multi(int irq, void *dev_id, struct pt_regs * regs)
-{
-	int status;
-	struct async_struct * info;
-	int pass_counter = 0;
-	int first_multi= 0;
-	struct rs_multiport_struct *multi;
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("rs_interrupt_multi(%d)...", irq);
-#endif
-
-	info = IRQ_ports[irq];
-	if (!info)
-		return;
-	multi = &rs_multiport[irq];
-	if (!multi->port1) {
-		/* Should never happen */
-		printk("rs_interrupt_multi: NULL port1!\n");
-		return;
-	}
-	if (multi->port_monitor)
-		first_multi = inb(multi->port_monitor);
-	
-	while (1) {
-		if (!info->tty ||
-		    (serial_in(info, UART_IIR) & UART_IIR_NO_INT))
-			goto next;
-
-		info->last_active = jiffies;
-
-		status = serial_inp(info, UART_LSR);
-#ifdef SERIAL_DEBUG_INTR
-		printk("status = %x...", status);
-#endif
-		if (status & UART_LSR_DR)
-			receive_chars(info, &status, regs);
-		check_modem_status(info);
-		if (status & UART_LSR_THRE)
-			transmit_chars(info, 0);
-
-	next:
-		info = info->next_port;
-		if (info)
-			continue;
-
-		info = IRQ_ports[irq];
-		/*
-		 * The user was a bonehead, and misconfigured their
-		 * multiport info.  Rather than lock up the kernel
-		 * in an infinite loop, if we loop too many times,
-		 * print a message and break out of the loop.
-		 */
-		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
-			printk("Misconfigured multiport serial info "
-			       "for irq %d.  Breaking out irq loop\n", irq);
-			break; 
-		}
-		if (multi->port_monitor)
-			printk("rs port monitor irq %d: 0x%x, 0x%x\n",
-			       info->state->irq, first_multi,
-			       inb(multi->port_monitor));
-		if ((inb(multi->port1) & multi->mask1) != multi->match1)
-			continue;
-		if (!multi->port2)
-			break;
-		if ((inb(multi->port2) & multi->mask2) != multi->match2)
-			continue;
-		if (!multi->port3)
-			break;
-		if ((inb(multi->port3) & multi->mask3) != multi->match3)
-			continue;
-		if (!multi->port4)
-			break;
-		if ((inb(multi->port4) & multi->mask4) != multi->match4)
-			continue;
-		break;
-	} 
-#ifdef SERIAL_DEBUG_INTR
-	printk("end.\n");
-#endif
-}
-#endif
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-/*
- * This routine is used to handle the "bottom half" processing for the
- * serial driver, known also the "software interrupt" processing.
- * This processing is done at the kernel interrupt level, after the
- * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
- * is where time-consuming activities which can not be done in the
- * interrupt driver proper are done; the interrupt driver schedules
- * them using rs_sched_event(), and they get done here.
- */
-static void do_serial_bh(void)
-{
-	run_task_queue(&tq_serial);
-}
-
-static void do_softint(void *private_)
-{
-	struct async_struct	*info = (struct async_struct *) private_;
-	struct tty_struct	*tty;
-	
-	tty = info->tty;
-	if (!tty)
-		return;
-
-	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
-#ifdef SERIAL_HAVE_POLL_WAIT
-		wake_up_interruptible(&tty->poll_wait);
-#endif
-	}
-}
-
-/*
- * This subroutine is called when the RS_TIMER goes off.  It is used
- * by the serial driver to handle ports that do not have an interrupt
- * (irq=0).  This doesn't work very well for 16450's, but gives barely
- * passable results for a 16550A.  (Although at the expense of much
- * CPU overhead).
- */
-static void rs_timer(unsigned long dummy)
-{
-	static unsigned long last_strobe;
-	struct async_struct *info;
-	unsigned int	i;
-	unsigned long flags;
-
-	if ((jiffies - last_strobe) >= RS_STROBE_TIME) {
-		for (i=0; i < NR_IRQS; i++) {
-			info = IRQ_ports[i];
-			if (!info)
-				continue;
-			save_flags(flags); cli();
-#ifdef CONFIG_SERIAL_SHARE_IRQ
-			if (info->next_port) {
-				do {
-					serial_out(info, UART_IER, 0);
-					info->IER |= UART_IER_THRI;
-					serial_out(info, UART_IER, info->IER);
-					info = info->next_port;
-				} while (info);
-#ifdef CONFIG_SERIAL_MULTIPORT
-				if (rs_multiport[i].port1)
-					rs_interrupt_multi(i, NULL, NULL);
-				else
-#endif
-					rs_interrupt(i, NULL, NULL);
-			} else
-#endif /* CONFIG_SERIAL_SHARE_IRQ */
-				rs_interrupt_single(i, NULL, NULL);
-			restore_flags(flags);
-		}
-	}
-	last_strobe = jiffies;
-	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
-
-	if (IRQ_ports[0]) {
-		save_flags(flags); cli();
-#ifdef CONFIG_SERIAL_SHARE_IRQ
-		rs_interrupt(0, NULL, NULL);
-#else
-		rs_interrupt_single(0, NULL, NULL);
-#endif
-		restore_flags(flags);
-
-		mod_timer(&serial_timer, jiffies + IRQ_timeout[0]);
-	}
-}
-
-/*
- * ---------------------------------------------------------------
- * Low level utility subroutines for the serial driver:  routines to
- * figure out the appropriate timeout for an interrupt chain, routines
- * to initialize and startup a serial port, and routines to shutdown a
- * serial port.  Useful stuff like that.
- * ---------------------------------------------------------------
- */
-
-/*
- * This routine figures out the correct timeout for a particular IRQ.
- * It uses the smallest timeout of all of the serial ports in a
- * particular interrupt chain.  Now only used for IRQ 0....
- */
-static void figure_IRQ_timeout(int irq)
-{
-	struct	async_struct	*info;
-	int	timeout = 60*HZ;	/* 60 seconds === a long time :-) */
-
-	info = IRQ_ports[irq];
-	if (!info) {
-		IRQ_timeout[irq] = 60*HZ;
-		return;
-	}
-	while (info) {
-		if (info->timeout < timeout)
-			timeout = info->timeout;
-		info = info->next_port;
-	}
-	if (!irq)
-		timeout = timeout / 2;
-	IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1;
-}
-
-#ifdef CONFIG_SERIAL_RSA
-/* Attempts to turn on the RSA FIFO.  Returns zero on failure */
-static int enable_rsa(struct async_struct *info)
-{
-	unsigned char mode;
-	int result;
-	unsigned long flags;
-
-	save_flags(flags); cli();
-	mode = serial_inp(info, UART_RSA_MSR);
-	result = mode & UART_RSA_MSR_FIFO;
-
-	if (!result) {
-		serial_outp(info, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
-		mode = serial_inp(info, UART_RSA_MSR);
-		result = mode & UART_RSA_MSR_FIFO;
-	}
-
-	restore_flags(flags);
-	return result;
-}
-
-/* Attempts to turn off the RSA FIFO.  Returns zero on failure */
-static int disable_rsa(struct async_struct *info)
-{
-	unsigned char mode;
-	int result;
-	unsigned long flags;
-
-	save_flags(flags); cli();
-	mode = serial_inp(info, UART_RSA_MSR);
-	result = !(mode & UART_RSA_MSR_FIFO);
-
-	if (!result) {
-		serial_outp(info, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
-		mode = serial_inp(info, UART_RSA_MSR);
-		result = !(mode & UART_RSA_MSR_FIFO);
-	}
-
-	restore_flags(flags);
-	return result;
-}
-#endif /* CONFIG_SERIAL_RSA */
-
-static int startup(struct async_struct * info)
-{
-	unsigned long flags;
-	int	retval=0;
-	void (*handler)(int, void *, struct pt_regs *);
-	struct serial_state *state= info->state;
-	unsigned long page;
-#ifdef CONFIG_SERIAL_MANY_PORTS
-	unsigned short ICP;
-#endif
-
-	page = get_zeroed_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
-	save_flags(flags); cli();
-
-	if (info->flags & ASYNC_INITIALIZED) {
-		free_page(page);
-		goto errout;
-	}
-
-	if (!CONFIGURED_SERIAL_PORT(state) || !state->type) {
-		if (info->tty)
-			set_bit(TTY_IO_ERROR, &info->tty->flags);
-		free_page(page);
-		goto errout;
-	}
-	if (info->xmit.buf)
-		free_page(page);
-	else
-		info->xmit.buf = (unsigned char *) page;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("starting up ttys%d (irq %d)...", info->line, state->irq);
-#endif
-
-	if (uart_config[state->type].flags & UART_STARTECH) {
-		/* Wake up UART */
-		serial_outp(info, UART_LCR, 0xBF);
-		serial_outp(info, UART_EFR, UART_EFR_ECB);
-		/*
-		 * Turn off LCR == 0xBF so we actually set the IER
-		 * register on the XR16C850
-		 */
-		serial_outp(info, UART_LCR, 0);
-		serial_outp(info, UART_IER, 0);
-		/*
-		 * Now reset LCR so we can turn off the ECB bit
-		 */
-		serial_outp(info, UART_LCR, 0xBF);
-		serial_outp(info, UART_EFR, 0);
-		/*
-		 * For a XR16C850, we need to set the trigger levels
-		 */
-		if (state->type == PORT_16850) {
-			serial_outp(info, UART_FCTR, UART_FCTR_TRGD |
-					UART_FCTR_RX);
-			serial_outp(info, UART_TRG, UART_TRG_96);
-			serial_outp(info, UART_FCTR, UART_FCTR_TRGD |
-					UART_FCTR_TX);
-			serial_outp(info, UART_TRG, UART_TRG_96);
-		}
-		serial_outp(info, UART_LCR, 0);
-	}
-
-	if (state->type == PORT_16750) {
-		/* Wake up UART */
-		serial_outp(info, UART_IER, 0);
-	}
-
-	if (state->type == PORT_16C950) {
-		/* Wake up and initialize UART */
-		info->ACR = 0;
-		serial_outp(info, UART_LCR, 0xBF);
-		serial_outp(info, UART_EFR, UART_EFR_ECB);
-		serial_outp(info, UART_IER, 0);
-		serial_outp(info, UART_LCR, 0);
-		serial_icr_write(info, UART_CSR, 0); /* Reset the UART */
-		serial_outp(info, UART_LCR, 0xBF);
-		serial_outp(info, UART_EFR, UART_EFR_ECB);
-		serial_outp(info, UART_LCR, 0);
-	}
-
-#ifdef CONFIG_SERIAL_RSA
-	/*
-	 * If this is an RSA port, see if we can kick it up to the
-	 * higher speed clock.
-	 */
-	if (state->type == PORT_RSA) {
-		if (state->baud_base != SERIAL_RSA_BAUD_BASE &&
-		    enable_rsa(info))
-			state->baud_base = SERIAL_RSA_BAUD_BASE;
-		if (state->baud_base == SERIAL_RSA_BAUD_BASE)
-			serial_outp(info, UART_RSA_FRR, 0);
-	}
-#endif
-
-	/*
-	 * Clear the FIFO buffers and disable them
-	 * (they will be reenabled in change_speed())
-	 */
-	if (uart_config[state->type].flags & UART_CLEAR_FIFO) {
-		serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-		serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
-					     UART_FCR_CLEAR_RCVR |
-					     UART_FCR_CLEAR_XMIT));
-		serial_outp(info, UART_FCR, 0);
-	}
-
-	/*
-	 * Clear the interrupt registers.
-	 */
-	(void) serial_inp(info, UART_LSR);
-	(void) serial_inp(info, UART_RX);
-	(void) serial_inp(info, UART_IIR);
-	(void) serial_inp(info, UART_MSR);
-
-	/*
-	 * At this point there's no way the LSR could still be 0xFF;
-	 * if it is, then bail out, because there's likely no UART
-	 * here.
-	 */
-	if (!(info->flags & ASYNC_BUGGY_UART) &&
-	    (serial_inp(info, UART_LSR) == 0xff)) {
-		printk("ttyS%d: LSR safety check engaged!\n", state->line);
-		if (capable(CAP_SYS_ADMIN)) {
-			if (info->tty)
-				set_bit(TTY_IO_ERROR, &info->tty->flags);
-		} else
-			retval = -ENODEV;
-		goto errout;
-	}
-	
-	/*
-	 * Allocate the IRQ if necessary
-	 */
-	if (state->irq && (!IRQ_ports[state->irq] ||
-			  !IRQ_ports[state->irq]->next_port)) {
-		if (IRQ_ports[state->irq]) {
-#ifdef CONFIG_SERIAL_SHARE_IRQ
-			free_irq(state->irq, &IRQ_ports[state->irq]);
-#ifdef CONFIG_SERIAL_MULTIPORT				
-			if (rs_multiport[state->irq].port1)
-				handler = rs_interrupt_multi;
-			else
-#endif
-				handler = rs_interrupt;
-#else
-			retval = -EBUSY;
-			goto errout;
-#endif /* CONFIG_SERIAL_SHARE_IRQ */
-		} else 
-			handler = rs_interrupt_single;
-
-		retval = request_irq(state->irq, handler, SA_SHIRQ,
-				     "serial", &IRQ_ports[state->irq]);
-		if (retval) {
-			if (capable(CAP_SYS_ADMIN)) {
-				if (info->tty)
-					set_bit(TTY_IO_ERROR,
-						&info->tty->flags);
-				retval = 0;
-			}
-			goto errout;
-		}
-	}
-
-	/*
-	 * Insert serial port into IRQ chain.
-	 */
-	info->prev_port = 0;
-	info->next_port = IRQ_ports[state->irq];
-	if (info->next_port)
-		info->next_port->prev_port = info;
-	IRQ_ports[state->irq] = info;
-	figure_IRQ_timeout(state->irq);
-
-	/*
-	 * Now, initialize the UART 
-	 */
-	serial_outp(info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
-
-	info->MCR = 0;
-	if (info->tty->termios->c_cflag & CBAUD)
-		info->MCR = UART_MCR_DTR | UART_MCR_RTS;
-#ifdef CONFIG_SERIAL_MANY_PORTS
-	if (info->flags & ASYNC_FOURPORT) {
-		if (state->irq == 0)
-			info->MCR |= UART_MCR_OUT1;
-	} else
-#endif
-	{
-		if (state->irq != 0)
-			info->MCR |= UART_MCR_OUT2;
-	}
-	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
-	serial_outp(info, UART_MCR, info->MCR);
-	
-	/*
-	 * Finally, enable interrupts
-	 */
-	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
-	serial_outp(info, UART_IER, info->IER);	/* enable interrupts */
-	
-#ifdef CONFIG_SERIAL_MANY_PORTS
-	if (info->flags & ASYNC_FOURPORT) {
-		/* Enable interrupts on the AST Fourport board */
-		ICP = (info->port & 0xFE0) | 0x01F;
-		outb_p(0x80, ICP);
-		(void) inb_p(ICP);
-	}
-#endif
-
-	/*
-	 * And clear the interrupt registers again for luck.
-	 */
-	(void)serial_inp(info, UART_LSR);
-	(void)serial_inp(info, UART_RX);
-	(void)serial_inp(info, UART_IIR);
-	(void)serial_inp(info, UART_MSR);
-
-	if (info->tty)
-		clear_bit(TTY_IO_ERROR, &info->tty->flags);
-	info->xmit.head = info->xmit.tail = 0;
-
-	/*
-	 * Set up serial timers...
-	 */
-	mod_timer(&serial_timer, jiffies + 2*HZ/100);
-
-	/*
-	 * Set up the tty->alt_speed kludge
-	 */
-#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
-	if (info->tty) {
-		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-			info->tty->alt_speed = 57600;
-		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-			info->tty->alt_speed = 115200;
-		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-			info->tty->alt_speed = 230400;
-		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-			info->tty->alt_speed = 460800;
-	}
-#endif
-	
-	/*
-	 * and set the speed of the serial port
-	 */
-	change_speed(info, 0);
-
-	info->flags |= ASYNC_INITIALIZED;
-	restore_flags(flags);
-	return 0;
-	
-errout:
-	restore_flags(flags);
-	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.
- */
-static void shutdown(struct async_struct * info)
-{
-	unsigned long	flags;
-	struct serial_state *state;
-	int		retval;
-
-	if (!(info->flags & ASYNC_INITIALIZED))
-		return;
-
-	state = info->state;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("Shutting down serial port %d (irq %d)....", info->line,
-	       state->irq);
-#endif
-	
-	save_flags(flags); cli(); /* Disable interrupts */
-
-	/*
-	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
-	 * here so the queue might never be waken up
-	 */
-	wake_up_interruptible(&info->delta_msr_wait);
-	
-	/*
-	 * First unlink the serial port from the IRQ chain...
-	 */
-	if (info->next_port)
-		info->next_port->prev_port = info->prev_port;
-	if (info->prev_port)
-		info->prev_port->next_port = info->next_port;
-	else
-		IRQ_ports[state->irq] = info->next_port;
-	figure_IRQ_timeout(state->irq);
-	
-	/*
-	 * Free the IRQ, if necessary
-	 */
-	if (state->irq && (!IRQ_ports[state->irq] ||
-			  !IRQ_ports[state->irq]->next_port)) {
-		if (IRQ_ports[state->irq]) {
-			free_irq(state->irq, &IRQ_ports[state->irq]);
-			retval = request_irq(state->irq, rs_interrupt_single,
-					     SA_SHIRQ, "serial",
-					     &IRQ_ports[state->irq]);
-			
-			if (retval)
-				printk("serial shutdown: request_irq: error %d"
-				       "  Couldn't reacquire IRQ.\n", retval);
-		} else
-			free_irq(state->irq, &IRQ_ports[state->irq]);
-	}
-
-	if (info->xmit.buf) {
-		unsigned long pg = (unsigned long) info->xmit.buf;
-		info->xmit.buf = 0;
-		free_page(pg);
-	}
-
-	info->IER = 0;
-	serial_outp(info, UART_IER, 0x00);	/* disable all intrs */
-#ifdef CONFIG_SERIAL_MANY_PORTS
-	if (info->flags & ASYNC_FOURPORT) {
-		/* reset interrupts on the AST Fourport board */
-		(void) inb((info->port & 0xFE0) | 0x01F);
-		info->MCR |= UART_MCR_OUT1;
-	} else
-#endif
-		info->MCR &= ~UART_MCR_OUT2;
-	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
-	
-	/* disable break condition */
-	serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
-	
-	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
-		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-	serial_outp(info, UART_MCR, info->MCR);
-
-	/* disable FIFO's */	
-	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
-				     UART_FCR_CLEAR_RCVR |
-				     UART_FCR_CLEAR_XMIT));
-	serial_outp(info, UART_FCR, 0);
-
-#ifdef CONFIG_SERIAL_RSA
-	/*
-	 * Reset the RSA board back to 115kbps compat mode.
-	 */
-	if ((state->type == PORT_RSA) &&
-	    (state->baud_base == SERIAL_RSA_BAUD_BASE &&
-	     disable_rsa(info)))
-		state->baud_base = SERIAL_RSA_BAUD_BASE_LO;
-#endif
-	
-
-	(void)serial_in(info, UART_RX);    /* read data port to reset things */
-	
-	if (info->tty)
-		set_bit(TTY_IO_ERROR, &info->tty->flags);
-
-	if (uart_config[info->state->type].flags & UART_STARTECH) {
-		/* Arrange to enter sleep mode */
-		serial_outp(info, UART_LCR, 0xBF);
-		serial_outp(info, UART_EFR, UART_EFR_ECB);
-		serial_outp(info, UART_LCR, 0);
-		serial_outp(info, UART_IER, UART_IERX_SLEEP);
-		serial_outp(info, UART_LCR, 0xBF);
-		serial_outp(info, UART_EFR, 0);
-		serial_outp(info, UART_LCR, 0);
-	}
-	if (info->state->type == PORT_16750) {
-		/* Arrange to enter sleep mode */
-		serial_outp(info, UART_IER, UART_IERX_SLEEP);
-	}
-	info->flags &= ~ASYNC_INITIALIZED;
-	restore_flags(flags);
-}
-
-#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
-static int baud_table[] = {
-	0, 50, 75, 110, 134, 150, 200, 300,
-	600, 1200, 1800, 2400, 4800, 9600, 19200,
-	38400, 57600, 115200, 230400, 460800, 0 };
-
-static int tty_get_baud_rate(struct tty_struct *tty)
-{
-	struct async_struct * info = (struct async_struct *)tty->driver_data;
-	unsigned int cflag, i;
-
-	cflag = tty->termios->c_cflag;
-
-	i = cflag & CBAUD;
-	if (i & CBAUDEX) {
-		i &= ~CBAUDEX;
-		if (i < 1 || i > 2) 
-			tty->termios->c_cflag &= ~CBAUDEX;
-		else
-			i += 15;
-	}
-	if (i == 15) {
-		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-			i += 1;
-		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-			i += 2;
-	}
-	return baud_table[i];
-}
-#endif
-
-/*
- * This routine is called to set the UART divisor registers to match
- * the specified baud rate for a serial port.
- */
-static void change_speed(struct async_struct *info,
-			 struct termios *old_termios)
-{
-	int	quot = 0, baud_base, baud;
-	unsigned cflag, cval, fcr = 0;
-	int	bits;
-	unsigned long	flags;
-
-	if (!info->tty || !info->tty->termios)
-		return;
-	cflag = info->tty->termios->c_cflag;
-	if (!CONFIGURED_SERIAL_PORT(info))
-		return;
-
-	/* byte size and parity */
-	switch (cflag & CSIZE) {
-	      case CS5: cval = 0x00; bits = 7; break;
-	      case CS6: cval = 0x01; bits = 8; break;
-	      case CS7: cval = 0x02; bits = 9; break;
-	      case CS8: cval = 0x03; bits = 10; break;
-	      /* Never happens, but GCC is too dumb to figure it out */
-	      default:  cval = 0x00; bits = 7; break;
-	      }
-	if (cflag & CSTOPB) {
-		cval |= 0x04;
-		bits++;
-	}
-	if (cflag & PARENB) {
-		cval |= UART_LCR_PARITY;
-		bits++;
-	}
-	if (!(cflag & PARODD))
-		cval |= UART_LCR_EPAR;
-#ifdef CMSPAR
-	if (cflag & CMSPAR)
-		cval |= UART_LCR_SPAR;
-#endif
-
-	/* Determine divisor based on baud rate */
-	baud = tty_get_baud_rate(info->tty);
-	if (!baud)
-		baud = 9600;	/* B0 transition handled in rs_set_termios */
-#ifdef CONFIG_SERIAL_RSA
-	if ((info->state->type == PORT_RSA) &&
-	    (info->state->baud_base != SERIAL_RSA_BAUD_BASE) &&
-	    enable_rsa(info))
-		info->state->baud_base = SERIAL_RSA_BAUD_BASE;
-#endif
-	baud_base = info->state->baud_base;
-	if (info->state->type == PORT_16C950) {
-		if (baud <= baud_base)
-			serial_icr_write(info, UART_TCR, 0);
-		else if (baud <= 2*baud_base) {
-			serial_icr_write(info, UART_TCR, 0x8);
-			baud_base = baud_base * 2;
-		} else if (baud <= 4*baud_base) {
-			serial_icr_write(info, UART_TCR, 0x4);
-			baud_base = baud_base * 4;
-		} else
-			serial_icr_write(info, UART_TCR, 0);
-	}
-	if (baud == 38400 &&
-	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
-		quot = info->state->custom_divisor;
-	else {
-		if (baud == 134)
-			/* Special case since 134 is really 134.5 */
-			quot = (2*baud_base / 269);
-		else if (baud)
-			quot = baud_base / baud;
-	}
-	/* If the quotient is zero refuse the change */
-	if (!quot && old_termios) {
-		info->tty->termios->c_cflag &= ~CBAUD;
-		info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
-		baud = tty_get_baud_rate(info->tty);
-		if (!baud)
-			baud = 9600;
-		if (baud == 38400 &&
-		    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
-			quot = info->state->custom_divisor;
-		else {
-			if (baud == 134)
-				/* Special case since 134 is really 134.5 */
-				quot = (2*baud_base / 269);
-			else if (baud)
-				quot = baud_base / baud;
-		}
-	}
-	/* As a last resort, if the quotient is zero, default to 9600 bps */
-	if (!quot)
-		quot = baud_base / 9600;
-	/*
-	 * Work around a bug in the Oxford Semiconductor 952 rev B
-	 * chip which causes it to seriously miscalculate baud rates
-	 * when DLL is 0.
-	 */
-	if (((quot & 0xFF) == 0) && (info->state->type == PORT_16C950) &&
-	    (info->state->revision == 0x5201))
-		quot++;
-	
-	info->quot = quot;
-	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
-	info->timeout += HZ/50;		/* Add .02 seconds of slop */
-
-	/* Set up FIFO's */
-	if (uart_config[info->state->type].flags & UART_USE_FIFO) {
-		if ((info->state->baud_base / quot) < 2400)
-			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
-#ifdef CONFIG_SERIAL_RSA
-		else if (info->state->type == PORT_RSA)
-			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14;
-#endif
-		else
-			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
-	}
-	if (info->state->type == PORT_16750)
-		fcr |= UART_FCR7_64BYTE;
-	
-	/* CTS flow control flag and modem status interrupts */
-	info->IER &= ~UART_IER_MSI;
-	if (info->flags & ASYNC_HARDPPS_CD)
-		info->IER |= UART_IER_MSI;
-	if (cflag & CRTSCTS) {
-		info->flags |= ASYNC_CTS_FLOW;
-		info->IER |= UART_IER_MSI;
-	} else
-		info->flags &= ~ASYNC_CTS_FLOW;
-	if (cflag & CLOCAL)
-		info->flags &= ~ASYNC_CHECK_CD;
-	else {
-		info->flags |= ASYNC_CHECK_CD;
-		info->IER |= UART_IER_MSI;
-	}
-	serial_out(info, UART_IER, info->IER);
-
-	/*
-	 * Set up parity check flag
-	 */
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
-	info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
-	if (I_INPCK(info->tty))
-		info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
-		info->read_status_mask |= UART_LSR_BI;
-	
-	/*
-	 * Characters to ignore
-	 */
-	info->ignore_status_mask = 0;
-	if (I_IGNPAR(info->tty))
-		info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
-	if (I_IGNBRK(info->tty)) {
-		info->ignore_status_mask |= UART_LSR_BI;
-		/*
-		 * If we're ignore parity and break indicators, ignore 
-		 * overruns too.  (For real raw support).
-		 */
-		if (I_IGNPAR(info->tty))
-			info->ignore_status_mask |= UART_LSR_OE;
-	}
-	/*
-	 * !!! ignore all characters if CREAD is not set
-	 */
-	if ((cflag & CREAD) == 0)
-		info->ignore_status_mask |= UART_LSR_DR;
-	save_flags(flags); cli();
-	if (uart_config[info->state->type].flags & UART_STARTECH) {
-		serial_outp(info, UART_LCR, 0xBF);
-		serial_outp(info, UART_EFR,
-			    (cflag & CRTSCTS) ? UART_EFR_CTS : 0);
-	}
-	serial_outp(info, UART_LCR, cval | UART_LCR_DLAB);	/* set DLAB */
-	serial_outp(info, UART_DLL, quot & 0xff);	/* LS of divisor */
-	serial_outp(info, UART_DLM, quot >> 8);		/* MS of divisor */
-	if (info->state->type == PORT_16750)
-		serial_outp(info, UART_FCR, fcr); 	/* set fcr */
-	serial_outp(info, UART_LCR, cval);		/* reset DLAB */
-	info->LCR = cval;				/* Save LCR */
- 	if (info->state->type != PORT_16750) {
- 		if (fcr & UART_FCR_ENABLE_FIFO) {
- 			/* emulated UARTs (Lucent Venus 167x) need two steps */
- 			serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
- 		}
-		serial_outp(info, UART_FCR, fcr); 	/* set fcr */
-	}
-	restore_flags(flags);
-}
-
-static void rs_put_char(struct tty_struct *tty, unsigned char ch)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
-		return;
-
-	if (!tty || !info->xmit.buf)
-		return;
-
-	save_flags(flags); cli();
-	if (CIRC_SPACE(info->xmit.head,
-		       info->xmit.tail,
-		       SERIAL_XMIT_SIZE) == 0) {
-		restore_flags(flags);
-		return;
-	}
-
-	info->xmit.buf[info->xmit.head] = ch;
-	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
-	restore_flags(flags);
-}
-
-static void rs_flush_chars(struct tty_struct *tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-				
-	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
-		return;
-
-	if (info->xmit.head == info->xmit.tail
-	    || tty->stopped
-	    || tty->hw_stopped
-	    || !info->xmit.buf)
-		return;
-
-	save_flags(flags); cli();
-	info->IER |= UART_IER_THRI;
-	serial_out(info, UART_IER, info->IER);
-	restore_flags(flags);
-}
-
-static int rs_write(struct tty_struct * tty, int from_user,
-		    const unsigned char *buf, int count)
-{
-	int	c, ret = 0;
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-				
-	if (serial_paranoia_check(info, tty->device, "rs_write"))
-		return 0;
-
-	if (!tty || !info->xmit.buf || !tmp_buf)
-		return 0;
-
-	save_flags(flags);
-	if (from_user) {
-		down(&tmp_buf_sem);
-		while (1) {
-			int c1;
-			c = CIRC_SPACE_TO_END(info->xmit.head,
-					      info->xmit.tail,
-					      SERIAL_XMIT_SIZE);
-			if (count < c)
-				c = count;
-			if (c <= 0)
-				break;
-
-			c -= copy_from_user(tmp_buf, buf, c);
-			if (!c) {
-				if (!ret)
-					ret = -EFAULT;
-				break;
-			}
-			cli();
-			c1 = CIRC_SPACE_TO_END(info->xmit.head,
-					       info->xmit.tail,
-					       SERIAL_XMIT_SIZE);
-			if (c1 < c)
-				c = c1;
-			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
-			info->xmit.head = ((info->xmit.head + c) &
-					   (SERIAL_XMIT_SIZE-1));
-			restore_flags(flags);
-			buf += c;
-			count -= c;
-			ret += c;
-		}
-		up(&tmp_buf_sem);
-	} else {
-		cli();
-		while (1) {
-			c = CIRC_SPACE_TO_END(info->xmit.head,
-					      info->xmit.tail,
-					      SERIAL_XMIT_SIZE);
-			if (count < c)
-				c = count;
-			if (c <= 0) {
-				break;
-			}
-			memcpy(info->xmit.buf + info->xmit.head, buf, c);
-			info->xmit.head = ((info->xmit.head + c) &
-					   (SERIAL_XMIT_SIZE-1));
-			buf += c;
-			count -= c;
-			ret += c;
-		}
-		restore_flags(flags);
-	}
-	if (info->xmit.head != info->xmit.tail
-	    && !tty->stopped
-	    && !tty->hw_stopped
-	    && !(info->IER & UART_IER_THRI)) {
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-	}
-	return ret;
-}
-
-static int rs_write_room(struct tty_struct *tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
-		return 0;
-	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-}
-
-static int rs_chars_in_buffer(struct tty_struct *tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-				
-	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
-		return 0;
-	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-}
-
-static void rs_flush_buffer(struct tty_struct *tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-	
-	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
-		return;
-	save_flags(flags); cli();
-	info->xmit.head = info->xmit.tail = 0;
-	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
-#ifdef SERIAL_HAVE_POLL_WAIT
-	wake_up_interruptible(&tty->poll_wait);
-#endif
-	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 rs_send_xchar(struct tty_struct *tty, char ch)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->device, "rs_send_char"))
-		return;
-
-	info->x_char = ch;
-	if (ch) {
-		/* Make sure transmit interrupts are on */
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-	}
-}
-
-/*
- * ------------------------------------------------------------
- * rs_throttle()
- * 
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void rs_throttle(struct tty_struct * tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-	
-	printk("throttle %s: %d....\n", tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
-		return;
-	
-	if (I_IXOFF(tty))
-		rs_send_xchar(tty, STOP_CHAR(tty));
-
-	if (tty->termios->c_cflag & CRTSCTS)
-		info->MCR &= ~UART_MCR_RTS;
-
-	save_flags(flags); cli();
-	serial_out(info, UART_MCR, info->MCR);
-	restore_flags(flags);
-}
-
-static void rs_unthrottle(struct tty_struct * tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-	
-	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
-		return;
-	
-	if (I_IXOFF(tty)) {
-		if (info->x_char)
-			info->x_char = 0;
-		else
-			rs_send_xchar(tty, START_CHAR(tty));
-	}
-	if (tty->termios->c_cflag & CRTSCTS)
-		info->MCR |= UART_MCR_RTS;
-	save_flags(flags); cli();
-	serial_out(info, UART_MCR, info->MCR);
-	restore_flags(flags);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-static int get_serial_info(struct async_struct * info,
-			   struct serial_struct * retinfo)
-{
-	struct serial_struct tmp;
-	struct serial_state *state = info->state;
-   
-	if (!retinfo)
-		return -EFAULT;
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.type = state->type;
-	tmp.line = state->line;
-	tmp.port = state->port;
-	if (HIGH_BITS_OFFSET)
-		tmp.port_high = state->port >> HIGH_BITS_OFFSET;
-	else
-		tmp.port_high = 0;
-	tmp.irq = state->irq;
-	tmp.flags = state->flags;
-	tmp.xmit_fifo_size = state->xmit_fifo_size;
-	tmp.baud_base = state->baud_base;
-	tmp.close_delay = state->close_delay;
-	tmp.closing_wait = state->closing_wait;
-	tmp.custom_divisor = state->custom_divisor;
-	tmp.hub6 = state->hub6;
-	tmp.io_type = state->io_type;
-	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
-		return -EFAULT;
-	return 0;
-}
-
-static int set_serial_info(struct async_struct * info,
-			   struct serial_struct * new_info)
-{
-	struct serial_struct new_serial;
- 	struct serial_state old_state, *state;
-	unsigned int		i,change_irq,change_port;
-	int 			retval = 0;
-	unsigned long		new_port;
-
-	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
-		return -EFAULT;
-	state = info->state;
-	old_state = *state;
-
-	new_port = new_serial.port;
-	if (HIGH_BITS_OFFSET)
-		new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
-
-	change_irq = new_serial.irq != state->irq;
-	change_port = (new_port != ((int) state->port)) ||
-		(new_serial.hub6 != state->hub6);
-  
-	if (!capable(CAP_SYS_ADMIN)) {
-		if (change_irq || change_port ||
-		    (new_serial.baud_base != state->baud_base) ||
-		    (new_serial.type != state->type) ||
-		    (new_serial.close_delay != state->close_delay) ||
-		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
-		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
-		     (state->flags & ~ASYNC_USR_MASK)))
-			return -EPERM;
-		state->flags = ((state->flags & ~ASYNC_USR_MASK) |
-			       (new_serial.flags & ASYNC_USR_MASK));
-		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
-			       (new_serial.flags & ASYNC_USR_MASK));
-		state->custom_divisor = new_serial.custom_divisor;
-		goto check_and_exit;
-	}
-
-	new_serial.irq = irq_cannonicalize(new_serial.irq);
-
-	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || 
-	    (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
-	    (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
-	    (new_serial.type == PORT_STARTECH)) {
-		return -EINVAL;
-	}
-
-	if ((new_serial.type != state->type) ||
-	    (new_serial.xmit_fifo_size <= 0))
-		new_serial.xmit_fifo_size =
-			uart_config[new_serial.type].dfl_xmit_fifo_size;
-
-	/* Make sure address is not already in use */
-	if (new_serial.type) {
-		for (i = 0 ; i < NR_PORTS; i++)
-			if ((state != &rs_table[i]) &&
-			    (rs_table[i].port == new_port) &&
-			    rs_table[i].type)
-				return -EADDRINUSE;
-	}
-
-	if ((change_port || change_irq) && (state->count > 1))
-		return -EBUSY;
-
-	/*
-	 * OK, past this point, all the error checking has been done.
-	 * At this point, we start making changes.....
-	 */
-
-	state->baud_base = new_serial.baud_base;
-	state->flags = ((state->flags & ~ASYNC_FLAGS) |
-			(new_serial.flags & ASYNC_FLAGS));
-	info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
-		       (info->flags & ASYNC_INTERNAL_FLAGS));
-	state->custom_divisor = new_serial.custom_divisor;
-	state->close_delay = new_serial.close_delay * HZ/100;
-	state->closing_wait = new_serial.closing_wait * HZ/100;
-#if (LINUX_VERSION_CODE > 0x20100)
-	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-#endif
-	info->xmit_fifo_size = state->xmit_fifo_size =
-		new_serial.xmit_fifo_size;
-
-	if ((state->type != PORT_UNKNOWN) && state->port) {
-#ifdef CONFIG_SERIAL_RSA
-		if (old_state.type == PORT_RSA)
-			release_region(state->port + UART_RSA_BASE, 16);
-		else
-#endif
-		release_region(state->port,8);
-	}
-	state->type = new_serial.type;
-	if (change_port || change_irq) {
-		/*
-		 * We need to shutdown the serial port at the old
-		 * port/irq combination.
-		 */
-		shutdown(info);
-		state->irq = new_serial.irq;
-		info->port = state->port = new_port;
-		info->hub6 = state->hub6 = new_serial.hub6;
-		if (info->hub6)
-			info->io_type = state->io_type = SERIAL_IO_HUB6;
-		else if (info->io_type == SERIAL_IO_HUB6)
-			info->io_type = state->io_type = SERIAL_IO_PORT;
-	}
-	if ((state->type != PORT_UNKNOWN) && state->port) {
-#ifdef CONFIG_SERIAL_RSA
-		if (state->type == PORT_RSA)
-			request_region(state->port + UART_RSA_BASE,
-				       16, "serial_rsa(set)");
-		else
-#endif
-			request_region(state->port,8,"serial(set)");
-	}
-
-	
-check_and_exit:
-	if (!state->port || !state->type)
-		return 0;
-	if (info->flags & ASYNC_INITIALIZED) {
-		if (((old_state.flags & ASYNC_SPD_MASK) !=
-		     (state->flags & ASYNC_SPD_MASK)) ||
-		    (old_state.custom_divisor != state->custom_divisor)) {
-#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
-			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-				info->tty->alt_speed = 57600;
-			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-				info->tty->alt_speed = 115200;
-			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-				info->tty->alt_speed = 230400;
-			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-				info->tty->alt_speed = 460800;
-#endif
-			change_speed(info, 0);
-		}
-	} else
-		retval = startup(info);
-	return retval;
-}
-
-
-/*
- * get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * 	    is emptied.  On bus types like RS485, the transmitter must
- * 	    release the bus after transmitting. This must be done when
- * 	    the transmit shift register is empty, not be done when the
- * 	    transmit holding register is empty.  This functionality
- * 	    allows an RS485 driver to be written in user space. 
- */
-static int get_lsr_info(struct async_struct * info, unsigned int *value)
-{
-	unsigned char status;
-	unsigned int result;
-	unsigned long flags;
-
-	save_flags(flags); cli();
-	status = serial_in(info, UART_LSR);
-	restore_flags(flags);
-	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
-
-	/*
-	 * 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 (info->x_char || 
-	    ((CIRC_CNT(info->xmit.head, info->xmit.tail,
-		       SERIAL_XMIT_SIZE) > 0) &&
-	     !info->tty->stopped && !info->tty->hw_stopped))
-		result &= ~TIOCSER_TEMT;
-
-	if (copy_to_user(value, &result, sizeof(int)))
-		return -EFAULT;
-	return 0;
-}
-
-
-static int get_modem_info(struct async_struct * info, unsigned int *value)
-{
-	unsigned char control, status;
-	unsigned int result;
-	unsigned long flags;
-
-	control = info->MCR;
-	save_flags(flags); cli();
-	status = serial_in(info, UART_MSR);
-	restore_flags(flags);
-	result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
-		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
-#ifdef TIOCM_OUT1
-		| ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0)
-		| ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0)
-#endif
-		| ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
-		| ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
-		| ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
-		| ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
-
-	if (copy_to_user(value, &result, sizeof(int)))
-		return -EFAULT;
-	return 0;
-}
-
-static int set_modem_info(struct async_struct * info, unsigned int cmd,
-			  unsigned int *value)
-{
-	unsigned int arg;
-	unsigned long flags;
-
-	if (copy_from_user(&arg, value, sizeof(int)))
-		return -EFAULT;
-
-	switch (cmd) {
-	case TIOCMBIS: 
-		if (arg & TIOCM_RTS)
-			info->MCR |= UART_MCR_RTS;
-		if (arg & TIOCM_DTR)
-			info->MCR |= UART_MCR_DTR;
-#ifdef TIOCM_OUT1
-		if (arg & TIOCM_OUT1)
-			info->MCR |= UART_MCR_OUT1;
-		if (arg & TIOCM_OUT2)
-			info->MCR |= UART_MCR_OUT2;
-#endif
-		if (arg & TIOCM_LOOP)
-			info->MCR |= UART_MCR_LOOP;
-		break;
-	case TIOCMBIC:
-		if (arg & TIOCM_RTS)
-			info->MCR &= ~UART_MCR_RTS;
-		if (arg & TIOCM_DTR)
-			info->MCR &= ~UART_MCR_DTR;
-#ifdef TIOCM_OUT1
-		if (arg & TIOCM_OUT1)
-			info->MCR &= ~UART_MCR_OUT1;
-		if (arg & TIOCM_OUT2)
-			info->MCR &= ~UART_MCR_OUT2;
-#endif
-		if (arg & TIOCM_LOOP)
-			info->MCR &= ~UART_MCR_LOOP;
-		break;
-	case TIOCMSET:
-		info->MCR = ((info->MCR & ~(UART_MCR_RTS |
-#ifdef TIOCM_OUT1
-					    UART_MCR_OUT1 |
-					    UART_MCR_OUT2 |
-#endif
-					    UART_MCR_LOOP |
-					    UART_MCR_DTR))
-			     | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
-#ifdef TIOCM_OUT1
-			     | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
-			     | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
-#endif
-			     | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0)
-			     | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
-		break;
-	default:
-		return -EINVAL;
-	}
-	save_flags(flags); cli();
-	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
-	serial_out(info, UART_MCR, info->MCR);
-	restore_flags(flags);
-	return 0;
-}
-
-static int do_autoconfig(struct async_struct * info)
-{
-	int irq, retval;
-	
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-	
-	if (info->state->count > 1)
-		return -EBUSY;
-	
-	shutdown(info);
-
-	autoconfig(info->state);
-	if ((info->state->flags & ASYNC_AUTO_IRQ) &&
-	    (info->state->port != 0  || info->state->iomem_base != 0) &&
-	    (info->state->type != PORT_UNKNOWN)) {
-		irq = detect_uart_irq(info->state);
-		if (irq > 0)
-			info->state->irq = irq;
-	}
-
-	retval = startup(info);
-	if (retval)
-		return retval;
-	return 0;
-}
-
-/*
- * rs_break() --- routine which turns the break handling on or off
- */
-#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
-static void send_break(	struct async_struct * info, int duration)
-{
-	if (!CONFIGURED_SERIAL_PORT(info))
-		return;
-	current->state = TASK_INTERRUPTIBLE;
-	current->timeout = jiffies + duration;
-	cli();
-	info->LCR |= UART_LCR_SBC;
-	serial_out(info, UART_LCR, info->LCR);
-	schedule();
-	info->LCR &= ~UART_LCR_SBC;
-	serial_out(info, UART_LCR, info->LCR);
-	sti();
-}
-#else
-static void rs_break(struct tty_struct *tty, int break_state)
-{
-	struct async_struct * info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-	
-	if (serial_paranoia_check(info, tty->device, "rs_break"))
-		return;
-
-	if (!CONFIGURED_SERIAL_PORT(info))
-		return;
-	save_flags(flags); cli();
-	if (break_state == -1)
-		info->LCR |= UART_LCR_SBC;
-	else
-		info->LCR &= ~UART_LCR_SBC;
-	serial_out(info, UART_LCR, info->LCR);
-	restore_flags(flags);
-}
-#endif
-
-#ifdef CONFIG_SERIAL_MULTIPORT
-static int get_multiport_struct(struct async_struct * info,
-				struct serial_multiport_struct *retinfo)
-{
-	struct serial_multiport_struct ret;
-	struct rs_multiport_struct *multi;
-	
-	multi = &rs_multiport[info->state->irq];
-
-	ret.port_monitor = multi->port_monitor;
-	
-	ret.port1 = multi->port1;
-	ret.mask1 = multi->mask1;
-	ret.match1 = multi->match1;
-	
-	ret.port2 = multi->port2;
-	ret.mask2 = multi->mask2;
-	ret.match2 = multi->match2;
-	
-	ret.port3 = multi->port3;
-	ret.mask3 = multi->mask3;
-	ret.match3 = multi->match3;
-	
-	ret.port4 = multi->port4;
-	ret.mask4 = multi->mask4;
-	ret.match4 = multi->match4;
-
-	ret.irq = info->state->irq;
-
-	if (copy_to_user(retinfo,&ret,sizeof(*retinfo)))
-		return -EFAULT;
-	return 0;
-}
-
-static int set_multiport_struct(struct async_struct * info,
-				struct serial_multiport_struct *in_multi)
-{
-	struct serial_multiport_struct new_multi;
-	struct rs_multiport_struct *multi;
-	struct serial_state *state;
-	int	was_multi, now_multi;
-	int	retval;
-	void (*handler)(int, void *, struct pt_regs *);
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-	state = info->state;
-	
-	if (copy_from_user(&new_multi, in_multi,
-			   sizeof(struct serial_multiport_struct)))
-		return -EFAULT;
-	
-	if (new_multi.irq != state->irq || state->irq == 0 ||
-	    !IRQ_ports[state->irq])
-		return -EINVAL;
-
-	multi = &rs_multiport[state->irq];
-	was_multi = (multi->port1 != 0);
-	
-	multi->port_monitor = new_multi.port_monitor;
-	
-	if (multi->port1)
-		release_region(multi->port1,1);
-	multi->port1 = new_multi.port1;
-	multi->mask1 = new_multi.mask1;
-	multi->match1 = new_multi.match1;
-	if (multi->port1)
-		request_region(multi->port1,1,"serial(multiport1)");
-
-	if (multi->port2)
-		release_region(multi->port2,1);
-	multi->port2 = new_multi.port2;
-	multi->mask2 = new_multi.mask2;
-	multi->match2 = new_multi.match2;
-	if (multi->port2)
-		request_region(multi->port2,1,"serial(multiport2)");
-
-	if (multi->port3)
-		release_region(multi->port3,1);
-	multi->port3 = new_multi.port3;
-	multi->mask3 = new_multi.mask3;
-	multi->match3 = new_multi.match3;
-	if (multi->port3)
-		request_region(multi->port3,1,"serial(multiport3)");
-
-	if (multi->port4)
-		release_region(multi->port4,1);
-	multi->port4 = new_multi.port4;
-	multi->mask4 = new_multi.mask4;
-	multi->match4 = new_multi.match4;
-	if (multi->port4)
-		request_region(multi->port4,1,"serial(multiport4)");
-
-	now_multi = (multi->port1 != 0);
-	
-	if (IRQ_ports[state->irq]->next_port &&
-	    (was_multi != now_multi)) {
-		free_irq(state->irq, &IRQ_ports[state->irq]);
-		if (now_multi)
-			handler = rs_interrupt_multi;
-		else
-			handler = rs_interrupt;
-
-		retval = request_irq(state->irq, handler, SA_SHIRQ,
-				     "serial", &IRQ_ports[state->irq]);
-		if (retval) {
-			printk("Couldn't reallocate serial interrupt "
-			       "driver!!\n");
-		}
-	}
-	return 0;
-}
-#endif
-
-static int rs_ioctl(struct tty_struct *tty, struct file * file,
-		    unsigned int cmd, unsigned long arg)
-{
-	struct async_struct * info = (struct async_struct *)tty->driver_data;
-	struct async_icount cprev, cnow;	/* kernel counter temps */
-	struct serial_icounter_struct icount;
-	unsigned long flags;
-#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
-	int retval, tmp;
-#endif
-	
-	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
-		return -ENODEV;
-
-	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
-	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
-	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
-		if (tty->flags & (1 << TTY_IO_ERROR))
-		    return -EIO;
-	}
-	
-	switch (cmd) {
-#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
-		case TCSBRK:	/* SVID version: non-zero arg --> no break */
-			retval = tty_check_change(tty);
-			if (retval)
-				return retval;
-			tty_wait_until_sent(tty, 0);
-			if (signal_pending(current))
-				return -EINTR;
-			if (!arg) {
-				send_break(info, HZ/4);	/* 1/4 second */
-				if (signal_pending(current))
-					return -EINTR;
-			}
-			return 0;
-		case TCSBRKP:	/* support for POSIX tcsendbreak() */
-			retval = tty_check_change(tty);
-			if (retval)
-				return retval;
-			tty_wait_until_sent(tty, 0);
-			if (signal_pending(current))
-				return -EINTR;
-			send_break(info, arg ? arg*(HZ/10) : HZ/4);
-			if (signal_pending(current))
-				return -EINTR;
-			return 0;
-		case TIOCGSOFTCAR:
-			tmp = C_CLOCAL(tty) ? 1 : 0;
-			if (copy_to_user((void *)arg, &tmp, sizeof(int)))
-				return -EFAULT;
-			return 0;
-		case TIOCSSOFTCAR:
-			if (copy_from_user(&tmp, (void *)arg, sizeof(int)))
-				return -EFAULT;
-
-			tty->termios->c_cflag =
-				((tty->termios->c_cflag & ~CLOCAL) |
-				 (tmp ? CLOCAL : 0));
-			return 0;
-#endif
-		case TIOCMGET:
-			return get_modem_info(info, (unsigned int *) arg);
-		case TIOCMBIS:
-		case TIOCMBIC:
-		case TIOCMSET:
-			return set_modem_info(info, cmd, (unsigned int *) arg);
-		case TIOCGSERIAL:
-			return get_serial_info(info,
-					       (struct serial_struct *) arg);
-		case TIOCSSERIAL:
-			return set_serial_info(info,
-					       (struct serial_struct *) arg);
-		case TIOCSERCONFIG:
-			return do_autoconfig(info);
-
-		case TIOCSERGETLSR: /* Get line status register */
-			return get_lsr_info(info, (unsigned int *) arg);
-
-		case TIOCSERGSTRUCT:
-			if (copy_to_user((struct async_struct *) arg,
-					 info, sizeof(struct async_struct)))
-				return -EFAULT;
-			return 0;
-				
-#ifdef CONFIG_SERIAL_MULTIPORT
-		case TIOCSERGETMULTI:
-			return get_multiport_struct(info,
-				       (struct serial_multiport_struct *) arg);
-		case TIOCSERSETMULTI:
-			return set_multiport_struct(info,
-				       (struct serial_multiport_struct *) arg);
-#endif
-			
-		/*
-		 * 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
-		 */
-		case TIOCMIWAIT:
-			save_flags(flags); cli();
-			/* note the counters on entry */
-			cprev = info->state->icount;
-			restore_flags(flags);
-			/* Force modem status interrupts on */
-			info->IER |= UART_IER_MSI;
-			serial_out(info, UART_IER, info->IER);
-			while (1) {
-				interruptible_sleep_on(&info->delta_msr_wait);
-				/* see if a signal did it */
-				if (signal_pending(current))
-					return -ERESTARTSYS;
-				save_flags(flags); cli();
-				cnow = info->state->icount; /* atomic copy */
-				restore_flags(flags);
-				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
-				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-					return -EIO; /* no change => error */
-				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)) ) {
-					return 0;
-				}
-				cprev = cnow;
-			}
-			/* NOTREACHED */
-
-		/* 
-		 * 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.
-		 */
-		case TIOCGICOUNT:
-			save_flags(flags); cli();
-			cnow = info->state->icount;
-			restore_flags(flags);
-			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;
-			
-			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
-				return -EFAULT;
-			return 0;
-		case TIOCSERGWILD:
-		case TIOCSERSWILD:
-			/* "setserial -W" is called in Debian boot */
-			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
-			return 0;
-
-		default:
-			return -ENOIOCTLCMD;
-		}
-	return 0;
-}
-
-static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-	unsigned int cflag = tty->termios->c_cflag;
-	
-	if (   (cflag == old_termios->c_cflag)
-	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
-		== RELEVANT_IFLAG(old_termios->c_iflag)))
-	  return;
-
-	change_speed(info, old_termios);
-
-	/* Handle transition to B0 status */
-	if ((old_termios->c_cflag & CBAUD) &&
-	    !(cflag & CBAUD)) {
-		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-		save_flags(flags); cli();
-		serial_out(info, UART_MCR, info->MCR);
-		restore_flags(flags);
-	}
-	
-	/* Handle transition away from B0 status */
-	if (!(old_termios->c_cflag & CBAUD) &&
-	    (cflag & CBAUD)) {
-		info->MCR |= UART_MCR_DTR;
-		if (!(tty->termios->c_cflag & CRTSCTS) || 
-		    !test_bit(TTY_THROTTLED, &tty->flags)) {
-			info->MCR |= UART_MCR_RTS;
-		}
-		save_flags(flags); cli();
-		serial_out(info, UART_MCR, info->MCR);
-		restore_flags(flags);
-	}
-	
-	/* Handle turning off CRTSCTS */
-	if ((old_termios->c_cflag & CRTSCTS) &&
-	    !(tty->termios->c_cflag & CRTSCTS)) {
-		tty->hw_stopped = 0;
-		rs_start(tty);
-	}
-
-#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(&info->open_wait);
-#endif
-}
-
-/*
- * ------------------------------------------------------------
- * rs_close()
- * 
- * This routine is called when the serial port gets closed.  First, we
- * wait for the last remaining data to be sent.  Then, we unlink its
- * async structure from the interrupt chain if necessary, and we free
- * that IRQ if nothing is left in the chain.
- * ------------------------------------------------------------
- */
-static void rs_close(struct tty_struct *tty, struct file * filp)
-{
-	struct async_struct * info = (struct async_struct *)tty->driver_data;
-	struct serial_state *state;
-	unsigned long flags;
-
-	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
-		return;
-
-	state = info->state;
-	
-	save_flags(flags); cli();
-	
-	if (tty_hung_up_p(filp)) {
-		DBG_CNT("before DEC-hung");
-		MOD_DEC_USE_COUNT;
-		restore_flags(flags);
-		return;
-	}
-	
-#ifdef SERIAL_DEBUG_OPEN
-	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
-#endif
-	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("rs_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 ttys%d: %d\n",
-		       info->line, state->count);
-		state->count = 0;
-	}
-	if (state->count) {
-		DBG_CNT("before DEC-2");
-		MOD_DEC_USE_COUNT;
-		restore_flags(flags);
-		return;
-	}
-	info->flags |= ASYNC_CLOSING;
-	restore_flags(flags);
-	/*
-	 * Save the termios structure, since this port may have
-	 * separate termios for callout and dialin.
-	 */
-	if (info->flags & ASYNC_NORMAL_ACTIVE)
-		info->state->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->state->callout_termios = *tty->termios;
-	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
-	 * the line discipline to only process XON/XOFF characters.
-	 */
-	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
-	/*
-	 * At this point we stop accepting input.  To do this, we
-	 * disable the receive line status interrupts, and tell the
-	 * interrupt driver to stop checking the data ready bit in the
-	 * line status register.
-	 */
-	info->IER &= ~UART_IER_RLSI;
-	info->read_status_mask &= ~UART_LSR_DR;
-	if (info->flags & ASYNC_INITIALIZED) {
-		serial_out(info, UART_IER, info->IER);
-		/*
-		 * Before we drop DTR, make sure the UART transmitter
-		 * has completely drained; this is especially
-		 * important if there is a transmit FIFO!
-		 */
-		rs_wait_until_sent(tty, info->timeout);
-	}
-	shutdown(info);
-	if (tty->driver.flush_buffer)
-		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
-	tty->closing = 0;
-	info->event = 0;
-	info->tty = 0;
-	if (info->blocked_open) {
-		if (info->close_delay) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(info->close_delay);
-		}
-		wake_up_interruptible(&info->open_wait);
-	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
-	wake_up_interruptible(&info->close_wait);
-	MOD_DEC_USE_COUNT;
-}
-
-/*
- * rs_wait_until_sent() --- wait until the transmitter is empty
- */
-static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-	struct async_struct * info = (struct async_struct *)tty->driver_data;
-	unsigned long orig_jiffies, char_time;
-	int lsr;
-	
-	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
-		return;
-
-	if (info->state->type == PORT_UNKNOWN)
-		return;
-
-	if (info->xmit_fifo_size == 0)
-		return; /* Just in case.... */
-
-	orig_jiffies = jiffies;
-	/*
-	 * 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 = (info->timeout - HZ/50) / info->xmit_fifo_size;
-	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 info->timeout, this is probably due to a
-	 * UART bug of some kind.  So, we clamp the timeout parameter at
-	 * 2*info->timeout.
-	 */
-	if (!timeout || timeout > 2*info->timeout)
-		timeout = 2*info->timeout;
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
-	printk("jiff=%lu...", jiffies);
-#endif
-	while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) {
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
-#endif
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(char_time);
-		if (signal_pending(current))
-			break;
-		if (timeout && time_after(jiffies, orig_jiffies + timeout))
-			break;
-	}
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
-#endif
-}
-
-/*
- * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void rs_hangup(struct tty_struct *tty)
-{
-	struct async_struct * info = (struct async_struct *)tty->driver_data;
-	struct serial_state *state = info->state;
-	
-	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
-		return;
-
-	state = info->state;
-	
-	rs_flush_buffer(tty);
-	if (info->flags & ASYNC_CLOSING)
-		return;
-	shutdown(info);
-	info->event = 0;
-	state->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
-	info->tty = 0;
-	wake_up_interruptible(&info->open_wait);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_open() and friends
- * ------------------------------------------------------------
- */
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
-			   struct async_struct *info)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	struct serial_state *state = info->state;
-	int		retval;
-	int		do_clocal = 0, extra_count = 0;
-	unsigned long	flags;
-
-	/*
-	 * If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (info->flags & ASYNC_CLOSING)) {
-		if (info->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&info->close_wait);
-#ifdef SERIAL_DO_RESTART
-		return ((info->flags & ASYNC_HUP_NOTIFY) ?
-			-EAGAIN : -ERESTARTSYS);
-#else
-		return -EAGAIN;
-#endif
-	}
-
-	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
-	 * If non-blocking mode is set, or the port is not enabled,
-	 * then make the check up front and then exit.
-	 */
-	if ((filp->f_flags & O_NONBLOCK) ||
-	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
-		info->flags |= ASYNC_NORMAL_ACTIVE;
-		return 0;
-	}
-
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (state->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
-	/*
-	 * Block waiting for the carrier detect and the line to become
-	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, state->count is dropped by one, so that
-	 * rs_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&info->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready before block: ttys%d, count = %d\n",
-	       state->line, state->count);
-#endif
-	save_flags(flags); cli();
-	if (!tty_hung_up_p(filp)) {
-		extra_count = 1;
-		state->count--;
-	}
-	restore_flags(flags);
-	info->blocked_open++;
-	while (1) {
-		save_flags(flags); cli();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD))
-			serial_out(info, UART_MCR,
-				   serial_inp(info, UART_MCR) |
-				   (UART_MCR_DTR | UART_MCR_RTS));
-		restore_flags(flags);
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp) ||
-		    !(info->flags & ASYNC_INITIALIZED)) {
-#ifdef SERIAL_DO_RESTART
-			if (info->flags & ASYNC_HUP_NOTIFY)
-				retval = -EAGAIN;
-			else
-				retval = -ERESTARTSYS;	
-#else
-			retval = -EAGAIN;
-#endif
-			break;
-		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
-		    (do_clocal || (serial_in(info, UART_MSR) &
-				   UART_MSR_DCD)))
-			break;
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-#ifdef SERIAL_DEBUG_OPEN
-		printk("block_til_ready blocking: ttys%d, count = %d\n",
-		       info->line, state->count);
-#endif
-		schedule();
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&info->open_wait, &wait);
-	if (extra_count)
-		state->count++;
-	info->blocked_open--;
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready after blocking: ttys%d, count = %d\n",
-	       info->line, state->count);
-#endif
-	if (retval)
-		return retval;
-	info->flags |= ASYNC_NORMAL_ACTIVE;
-	return 0;
-}
-
-static int get_async_struct(int line, struct async_struct **ret_info)
-{
-	struct async_struct *info;
-	struct serial_state *sstate;
-
-	sstate = rs_table + line;
-	sstate->count++;
-	info = sstate->info;
-
-	/*
-	 * If the async_struct is already allocated, do the fastpath.
-	 */
-	if (info)
-		goto out;
-
-	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
-	if (!info) {
-		sstate->count--;
-		return -ENOMEM;
-	}
-
-	memset(info, 0, sizeof(struct async_struct));
-	init_waitqueue_head(&info->open_wait);
-	init_waitqueue_head(&info->close_wait);
-	init_waitqueue_head(&info->delta_msr_wait);
-	info->magic = SERIAL_MAGIC;
-	info->port = sstate->port;
-	info->hub6 = sstate->hub6;
-	info->flags = sstate->flags;
-	info->xmit_fifo_size = sstate->xmit_fifo_size;
-	info->state = sstate;
-	info->line = line;
-	info->iomem_base = sstate->iomem_base;
-	info->iomem_reg_shift = sstate->iomem_reg_shift;
-	info->io_type = sstate->io_type;
-	info->tqueue.routine = do_softint;
-	info->tqueue.data = info;
-
-	if (sstate->info) {
-		kfree(info);
-		info = sstate->info;
-	} else {
-		sstate->info = info;
-	}
-
-out:
-	/*
-	 * If this is the first open, copy over some timeouts.
-	 */
-	if (sstate->count == 1) {
-		info->closing_wait = sstate->closing_wait;
-	}
-	*ret_info = info;
-	return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened.  It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain.   It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int rs_open(struct tty_struct *tty, struct file * filp)
-{
-	struct async_struct	*info;
-	int 			retval, line;
-	unsigned long		page;
-
-	MOD_INC_USE_COUNT;
-	line = minor(tty->device) - tty->driver.minor_start;
-	if ((line < 0) || (line >= NR_PORTS)) {
-		MOD_DEC_USE_COUNT;
-		return -ENODEV;
-	}
-	retval = get_async_struct(line, &info);
-	if (retval) {
-		MOD_DEC_USE_COUNT;
-		return retval;
-	}
-	tty->driver_data = info;
-	info->tty = tty;
-	if (serial_paranoia_check(info, tty->device, "rs_open")) {
-		MOD_DEC_USE_COUNT;		
-		return -ENODEV;
-	}
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
-	       info->state->count);
-#endif
-#if (LINUX_VERSION_CODE > 0x20100)
-	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-#endif
-
-	/*
-	 *	This relies on lock_kernel() stuff so wants tidying for 2.5
-	 */
-	if (!tmp_buf) {
-		page = get_zeroed_page(GFP_KERNEL);
-		if (!page) {
-			MOD_DEC_USE_COUNT;
-			return -ENOMEM;
-		}
-		if (tmp_buf)
-			free_page(page);
-		else
-			tmp_buf = (unsigned char *) page;
-	}
-
-	/*
-	 * If the port is the middle of closing, bail out now
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (info->flags & ASYNC_CLOSING)) {
-		if (info->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&info->close_wait);
-		MOD_DEC_USE_COUNT;
-#ifdef SERIAL_DO_RESTART
-		return ((info->flags & ASYNC_HUP_NOTIFY) ?
-			-EAGAIN : -ERESTARTSYS);
-#else
-		return -EAGAIN;
-#endif
-	}
-
-	/*
-	 * Start up serial port
-	 */
-	retval = startup(info);
-	if (retval) {
-		MOD_DEC_USE_COUNT;
-		return retval;
-	}
-
-	retval = block_til_ready(tty, filp, info);
-	if (retval) {
-#ifdef SERIAL_DEBUG_OPEN
-		printk("rs_open returning after block_til_ready with %d\n",
-		       retval);
-#endif
-		MOD_DEC_USE_COUNT;
-		return retval;
-	}
-
-	if ((info->state->count == 1) &&
-	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->state->normal_termios;
-		else 
-			*tty->termios = info->state->callout_termios;
-		change_speed(info, 0);
-	}
-#ifdef CONFIG_SERIAL_CONSOLE
-	if (sercons.cflag && sercons.index == line) {
-		tty->termios->c_cflag = sercons.cflag;
-		sercons.cflag = 0;
-		change_speed(info, 0);
-	}
-#endif
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("rs_open ttys%d successful...", info->line);
-#endif
-	return 0;
-}
-
-/*
- * /proc fs routines....
- */
-
-static inline int line_info(char *buf, struct serial_state *state)
-{
-	struct async_struct *info = state->info, scr_info;
-	char	stat_buf[30], control, status;
-	int	ret;
-	unsigned long flags;
-
-	ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
-		      state->line, uart_config[state->type].name, 
-		      state->port, state->irq);
-
-	if (!state->port || (state->type == PORT_UNKNOWN)) {
-		ret += sprintf(buf+ret, "\n");
-		return ret;
-	}
-
-	/*
-	 * Figure out the current RS-232 lines
-	 */
-	if (!info) {
-		info = &scr_info;	/* This is just for serial_{in,out} */
-
-		info->magic = SERIAL_MAGIC;
-		info->port = state->port;
-		info->flags = state->flags;
-		info->hub6 = state->hub6;
-		info->io_type = state->io_type;
-		info->iomem_base = state->iomem_base;
-		info->iomem_reg_shift = state->iomem_reg_shift;
-		info->quot = 0;
-		info->tty = 0;
-	}
-	save_flags(flags); cli();
-	status = serial_in(info, UART_MSR);
-	control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR);
-	restore_flags(flags); 
-
-	stat_buf[0] = 0;
-	stat_buf[1] = 0;
-	if (control & UART_MCR_RTS)
-		strcat(stat_buf, "|RTS");
-	if (status & UART_MSR_CTS)
-		strcat(stat_buf, "|CTS");
-	if (control & UART_MCR_DTR)
-		strcat(stat_buf, "|DTR");
-	if (status & UART_MSR_DSR)
-		strcat(stat_buf, "|DSR");
-	if (status & UART_MSR_DCD)
-		strcat(stat_buf, "|CD");
-	if (status & UART_MSR_RI)
-		strcat(stat_buf, "|RI");
-
-	if (info->quot) {
-		ret += sprintf(buf+ret, " baud:%d",
-			       state->baud_base / info->quot);
-	}
-
-	ret += sprintf(buf+ret, " tx:%d rx:%d",
-		      state->icount.tx, state->icount.rx);
-
-	if (state->icount.frame)
-		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
-	
-	if (state->icount.parity)
-		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
-	
-	if (state->icount.brk)
-		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
-
-	if (state->icount.overrun)
-		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
-
-	/*
-	 * Last thing is the RS-232 status lines
-	 */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
-	return ret;
-}
-
-int rs_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
-{
-	int i, len = 0, l;
-	off_t	begin = 0;
-
-	len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n",
-		       serial_version, LOCAL_VERSTRING, serial_revdate);
-	for (i = 0; i < NR_PORTS && len < 4000; i++) {
-		l = line_info(page + len, &rs_table[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);
-}
-
-/*
- * ---------------------------------------------------------------------
- * rs_init() and friends
- *
- * rs_init() is called at boot-time to initialize the serial driver.
- * ---------------------------------------------------------------------
- */
-
-/*
- * This routine prints out the appropriate serial driver version
- * number, and identifies which options were configured into this
- * driver.
- */
-static char serial_options[] __initdata =
-#ifdef CONFIG_HUB6
-       " HUB-6"
-#define SERIAL_OPT
-#endif
-#ifdef CONFIG_SERIAL_MANY_PORTS
-       " MANY_PORTS"
-#define SERIAL_OPT
-#endif
-#ifdef CONFIG_SERIAL_MULTIPORT
-       " MULTIPORT"
-#define SERIAL_OPT
-#endif
-#ifdef CONFIG_SERIAL_SHARE_IRQ
-       " SHARE_IRQ"
-#define SERIAL_OPT
-#endif
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-       " DETECT_IRQ"
-#define SERIAL_OPT
-#endif
-#ifdef ENABLE_SERIAL_PCI
-       " SERIAL_PCI"
-#define SERIAL_OPT
-#endif
-#ifdef ENABLE_SERIAL_PNP
-       " ISAPNP"
-#define SERIAL_OPT
-#endif
-#ifdef ENABLE_SERIAL_ACPI
-       " SERIAL_ACPI"
-#define SERIAL_OPT
-#endif
-#ifdef SERIAL_OPT
-       " enabled\n";
-#else
-       " no serial options enabled\n";
-#endif
-#undef SERIAL_OPT
-
-static _INLINE_ void show_serial_version(void)
-{
- 	printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name,
-	       serial_version, LOCAL_VERSTRING, serial_revdate,
-	       serial_options);
-}
-
-/*
- * This routine detect the IRQ of a serial port by clearing OUT2 when
- * no UART interrupt are requested (IER = 0) (*GPL*). This seems to work at
- * each time, as long as no other device permanently request the IRQ.
- * If no IRQ is detected, or multiple IRQ appear, this function returns 0.
- * The variable "state" and the field "state->port" should not be null.
- */
-static unsigned detect_uart_irq (struct serial_state * state)
-{
-	int irq;
-	unsigned long irqs;
-	unsigned char save_mcr, save_ier;
-	struct async_struct scr_info; /* serial_{in,out} because HUB6 */
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-	unsigned char save_ICP=0; /* no warning */
-	unsigned short ICP=0;
-
-	if (state->flags & ASYNC_FOURPORT)  {
-		ICP = (state->port & 0xFE0) | 0x01F;
-		save_ICP = inb_p(ICP);
-		outb_p(0x80, ICP);
-		(void) inb_p(ICP);
-	}
-#endif
-	scr_info.magic = SERIAL_MAGIC;
-	scr_info.state = state;
-	scr_info.port = state->port;
-	scr_info.flags = state->flags;
-#ifdef CONFIG_HUB6
-	scr_info.hub6 = state->hub6;
-#endif
-	scr_info.io_type = state->io_type;
-	scr_info.iomem_base = state->iomem_base;
-	scr_info.iomem_reg_shift = state->iomem_reg_shift;
-
-	/* forget possible initially masked and pending IRQ */
-	probe_irq_off(probe_irq_on());
-	save_mcr = serial_inp(&scr_info, UART_MCR);
-	save_ier = serial_inp(&scr_info, UART_IER);
-	serial_outp(&scr_info, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
-	
-	irqs = probe_irq_on();
-	serial_outp(&scr_info, UART_MCR, 0);
-	udelay (10);
-	if (state->flags & ASYNC_FOURPORT)  {
-		serial_outp(&scr_info, UART_MCR,
-			    UART_MCR_DTR | UART_MCR_RTS);
-	} else {
-		serial_outp(&scr_info, UART_MCR,
-			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
-	}
-	serial_outp(&scr_info, UART_IER, 0x0f);	/* enable all intrs */
-	(void)serial_inp(&scr_info, UART_LSR);
-	(void)serial_inp(&scr_info, UART_RX);
-	(void)serial_inp(&scr_info, UART_IIR);
-	(void)serial_inp(&scr_info, UART_MSR);
-	serial_outp(&scr_info, UART_TX, 0xFF);
-	udelay (20);
-	irq = probe_irq_off(irqs);
-
-	serial_outp(&scr_info, UART_MCR, save_mcr);
-	serial_outp(&scr_info, UART_IER, save_ier);
-#ifdef CONFIG_SERIAL_MANY_PORTS
-	if (state->flags & ASYNC_FOURPORT)
-		outb_p(save_ICP, ICP);
-#endif
-	return (irq > 0)? irq : 0;
-}
-
-/*
- * This is a quickie test to see how big the FIFO is.
- * It doesn't work at all the time, more's the pity.
- */
-static int size_fifo(struct async_struct *info)
-{
-	unsigned char old_fcr, old_mcr, old_dll, old_dlm;
-	int count;
-
-	old_fcr = serial_inp(info, UART_FCR);
-	old_mcr = serial_inp(info, UART_MCR);
-	serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO |
-		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-	serial_outp(info, UART_MCR, UART_MCR_LOOP);
-	serial_outp(info, UART_LCR, UART_LCR_DLAB);
-	old_dll = serial_inp(info, UART_DLL);
-	old_dlm = serial_inp(info, UART_DLM);
-	serial_outp(info, UART_DLL, 0x01);
-	serial_outp(info, UART_DLM, 0x00);
-	serial_outp(info, UART_LCR, 0x03);
-	for (count = 0; count < 256; count++)
-		serial_outp(info, UART_TX, count);
-	mdelay(20);
-	for (count = 0; (serial_inp(info, UART_LSR) & UART_LSR_DR) &&
-	     (count < 256); count++)
-		serial_inp(info, UART_RX);
-	serial_outp(info, UART_FCR, old_fcr);
-	serial_outp(info, UART_MCR, old_mcr);
-	serial_outp(info, UART_LCR, UART_LCR_DLAB);
-	serial_outp(info, UART_DLL, old_dll);
-	serial_outp(info, UART_DLM, old_dlm);
-
-	return count;
-}
-
-/*
- * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
- * When this function is called we know it is at least a StarTech
- * 16650 V2, but it might be one of several StarTech UARTs, or one of
- * its clones.  (We treat the broken original StarTech 16650 V1 as a
- * 16550, and why not?  Startech doesn't seem to even acknowledge its
- * existence.)
- * 
- * What evil have men's minds wrought...
- */
-static void autoconfig_startech_uarts(struct async_struct *info,
-				      struct serial_state *state,
-				      unsigned long flags)
-{
-	unsigned char scratch, scratch2, scratch3, scratch4;
-
-	/*
-	 * First we check to see if it's an Oxford Semiconductor UART.
-	 *
-	 * If we have to do this here because some non-National
-	 * Semiconductor clone chips lock up if you try writing to the
-	 * LSR register (which serial_icr_read does)
-	 */
-	if (state->type == PORT_16550A) {
-		/*
-		 * EFR [4] must be set else this test fails
-		 *
-		 * This shouldn't be necessary, but Mike Hudson
-		 * (Exoray@isys.ca) claims that it's needed for 952
-		 * dual UART's (which are not recommended for new designs).
-		 */
-		info->ACR = 0;
-		serial_out(info, UART_LCR, 0xBF);
-		serial_out(info, UART_EFR, 0x10);
-		serial_out(info, UART_LCR, 0x00);
-		/* Check for Oxford Semiconductor 16C950 */
-		scratch = serial_icr_read(info, UART_ID1);
-		scratch2 = serial_icr_read(info, UART_ID2);
-		scratch3 = serial_icr_read(info, UART_ID3);
-		
-		if (scratch == 0x16 && scratch2 == 0xC9 &&
-		    (scratch3 == 0x50 || scratch3 == 0x52 ||
-		     scratch3 == 0x54)) {
-			state->type = PORT_16C950;
-			state->revision = serial_icr_read(info, UART_REV) |
-				(scratch3 << 8);
-			return;
-		}
-	}
-	
-	/*
-	 * We check for a XR16C850 by setting DLL and DLM to 0, and
-	 * then reading back DLL and DLM.  If DLM reads back 0x10,
-	 * then the UART is a XR16C850 and the DLL contains the chip
-	 * revision.  If DLM reads back 0x14, then the UART is a
-	 * XR16C854.
-	 * 
-	 */
-
-	/* Save the DLL and DLM */
-
-	serial_outp(info, UART_LCR, UART_LCR_DLAB);
-	scratch3 = serial_inp(info, UART_DLL);
-	scratch4 = serial_inp(info, UART_DLM);
-
-	serial_outp(info, UART_DLL, 0);
-	serial_outp(info, UART_DLM, 0);
-	scratch2 = serial_inp(info, UART_DLL);
-	scratch = serial_inp(info, UART_DLM);
-	serial_outp(info, UART_LCR, 0);
-
-	if (scratch == 0x10 || scratch == 0x14) {
-		if (scratch == 0x10)
-			state->revision = scratch2;
-		state->type = PORT_16850;
-		return;
-	}
-
-	/* Restore the DLL and DLM */
-
-	serial_outp(info, UART_LCR, UART_LCR_DLAB);
-	serial_outp(info, UART_DLL, scratch3);
-	serial_outp(info, UART_DLM, scratch4);
-	serial_outp(info, UART_LCR, 0);
-	/*
-	 * We distinguish between the '654 and the '650 by counting
-	 * how many bytes are in the FIFO.  I'm using this for now,
-	 * since that's the technique that was sent to me in the
-	 * serial driver update, but I'm not convinced this works.
-	 * I've had problems doing this in the past.  -TYT
-	 */
-	if (size_fifo(info) == 64)
-		state->type = PORT_16654;
-	else
-		state->type = PORT_16650V2;
-}
-
-/*
- * This routine is called by rs_init() to initialize a specific serial
- * port.  It determines what type of UART chip this serial port is
- * using: 8250, 16450, 16550, 16550A.  The important question is
- * whether or not this UART is a 16550A or not, since this will
- * determine whether or not we can use its FIFO features or not.
- */
-static void autoconfig(struct serial_state * state)
-{
-	unsigned char status1, status2, scratch, scratch2, scratch3;
-	unsigned char save_lcr, save_mcr;
-	struct async_struct *info, scr_info;
-	unsigned long flags;
-
-	state->type = PORT_UNKNOWN;
-
-#ifdef SERIAL_DEBUG_AUTOCONF
-	printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line,
-	       state->port, (unsigned) state->iomem_base);
-#endif
-	
-	if (!CONFIGURED_SERIAL_PORT(state))
-		return;
-		
-	info = &scr_info;	/* This is just for serial_{in,out} */
-
-	info->magic = SERIAL_MAGIC;
-	info->state = state;
-	info->port = state->port;
-	info->flags = state->flags;
-#ifdef CONFIG_HUB6
-	info->hub6 = state->hub6;
-#endif
-	info->io_type = state->io_type;
-	info->iomem_base = state->iomem_base;
-	info->iomem_reg_shift = state->iomem_reg_shift;
-
-	save_flags(flags); cli();
-	
-	if (!(state->flags & ASYNC_BUGGY_UART) &&
-	    !state->iomem_base) {
-		/*
-		 * Do a simple existence test first; if we fail this,
-		 * there's no point trying anything else.
-		 * 
-		 * 0x80 is used as a nonsense port to prevent against
-		 * false positives due to ISA bus float.  The
-		 * assumption is that 0x80 is a non-existent port;
-		 * which should be safe since include/asm/io.h also
-		 * makes this assumption.
-		 */
-		scratch = serial_inp(info, UART_IER);
-		serial_outp(info, UART_IER, 0);
-#ifdef __i386__
-		outb(0xff, 0x080);
-#endif
-		scratch2 = serial_inp(info, UART_IER);
-		serial_outp(info, UART_IER, 0x0F);
-#ifdef __i386__
-		outb(0, 0x080);
-#endif
-		scratch3 = serial_inp(info, UART_IER);
-		serial_outp(info, UART_IER, scratch);
-		if (scratch2 || scratch3 != 0x0F) {
-#ifdef SERIAL_DEBUG_AUTOCONF
-			printk("serial: ttyS%d: simple autoconfig failed "
-			       "(%02x, %02x)\n", state->line, 
-			       scratch2, scratch3);
-#endif
-			restore_flags(flags);
-			return;		/* We failed; there's nothing here */
-		}
-	}
-
-	save_mcr = serial_in(info, UART_MCR);
-	save_lcr = serial_in(info, UART_LCR);
-
-	/* 
-	 * Check to see if a UART is really there.  Certain broken
-	 * internal modems based on the Rockwell chipset fail this
-	 * test, because they apparently don't implement the loopback
-	 * test mode.  So this test is skipped on the COM 1 through
-	 * COM 4 ports.  This *should* be safe, since no board
-	 * manufacturer would be stupid enough to design a board
-	 * that conflicts with COM 1-4 --- we hope!
-	 */
-	if (!(state->flags & ASYNC_SKIP_TEST)) {
-		serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
-		status1 = serial_inp(info, UART_MSR) & 0xF0;
-		serial_outp(info, UART_MCR, save_mcr);
-		if (status1 != 0x90) {
-#ifdef SERIAL_DEBUG_AUTOCONF
-			printk("serial: ttyS%d: no UART loopback failed\n",
-			       state->line);
-#endif
-			restore_flags(flags);
-			return;
-		}
-	}
-	serial_outp(info, UART_LCR, 0xBF); /* set up for StarTech test */
-	serial_outp(info, UART_EFR, 0);	/* EFR is the same as FCR */
-	serial_outp(info, UART_LCR, 0);
-	serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-	scratch = serial_in(info, UART_IIR) >> 6;
-	switch (scratch) {
-		case 0:
-			state->type = PORT_16450;
-			break;
-		case 1:
-			state->type = PORT_UNKNOWN;
-			break;
-		case 2:
-			state->type = PORT_16550;
-			break;
-		case 3:
-			state->type = PORT_16550A;
-			break;
-	}
-	if (state->type == PORT_16550A) {
-		/* Check for Startech UART's */
-		serial_outp(info, UART_LCR, UART_LCR_DLAB);
-		if (serial_in(info, UART_EFR) == 0) {
-			state->type = PORT_16650;
-		} else {
-			serial_outp(info, UART_LCR, 0xBF);
-			if (serial_in(info, UART_EFR) == 0)
-				autoconfig_startech_uarts(info, state, flags);
-		}
-	}
-	if (state->type == PORT_16550A) {
-		/* Check for TI 16750 */
-		serial_outp(info, UART_LCR, save_lcr | UART_LCR_DLAB);
-		serial_outp(info, UART_FCR,
-			    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-		scratch = serial_in(info, UART_IIR) >> 5;
-		if (scratch == 7) {
-			/*
-			 * If this is a 16750, and not a cheap UART
-			 * clone, then it should only go into 64 byte
-			 * mode if the UART_FCR7_64BYTE bit was set
-			 * while UART_LCR_DLAB was latched.
-			 */
- 			serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-			serial_outp(info, UART_LCR, 0);
-			serial_outp(info, UART_FCR,
-				    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-			scratch = serial_in(info, UART_IIR) >> 5;
-			if (scratch == 6)
-				state->type = PORT_16750;
-		}
-		serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-	}
-#if defined(CONFIG_SERIAL_RSA) && defined(MODULE)
-	if (state->type == PORT_16550A) {
-		int i;
-
-		for (i = 0 ; i < PORT_RSA_MAX ; ++i) {
-			if (!probe_rsa[i] && !force_rsa[i])
-				break;
-			if (((probe_rsa[i] != state->port) ||
-			     check_region(state->port + UART_RSA_BASE, 16)) &&
-			    (force_rsa[i] != state->port))
-				continue;
-			if (!enable_rsa(info))
-				continue;
-			state->type = PORT_RSA;
-			state->baud_base = SERIAL_RSA_BAUD_BASE;
-			break;
-		}
-	}
-#endif
-	serial_outp(info, UART_LCR, save_lcr);
-	if (state->type == PORT_16450) {
-		scratch = serial_in(info, UART_SCR);
-		serial_outp(info, UART_SCR, 0xa5);
-		status1 = serial_in(info, UART_SCR);
-		serial_outp(info, UART_SCR, 0x5a);
-		status2 = serial_in(info, UART_SCR);
-		serial_outp(info, UART_SCR, scratch);
-
-		if ((status1 != 0xa5) || (status2 != 0x5a))
-			state->type = PORT_8250;
-	}
-	state->xmit_fifo_size =	uart_config[state->type].dfl_xmit_fifo_size;
-
-	if (state->type == PORT_UNKNOWN) {
-		restore_flags(flags);
-		return;
-	}
-
-	if (info->port) {
-#ifdef CONFIG_SERIAL_RSA
-		if (state->type == PORT_RSA)
-			request_region(info->port + UART_RSA_BASE, 16,
-				       "serial_rsa(auto)");
-		else
-#endif
-			request_region(info->port,8,"serial(auto)");
-	}
-
-	/*
-	 * Reset the UART.
-	 */
-#ifdef CONFIG_SERIAL_RSA
-	if (state->type == PORT_RSA)
-		serial_outp(info, UART_RSA_FRR, 0);
-#endif
-	serial_outp(info, UART_MCR, save_mcr);
-	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
-				     UART_FCR_CLEAR_RCVR |
-				     UART_FCR_CLEAR_XMIT));
-	serial_outp(info, UART_FCR, 0);
-	(void)serial_in(info, UART_RX);
-	serial_outp(info, UART_IER, 0);
-	
-	restore_flags(flags);
-}
-
-int register_serial(struct serial_struct *req);
-void unregister_serial(int line);
-
-#if (LINUX_VERSION_CODE > 0x20100)
-EXPORT_SYMBOL(register_serial);
-EXPORT_SYMBOL(unregister_serial);
-#else
-static struct symbol_table serial_syms = {
-#include <linux/symtab_begin.h>
-	X(register_serial),
-	X(unregister_serial),
-#include <linux/symtab_end.h>
-};
-#endif
-
-
-#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP) 
-
-static void __devinit printk_pnp_dev_id(unsigned short vendor,
-				     unsigned short device)
-{
-	printk("%c%c%c%x%x%x%x",
-	       'A' + ((vendor >> 2) & 0x3f) - 1,
-	       'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
-	       'A' + ((vendor >> 8) & 0x1f) - 1,
-	       (device >> 4) & 0x0f,
-	       device & 0x0f,
-	       (device >> 12) & 0x0f,
-	       (device >> 8) & 0x0f);
-}
-
-static _INLINE_ int get_pci_port(struct pci_dev *dev,
-				  struct pci_board *board,
-				  struct serial_struct *req,
-				  int idx)
-{
-	unsigned long port;
-	int base_idx;
-	int max_port;
-	int offset;
-
-	base_idx = SPCI_FL_GET_BASE(board->flags);
-	if (board->flags & SPCI_FL_BASE_TABLE)
-		base_idx += idx;
-
-	if (board->flags & SPCI_FL_REGION_SZ_CAP) {
-		max_port = pci_resource_len(dev, base_idx) / 8;
-		if (idx >= max_port)
-			return 1;
-	}
-			
-	offset = board->first_uart_offset;
-
-	/* Timedia/SUNIX uses a mixture of BARs and offsets */
-	/* Ugh, this is ugly as all hell --- TYT */
-	if(dev->vendor == PCI_VENDOR_ID_TIMEDIA )  /* 0x1409 */
-		switch(idx) {
-			case 0: base_idx=0;
-				break;
-			case 1: base_idx=0; offset=8;
-				break;
-			case 2: base_idx=1; 
-				break;
-			case 3: base_idx=1; offset=8;
-				break;
-			case 4: /* BAR 2*/
-			case 5: /* BAR 3 */
-			case 6: /* BAR 4*/
-			case 7: base_idx=idx-2; /* BAR 5*/
-		}
-
-	/* Some Titan cards are also a little weird */
-	if (dev->vendor == PCI_VENDOR_ID_TITAN &&
-	    (dev->device == PCI_DEVICE_ID_TITAN_400L ||
-	     dev->device == PCI_DEVICE_ID_TITAN_800L)) {
-		switch (idx) {
-		case 0: base_idx = 1;
-			break;
-		case 1: base_idx = 2;
-			break;
-		default:
-			base_idx = 4;
-			offset = 8 * (idx - 2);
-		}
-		
-	}
-  
-	port =  pci_resource_start(dev, base_idx) + offset;
-
-	if ((board->flags & SPCI_FL_BASE_TABLE) == 0)
-		port += idx * (board->uart_offset ? board->uart_offset : 8);
-
-	if (IS_PCI_REGION_IOPORT(dev, base_idx)) {
-		req->port = port;
-		if (HIGH_BITS_OFFSET)
-			req->port_high = port >> HIGH_BITS_OFFSET;
-		else
-			req->port_high = 0;
-		return 0;
-	}
-	req->io_type = SERIAL_IO_MEM;
-	req->iomem_base = ioremap(port, board->uart_offset);
-	req->iomem_reg_shift = board->reg_shift;
-	req->port = 0;
-	return 0;
-}
-
-static _INLINE_ int get_pci_irq(struct pci_dev *dev,
-				struct pci_board *board,
-				int idx)
-{
-	int base_idx;
-
-	if ((board->flags & SPCI_FL_IRQRESOURCE) == 0)
-		return dev->irq;
-
-	base_idx = SPCI_FL_GET_IRQBASE(board->flags);
-	if (board->flags & SPCI_FL_IRQ_TABLE)
-		base_idx += idx;
-	
-	return PCI_IRQ_RESOURCE(dev, base_idx);
-}
-
-/*
- * Common enabler code shared by both PCI and ISAPNP probes
- */
-static void __devinit start_pci_pnp_board(struct pci_dev *dev,
-				       struct pci_board *board)
-{
-	int k, line;
-	struct serial_struct serial_req;
-	int base_baud;
-
-       if (PREPARE_FUNC(dev) && (PREPARE_FUNC(dev))(dev) < 0) {
-	       printk("serial: PNP device '");
-	       printk_pnp_dev_id(dev->vendor, dev->device);
-	       printk("' prepare failed\n");
-	       return;
-       }
-
-       if (ACTIVATE_FUNC(dev) && (ACTIVATE_FUNC(dev))(dev) < 0) {
-	       printk("serial: PNP device '");
-	       printk_pnp_dev_id(dev->vendor, dev->device);
-	       printk("' activate failed\n");
-	       return;
-       }
-
-	/*
-	 * Run the initialization function, if any
-	 */
-	if (board->init_fn && ((board->init_fn)(dev, board, 1) != 0))
-		return;
-
-	/*
-	 * Register the serial board in the array if we need to
-	 * shutdown the board on a module unload or card removal
-	 */
-	if (DEACTIVATE_FUNC(dev) || board->init_fn) {
-		for (k=0; k < NR_PCI_BOARDS; k++)
-			if (serial_pci_board[k].dev == 0)
-				break;
-		if (k >= NR_PCI_BOARDS)
-			return;
-		serial_pci_board[k].board = *board;
-		serial_pci_board[k].dev = dev;
-	}
-
-	base_baud = board->base_baud;
-	if (!base_baud)
-		base_baud = BASE_BAUD;
-	memset(&serial_req, 0, sizeof(serial_req));
-
-	for (k=0; k < board->num_ports; k++) {
-		serial_req.irq = get_pci_irq(dev, board, k);
-		if (get_pci_port(dev, board, &serial_req, k))
-			break;
-		serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
-#ifdef SERIAL_DEBUG_PCI
-		printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
-		       serial_req.port, serial_req.irq, serial_req.io_type);
-#endif
-		line = register_serial(&serial_req);
-		if (line < 0)
-			break;
-		rs_table[line].baud_base = base_baud;
-		rs_table[line].dev = dev;
-	}
-}
-#endif	/* ENABLE_SERIAL_PCI || ENABLE_SERIAL_PNP */
-
-#ifdef ENABLE_SERIAL_PCI
-/*
- * Some PCI serial cards using the PLX 9050 PCI interface chip require
- * that the card interrupt be explicitly enabled or disabled.  This
- * seems to be mainly needed on card using the PLX which also use I/O
- * mapped memory.
- */
-static int __devinit
-pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
-{
-	u8 data, *p, irq_config;
-	int pci_config;
-
-	irq_config = 0x41;
-	pci_config = PCI_COMMAND_MEMORY;
-	if (dev->vendor == PCI_VENDOR_ID_PANACOM)
-		irq_config = 0x43;
-	if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
-	    (dev->device == PCI_DEVICE_ID_PLX_ROMULUS)) {
-		/*
-		 * As the megawolf cards have the int pins active
-		 * high, and have 2 UART chips, both ints must be
-		 * enabled on the 9050. Also, the UARTS are set in
-		 * 16450 mode by default, so we have to enable the
-		 * 16C950 'enhanced' mode so that we can use the deep
-		 * FIFOs
-		 */
-		irq_config = 0x5b;
-		pci_config = PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
-	}
-	
-	pci_read_config_byte(dev, PCI_COMMAND, &data);
-
-	if (enable)
-		pci_write_config_byte(dev, PCI_COMMAND,
-				      data | pci_config);
-	
-	/* enable/disable interrupts */
-	p = ioremap(pci_resource_start(dev, 0), 0x80);
-	writel(enable ? irq_config : 0x00, (unsigned long)p + 0x4c);
-	iounmap(p);
-
-	if (!enable)
-		pci_write_config_byte(dev, PCI_COMMAND,
-				      data & ~pci_config);
-	return 0;
-}
-
-
-/*
- * SIIG serial cards have an PCI interface chip which also controls
- * the UART clocking frequency. Each UART can be clocked independently
- * (except cards equiped with 4 UARTs) and initial clocking settings
- * are stored in the EEPROM chip. It can cause problems because this
- * version of serial driver doesn't support differently clocked UART's
- * on single PCI card. To prevent this, initialization functions set
- * high frequency clocking for all UART's on given card. It is safe (I
- * hope) because it doesn't touch EEPROM settings to prevent conflicts
- * with other OSes (like M$ DOS).
- *
- *  SIIG support added by Andrey Panin <pazke@mail.tp.ru>, 10/1999
- * 
- * There is two family of SIIG serial cards with different PCI
- * interface chip and different configuration methods:
- *     - 10x cards have control registers in IO and/or memory space;
- *     - 20x cards have control registers in standard PCI configuration space.
- */
-
-#define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
-#define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
-
-static int __devinit
-pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
-{
-       u16 data, *p;
-
-       if (!enable) return 0;
-
-       p = ioremap(pci_resource_start(dev, 0), 0x80);
-
-       switch (dev->device & 0xfff8) {
-               case PCI_DEVICE_ID_SIIG_1S_10x:         /* 1S */
-                       data = 0xffdf;
-                       break;
-               case PCI_DEVICE_ID_SIIG_2S_10x:         /* 2S, 2S1P */
-                       data = 0xf7ff;
-                       break;
-               default:                                /* 1S1P, 4S */
-                       data = 0xfffb;
-                       break;
-       }
-
-       writew(readw((unsigned long) p + 0x28) & data, (unsigned long) p + 0x28);
-       iounmap(p);
-       return 0;
-}
-
-#define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
-#define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
-
-static int __devinit
-pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
-{
-       u8 data;
-
-       if (!enable) return 0;
-
-       /* Change clock frequency for the first UART. */
-       pci_read_config_byte(dev, 0x6f, &data);
-       pci_write_config_byte(dev, 0x6f, data & 0xef);
-
-       /* If this card has 2 UART, we have to do the same with second UART. */
-       if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) ||
-           ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) {
-               pci_read_config_byte(dev, 0x73, &data);
-               pci_write_config_byte(dev, 0x73, data & 0xef);
-       }
-       return 0;
-}
-
-/* Added for EKF Intel i960 serial boards */
-static int __devinit
-pci_inteli960ni_fn(struct pci_dev *dev,
-		   struct pci_board *board,
-		   int enable)
-{
-	unsigned long oldval;
-	
-	if (!(pci_get_subdevice(dev) & 0x1000))
-		return(-1);
-
-	if (!enable) /* is there something to deinit? */
-		return(0);
-   
-#ifdef SERIAL_DEBUG_PCI
-	printk(KERN_DEBUG " Subsystem ID %lx (intel 960)\n",
-	       (unsigned long) board->subdevice);
-#endif
-	/* is firmware started? */
-	pci_read_config_dword(dev, 0x44, (void*) &oldval); 
-	if (oldval == 0x00001000L) { /* RESET value */ 
-		printk(KERN_DEBUG "Local i960 firmware missing");
-		return(-1); 
-	}
-	return(0);
-}
-
-/*
- * Timedia has an explosion of boards, and to avoid the PCI table from
- * growing *huge*, we use this function to collapse some 70 entries
- * in the PCI table into one, for sanity's and compactness's sake.
- */
-static unsigned short timedia_single_port[] = {
-	0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 };
-static unsigned short timedia_dual_port[] = {
-	0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
-	0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, 
-	0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, 
-	0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
-	0xD079, 0 };
-static unsigned short timedia_quad_port[] = {
-	0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, 
-	0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, 
-	0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
-	0xB157, 0 };
-static unsigned short timedia_eight_port[] = {
-	0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, 
-	0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 };
-static struct timedia_struct {
-	int num;
-	unsigned short *ids;
-} timedia_data[] = {
-	{ 1, timedia_single_port },
-	{ 2, timedia_dual_port },
-	{ 4, timedia_quad_port },
-	{ 8, timedia_eight_port },
-	{ 0, 0 }
-};
-
-static int __devinit
-pci_timedia_fn(struct pci_dev *dev, struct pci_board *board, int enable)
-{
-	int	i, j;
-	unsigned short *ids;
-
-	if (!enable)
-		return 0;
-
-	for (i=0; timedia_data[i].num; i++) {
-		ids = timedia_data[i].ids;
-		for (j=0; ids[j]; j++) {
-			if (pci_get_subdevice(dev) == ids[j]) {
-				board->num_ports = timedia_data[i].num;
-				return 0;
-			}
-		}
-	}
-	return 0;
-}
-
-static int __devinit
-pci_xircom_fn(struct pci_dev *dev, struct pci_board *board, int enable)
-{
-	__set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ/10);
-	return 0;
-}
-
-/*
- * This is the configuration table for all of the PCI serial boards
- * which we support.  It is directly indexed by the pci_board_num_t enum
- * value, which is encoded in the pci_device_id PCI probe table's
- * driver_data member.
- */
-enum pci_board_num_t {
-	pbn_b0_1_115200,
-	pbn_default = 0,
-
-	pbn_b0_2_115200,
-	pbn_b0_4_115200,
-
-	pbn_b0_1_921600,
-	pbn_b0_2_921600,
-	pbn_b0_4_921600,
-
-	pbn_b0_bt_1_115200,
-	pbn_b0_bt_2_115200,
-	pbn_b0_bt_1_460800,
-	pbn_b0_bt_2_460800,
-
-	pbn_b1_1_115200,
-	pbn_b1_2_115200,
-	pbn_b1_4_115200,
-	pbn_b1_8_115200,
-
-	pbn_b1_2_921600,
-	pbn_b1_4_921600,
-	pbn_b1_8_921600,
-
-	pbn_b1_2_1382400,
-	pbn_b1_4_1382400,
-	pbn_b1_8_1382400,
-
-	pbn_b2_8_115200,
-	pbn_b2_4_460800,
-	pbn_b2_8_460800,
-	pbn_b2_16_460800,
-	pbn_b2_4_921600,
-	pbn_b2_8_921600,
-
-	pbn_b2_bt_1_115200,
-	pbn_b2_bt_2_115200,
-	pbn_b2_bt_4_115200,
-	pbn_b2_bt_2_921600,
-
-	pbn_panacom,
-	pbn_panacom2,
-	pbn_panacom4,
-	pbn_plx_romulus,
-	pbn_oxsemi,
-	pbn_timedia,
-	pbn_intel_i960,
-	pbn_sgi_ioc3,
-#ifdef CONFIG_DDB5074
-	pbn_nec_nile4,
-#endif
-#if 0
-	pbn_dci_pccom8,
-#endif
-	pbn_xircom_combo,
-
-	pbn_siig10x_0,
-	pbn_siig10x_1,
-	pbn_siig10x_2,
-	pbn_siig10x_4,
-	pbn_siig20x_0,
-	pbn_siig20x_2,
-	pbn_siig20x_4,
-	
-	pbn_computone_4,
-	pbn_computone_6,
-	pbn_computone_8,
-};
-
-static struct pci_board pci_boards[] __devinitdata = {
-	/*
-	 * PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
-	 * Offset to get to next UART's registers,
-	 * Register shift to use for memory-mapped I/O,
-	 * Initialization function, first UART offset
-	 */
-
-	/* Generic serial board, pbn_b0_1_115200, pbn_default */
-	{ SPCI_FL_BASE0, 1, 115200 },		/* pbn_b0_1_115200,
-						   pbn_default */
-
-	{ SPCI_FL_BASE0, 2, 115200 },		/* pbn_b0_2_115200 */
-	{ SPCI_FL_BASE0, 4, 115200 },		/* pbn_b0_4_115200 */
-
-	{ SPCI_FL_BASE0, 1, 921600 },		/* pbn_b0_1_921600 */
-	{ SPCI_FL_BASE0, 2, 921600 },		/* pbn_b0_2_921600 */
-	{ SPCI_FL_BASE0, 4, 921600 },		/* pbn_b0_4_921600 */
-
-	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b0_bt_1_115200 */
-	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b0_bt_2_115200 */
-	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, /* pbn_b0_bt_1_460800 */
-	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, /* pbn_b0_bt_2_460800 */
-
-	{ SPCI_FL_BASE1, 1, 115200 },		/* pbn_b1_1_115200 */
-	{ SPCI_FL_BASE1, 2, 115200 },		/* pbn_b1_2_115200 */
-	{ SPCI_FL_BASE1, 4, 115200 },		/* pbn_b1_4_115200 */
-	{ SPCI_FL_BASE1, 8, 115200 },		/* pbn_b1_8_115200 */
-
-	{ SPCI_FL_BASE1, 2, 921600 },		/* pbn_b1_2_921600 */
-	{ SPCI_FL_BASE1, 4, 921600 },		/* pbn_b1_4_921600 */
-	{ SPCI_FL_BASE1, 8, 921600 },		/* pbn_b1_8_921600 */
-
-	{ SPCI_FL_BASE1, 2, 1382400 },		/* pbn_b1_2_1382400 */
-	{ SPCI_FL_BASE1, 4, 1382400 },		/* pbn_b1_4_1382400 */
-	{ SPCI_FL_BASE1, 8, 1382400 },		/* pbn_b1_8_1382400 */
-
-	{ SPCI_FL_BASE2, 8, 115200 },		/* pbn_b2_8_115200 */
-	{ SPCI_FL_BASE2, 4, 460800 },		/* pbn_b2_4_460800 */
-	{ SPCI_FL_BASE2, 8, 460800 },		/* pbn_b2_8_460800 */
-	{ SPCI_FL_BASE2, 16, 460800 },		/* pbn_b2_16_460800 */
-	{ SPCI_FL_BASE2, 4, 921600 },		/* pbn_b2_4_921600 */
-	{ SPCI_FL_BASE2, 8, 921600 },		/* pbn_b2_8_921600 */
-
-	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b2_bt_1_115200 */
-	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b2_bt_2_115200 */
-	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 115200 }, /* pbn_b2_bt_4_115200 */
-	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600 }, /* pbn_b2_bt_2_921600 */
-
-	{ SPCI_FL_BASE2, 2, 921600, /* IOMEM */		   /* pbn_panacom */
-		0x400, 7, pci_plx9050_fn },
-	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,   /* pbn_panacom2 */
-		0x400, 7, pci_plx9050_fn },
-	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600,   /* pbn_panacom4 */
-		0x400, 7, pci_plx9050_fn },
-	{ SPCI_FL_BASE2, 4, 921600,			   /* pbn_plx_romulus */
-		0x20, 2, pci_plx9050_fn, 0x03 },
-		/* This board uses the size of PCI Base region 0 to
-		 * signal now many ports are available */
-	{ SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 }, /* pbn_oxsemi */
-	{ SPCI_FL_BASE_TABLE, 1, 921600,		   /* pbn_timedia */
-		0, 0, pci_timedia_fn },
-	/* EKF addition for i960 Boards form EKF with serial port */
-	{ SPCI_FL_BASE0, 32, 921600, /* max 256 ports */   /* pbn_intel_i960 */
-		8<<2, 2, pci_inteli960ni_fn, 0x10000},
-	{ SPCI_FL_BASE0 | SPCI_FL_IRQRESOURCE,		   /* pbn_sgi_ioc3 */
-		1, 458333, 0, 0, 0, 0x20178 },
-#ifdef CONFIG_DDB5074
-	/*
-	 * NEC Vrc-5074 (Nile 4) builtin UART.
-	 * Conditionally compiled in since this is a motherboard device.
-	 */
-	{ SPCI_FL_BASE0, 1, 520833,			   /* pbn_nec_nile4 */
-		64, 3, NULL, 0x300 },
-#endif
-#if 0	/* PCI_DEVICE_ID_DCI_PCCOM8 ? */		   /* pbn_dci_pccom8 */
-	{ SPCI_FL_BASE3, 8, 115200, 8 },
-#endif
-	{ SPCI_FL_BASE0, 1, 115200,			  /* pbn_xircom_combo */
-		0, 0, pci_xircom_fn },
-
-	{ SPCI_FL_BASE2, 1, 460800,			   /* pbn_siig10x_0 */
-		0, 0, pci_siig10x_fn },
-	{ SPCI_FL_BASE2, 1, 921600,			   /* pbn_siig10x_1 */
-		0, 0, pci_siig10x_fn },
-	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,   /* pbn_siig10x_2 */
-		0, 0, pci_siig10x_fn },
-	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600,   /* pbn_siig10x_4 */
-		0, 0, pci_siig10x_fn },
-	{ SPCI_FL_BASE0, 1, 921600,			   /* pbn_siix20x_0 */
-		0, 0, pci_siig20x_fn },
-	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600,   /* pbn_siix20x_2 */
-		0, 0, pci_siig20x_fn },
-	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 921600,   /* pbn_siix20x_4 */
-		0, 0, pci_siig20x_fn },
-
-	{ SPCI_FL_BASE0, 4, 921600, /* IOMEM */		   /* pbn_computone_4 */
-		0x40, 2, NULL, 0x200 },
-	{ SPCI_FL_BASE0, 6, 921600, /* IOMEM */		   /* pbn_computone_6 */
-		0x40, 2, NULL, 0x200 },
-	{ SPCI_FL_BASE0, 8, 921600, /* IOMEM */		   /* pbn_computone_8 */
-		0x40, 2, NULL, 0x200 },
-};
-
-/*
- * Given a complete unknown PCI device, try to use some heuristics to
- * guess what the configuration might be, based on the pitiful PCI
- * serial specs.  Returns 0 on success, 1 on failure.
- */
-static int __devinit serial_pci_guess_board(struct pci_dev *dev,
-					   struct pci_board *board)
-{
-	int	num_iomem = 0, num_port = 0, first_port = -1;
-	int	i;
-	
-	/*
-	 * If it is not a communications device or the programming
-	 * interface is greater than 6, give up.
-	 *
-	 * (Should we try to make guesses for multiport serial devices
-	 * later?) 
-	 */
-	if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
-	    ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
-	    (dev->class & 0xff) > 6)
-		return 1;
-
-	for (i=0; i < 6; i++) {
-		if (IS_PCI_REGION_IOPORT(dev, i)) {
-			num_port++;
-			if (first_port == -1)
-				first_port = i;
-		}
-		if (IS_PCI_REGION_IOMEM(dev, i))
-			num_iomem++;
-	}
-
-	/*
-	 * If there is 1 or 0 iomem regions, and exactly one port, use
-	 * it.
-	 */
-	if (num_iomem <= 1 && num_port == 1) {
-		board->flags = first_port;
-		return 0;
-	}
-	return 1;
-}
-
-static int __devinit serial_init_one(struct pci_dev *dev,
-				     const struct pci_device_id *ent)
-{
-	struct pci_board *board, tmp;
-	int rc;
-
-	board = &pci_boards[ent->driver_data];
-
-	rc = pci_enable_device(dev);
-	if (rc) return rc;
-
-	if (ent->driver_data == pbn_default &&
-	    serial_pci_guess_board(dev, board))
-		return -ENODEV;
-	else if (serial_pci_guess_board(dev, &tmp) == 0) {
-		printk(KERN_INFO "Redundant entry in serial pci_table.  "
-		       "Please send the output of\n"
-		       "lspci -vv, this message (%04x,%04x,%04x,%04x)\n"
-		       "and the manufacturer and name of "
-		       "serial board or modem board\n"
-		       "to serial-pci-info@lists.sourceforge.net.\n",
-		       dev->vendor, dev->device,
-		       pci_get_subvendor(dev), pci_get_subdevice(dev));
-	}
-		       
-	start_pci_pnp_board(dev, board);
-
-	return 0;
-}
-
-static void __devexit serial_remove_one(struct pci_dev *dev)
-{
-	int	i;
-
-	/*
-	 * Iterate through all of the ports finding those that belong
-	 * to this PCI device.
-	 */
-	for(i = 0; i < NR_PORTS; i++) {
-		if (rs_table[i].dev != dev)
-			continue;
-		unregister_serial(i);
-		rs_table[i].dev = 0;
-	}
-	/*
-	 * Now execute any board-specific shutdown procedure
-	 */
-	for (i=0; i < NR_PCI_BOARDS; i++) {
-		struct pci_board_inst *brd = &serial_pci_board[i];
-
-		if (serial_pci_board[i].dev != dev)
-			continue;
-		if (brd->board.init_fn)
-			(brd->board.init_fn)(brd->dev, &brd->board, 0);
-		if (DEACTIVATE_FUNC(brd->dev))
-			(DEACTIVATE_FUNC(brd->dev))(brd->dev);
-		serial_pci_board[i].dev = 0;
-	}
-}
-
-
-static struct pci_device_id serial_pci_tbl[] __devinitdata = {
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
-		pbn_b1_8_1382400 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
-		pbn_b1_4_1382400 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
-		pbn_b1_2_1382400 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
-		pbn_b1_8_1382400 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
-		pbn_b1_4_1382400 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
-		pbn_b1_2_1382400 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0,
-		pbn_b1_8_921600 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0,
-		pbn_b1_8_921600 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0,
-		pbn_b1_4_921600 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0,
-		pbn_b1_4_921600 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0,
-		pbn_b1_2_921600 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6, 0, 0,
-		pbn_b1_8_921600 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0,
-		pbn_b1_8_921600 },
-	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-		PCI_SUBVENDOR_ID_CONNECT_TECH,
-		PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0,
-		pbn_b1_4_921600 },
-
-	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b2_bt_1_115200 },
-	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b2_bt_2_115200 },
-	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM422,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b2_bt_4_115200 },
-	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM232,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b2_bt_2_115200 },
-	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM4,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b2_bt_4_115200 },
-	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b2_8_115200 },
-
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b2_bt_2_115200 },
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b2_bt_2_921600 },
-	/* VScom SPCOM800, from sl@s.pl */
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800, 
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b2_8_921600 },
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b2_4_921600 },
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-		PCI_SUBVENDOR_ID_KEYSPAN,
-		PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
-		pbn_panacom },
-	{	PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_panacom4 },
-	{	PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_panacom2 },
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-		PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0, 
-		pbn_b2_4_460800 },
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-		PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0, 
-		pbn_b2_8_460800 },
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-		PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0, 
-		pbn_b2_16_460800 },
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-		PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0, 
-		pbn_b2_16_460800 },
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-		PCI_SUBVENDOR_ID_CHASE_PCIRAS,
-		PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0, 
-		pbn_b2_4_460800 },
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-		PCI_SUBVENDOR_ID_CHASE_PCIRAS,
-		PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0, 
-		pbn_b2_8_460800 },
-	/* Megawolf Romulus PCI Serial Card, from Mike Hudson */
-	/* (Exoray@isys.ca) */
-	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
-		0x10b5, 0x106a, 0, 0,
-		pbn_plx_romulus },
-	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b1_4_115200 },
-	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b1_2_115200 },
-	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b1_8_115200 },
-	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b1_8_115200 },
-	{	PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
-		PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, 0, 0, 
-		pbn_b0_4_921600 },
-	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b0_4_115200 },
-	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b0_2_115200 },
-
-	/* Digitan DS560-558, from jimd@esoft.com */
-	{	PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b1_1_115200 },
-
-	/* 3Com US Robotics 56k Voice Internal PCI model 5610 */
-	{	PCI_VENDOR_ID_USR, 0x1008,
-		PCI_ANY_ID, PCI_ANY_ID, },
-
-	/* Titan Electronic cards */
-	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b0_1_921600 },
-	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b0_2_921600 },
-	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b0_4_921600 },
-	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b0_4_921600 },
-	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L,
-		PCI_ANY_ID, PCI_ANY_ID,
-		SPCI_FL_BASE1, 1, 921600 },
-	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L,
-		PCI_ANY_ID, PCI_ANY_ID,
-		SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
-	/* The 400L and 800L have a custom hack in get_pci_port */
-	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L,
-		PCI_ANY_ID, PCI_ANY_ID,
-		SPCI_FL_BASE_TABLE, 4, 921600 },
-	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
-		PCI_ANY_ID, PCI_ANY_ID,
-		SPCI_FL_BASE_TABLE, 8, 921600 },
-
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_1 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_1 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_1 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_4 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_4 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_4 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_4 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_4 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_4 },
-
-	/* Computone devices submitted by Doug McNash dmcnash@computone.com */
-	{	PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-		PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
-		0, 0, pbn_computone_4 },
-	{	PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-		PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
-		0, 0, pbn_computone_8 },
-	{	PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-		PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
-		0, 0, pbn_computone_6 },
-
-	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_oxsemi },
-	{	PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
-		PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0, pbn_timedia },
-
-	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b0_bt_2_115200 },
-	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b0_bt_2_115200 },
-	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b0_bt_2_115200 },
-	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b0_bt_2_460800 },
-	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b0_bt_2_460800 },
-	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b0_bt_2_460800 },
-	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b0_bt_1_115200 },
-	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b0_bt_1_460800 },
-
-	/* RAStel 2 port modem, gerg@moreton.com.au */
-	{	PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_b2_bt_2_115200 },
-
-	/* EKF addition for i960 Boards form EKF with serial port */
-	{	PCI_VENDOR_ID_INTEL, 0x1960,
-		0xE4BF, PCI_ANY_ID, 0, 0,
-		pbn_intel_i960 },
-
-	/* Xircom Cardbus/Ethernet combos */
-	{	PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_X3201_MDM,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_xircom_combo },
-
-	/*
-	 * Untested PCI modems, sent in from various folks...
-	 */
-
-	/* Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de> */
-	{	PCI_VENDOR_ID_ROCKWELL, 0x1004,
-		0x1048, 0x1500, 0, 0,
-		pbn_b1_1_115200 },
-
-	{	PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
-		0xFF00, 0, 0, 0,
-		pbn_sgi_ioc3 },
-
-#ifdef CONFIG_DDB5074
-	/*
-	 * NEC Vrc-5074 (Nile 4) builtin UART.
-	 * Conditionally compiled in since this is a motherboard device.
-	 */
-	{	PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NILE4,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_nec_nile4 },
-#endif
-
-#if 0	/* PCI_DEVICE_ID_DCI_PCCOM8 ? */
-	{	PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_dci_pccom8 },
-#endif
-
-       { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-	 PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, },
-       { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-	 PCI_CLASS_COMMUNICATION_MODEM << 8, 0xffff00, },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, serial_pci_tbl);
-
-static struct pci_driver serial_pci_driver = {
-       name:           "serial",
-       probe:          serial_init_one,
-       remove:	       __devexit_p(serial_remove_one),
-       id_table:       serial_pci_tbl,
-};
-
-
-/*
- * Query PCI space for known serial boards
- * If found, add them to the PCI device space in rs_table[]
- *
- * Accept a maximum of eight boards
- *
- */
-static void __devinit probe_serial_pci(void) 
-{
-#ifdef SERIAL_DEBUG_PCI
-	printk(KERN_DEBUG "Entered probe_serial_pci()\n");
-#endif
-
-	/* Register call PCI serial devices.  Null out
-	 * the driver name upon failure, as a signal
-	 * not to attempt to unregister the driver later
-	 */
-	if (pci_module_init (&serial_pci_driver) != 0)
-		serial_pci_driver.name = "";
-
-#ifdef SERIAL_DEBUG_PCI
-	printk(KERN_DEBUG "Leaving probe_serial_pci() (probe finished)\n");
-#endif
-	return;
-}
-
-#endif /* ENABLE_SERIAL_PCI */
-
-#ifdef ENABLE_SERIAL_PNP
-
-struct pnp_board {
-	unsigned short vendor;
-	unsigned short device;
-};
-
-static struct pnp_board pnp_devices[] __devinitdata = {
-	/* Archtek America Corp. */
-	/* Archtek SmartLink Modem 3334BT Plug & Play */
-	{	ISAPNP_VENDOR('A', 'A', 'C'), ISAPNP_DEVICE(0x000F) },
-	/* Anchor Datacomm BV */
-	/* SXPro 144 External Data Fax Modem Plug & Play */
-	{	ISAPNP_VENDOR('A', 'D', 'C'), ISAPNP_DEVICE(0x0001) },
-	/* SXPro 288 External Data Fax Modem Plug & Play */
-	{	ISAPNP_VENDOR('A', 'D', 'C'), ISAPNP_DEVICE(0x0002) },
-	/* Rockwell 56K ACF II Fax+Data+Voice Modem */
-	{	ISAPNP_VENDOR('A', 'K', 'Y'), ISAPNP_DEVICE(0x1021) },
-	/* AZT3005 PnP SOUND DEVICE */
-	{	ISAPNP_VENDOR('A', 'Z', 'T'), ISAPNP_DEVICE(0x4001) },
-	/* Best Data Products Inc. Smart One 336F PnP Modem */
-	{	ISAPNP_VENDOR('B', 'D', 'P'), ISAPNP_DEVICE(0x3336) },
-	/*  Boca Research */
-	/* Boca Complete Ofc Communicator 14.4 Data-FAX */
-	{	ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x0A49) },
-	/* Boca Research 33,600 ACF Modem */
-	{	ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x1400) },
-	/* Boca 33.6 Kbps Internal FD34FSVD */
-	{	ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x3400) },
-	/* Boca 33.6 Kbps Internal FD34FSVD */
-	{	ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x0A49) },
-	/* Best Data Products Inc. Smart One 336F PnP Modem */
-	{	ISAPNP_VENDOR('B', 'D', 'P'), ISAPNP_DEVICE(0x3336) },
-	/* Computer Peripherals Inc */
-	/* EuroViVa CommCenter-33.6 SP PnP */
-	{	ISAPNP_VENDOR('C', 'P', 'I'), ISAPNP_DEVICE(0x4050) },
-	/* Creative Labs */
-	/* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */
-	{	ISAPNP_VENDOR('C', 'T', 'L'), ISAPNP_DEVICE(0x3001) },
-	/* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
-	{	ISAPNP_VENDOR('C', 'T', 'L'), ISAPNP_DEVICE(0x3011) },
-	/* Creative */
-	/* Creative Modem Blaster Flash56 DI5601-1 */
-	{	ISAPNP_VENDOR('D', 'M', 'B'), ISAPNP_DEVICE(0x1032) },
-	/* Creative Modem Blaster V.90 DI5660 */
-	{	ISAPNP_VENDOR('D', 'M', 'B'), ISAPNP_DEVICE(0x2001) },
-	/* FUJITSU */
-	/* Fujitsu 33600 PnP-I2 R Plug & Play */
-	{	ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0202) },
-	/* Fujitsu FMV-FX431 Plug & Play */
-	{	ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0205) },
-	/* Fujitsu 33600 PnP-I4 R Plug & Play */
-	{	ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0206) },
-	/* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */
-	{	ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0209) },
-	/* Archtek America Corp. */
-	/* Archtek SmartLink Modem 3334BT Plug & Play */
-	{	ISAPNP_VENDOR('G', 'V', 'C'), ISAPNP_DEVICE(0x000F) },
-	/* Hayes */
-	/* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
-	{	ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x0001) },
-	/* Hayes Optima 336 V.34 + FAX + Voice PnP */
-	{	ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x000C) },
-	/* Hayes Optima 336B V.34 + FAX + Voice PnP */
-	{	ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x000D) },
-	/* Hayes Accura 56K Ext Fax Modem PnP */
-	{	ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x5670) },
-	/* Hayes Accura 56K Ext Fax Modem PnP */
-	{	ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x5674) },
-	/* Hayes Accura 56K Fax Modem PnP */
-	{	ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x5675) },
-	/* Hayes 288, V.34 + FAX */
-	{	ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0xF000) },
-	/* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */
-	{	ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0xF001) },
-	/* IBM */
-	/* IBM Thinkpad 701 Internal Modem Voice */
-	{	ISAPNP_VENDOR('I', 'B', 'M'), ISAPNP_DEVICE(0x0033) },
-	/* Intertex */
-	/* Intertex 28k8 33k6 Voice EXT PnP */
-	{	ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xC801) },
-	/* Intertex 33k6 56k Voice EXT PnP */
-	{	ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xC901) },
-	/* Intertex 28k8 33k6 Voice SP EXT PnP */
-	{	ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xD801) },
-	/* Intertex 33k6 56k Voice SP EXT PnP */
-	{	ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xD901) },
-	/* Intertex 28k8 33k6 Voice SP INT PnP */
-	{	ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xF401) },
-	/* Intertex 28k8 33k6 Voice SP EXT PnP */
-	{	ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xF801) },
-	/* Intertex 33k6 56k Voice SP EXT PnP */
-	{	ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xF901) },
-	/* Kortex International */
-	/* KORTEX 28800 Externe PnP */
-	{	ISAPNP_VENDOR('K', 'O', 'R'), ISAPNP_DEVICE(0x4522) },
-	/* KXPro 33.6 Vocal ASVD PnP */
-	{	ISAPNP_VENDOR('K', 'O', 'R'), ISAPNP_DEVICE(0xF661) },
-	/* Lasat */
-	/* LASAT Internet 33600 PnP */
-	{	ISAPNP_VENDOR('L', 'A', 'S'), ISAPNP_DEVICE(0x4040) },
-	/* Lasat Safire 560 PnP */
-	{	ISAPNP_VENDOR('L', 'A', 'S'), ISAPNP_DEVICE(0x4540) },
-	/* Lasat Safire 336  PnP */
-	{	ISAPNP_VENDOR('L', 'A', 'S'), ISAPNP_DEVICE(0x5440) },
-	/* Microcom, Inc. */
-	/* Microcom TravelPorte FAST V.34 Plug & Play */
-	{	ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x281) },
-	/* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */
-	{	ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0336) },
-	/* Microcom DeskPorte FAST EP 28.8 Plug & Play */
-	{	ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0339) },
-	/* Microcom DeskPorte 28.8P Plug & Play */
-	{	ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0342) },
-	/* Microcom DeskPorte FAST ES 28.8 Plug & Play */
-	{	ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0500) },
-	/* Microcom DeskPorte FAST ES 28.8 Plug & Play */
-	{	ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0501) },
-	/* Microcom DeskPorte 28.8S Internal Plug & Play */
-	{	ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0502) },
-	/* Motorola */
-	/* Motorola BitSURFR Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1105) },
-	/* Motorola TA210 Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1111) },
-	/* Motorola HMTA 200 (ISDN) Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1114) },
-	/* Motorola BitSURFR Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1115) },
-	/* Motorola Lifestyle 28.8 Internal */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1190) },
-	/* Motorola V.3400 Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1501) },
-	/* Motorola Lifestyle 28.8 V.34 Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1502) },
-	/* Motorola Power 28.8 V.34 Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1505) },
-	/* Motorola ModemSURFR External 28.8 Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1509) },
-	/* Motorola Premier 33.6 Desktop Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x150A) },
-	/* Motorola VoiceSURFR 56K External PnP */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x150F) },
-	/* Motorola ModemSURFR 56K External PnP */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1510) },
-	/* Motorola ModemSURFR 56K Internal PnP */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1550) },
-	/* Motorola ModemSURFR Internal 28.8 Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1560) },
-	/* Motorola Premier 33.6 Internal Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1580) },
-	/* Motorola OnlineSURFR 28.8 Internal Plug & Play */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x15B0) },
-	/* Motorola VoiceSURFR 56K Internal PnP */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x15F0) },
-	/* Com 1 */
-	/*  Deskline K56 Phone System PnP */
-	{	ISAPNP_VENDOR('M', 'V', 'X'), ISAPNP_DEVICE(0x00A1) },
-	/* PC Rider K56 Phone System PnP */
-	{	ISAPNP_VENDOR('M', 'V', 'X'), ISAPNP_DEVICE(0x00F2) },
-	/* Pace 56 Voice Internal Plug & Play Modem */
-	{	ISAPNP_VENDOR('P', 'M', 'C'), ISAPNP_DEVICE(0x2430) },
-	/* Generic */
-	/* Generic standard PC COM port	 */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0500) },
-	/* Generic 16550A-compatible COM port */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0501) },
-	/* Compaq 14400 Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC000) },
-	/* Compaq 2400/9600 Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC001) },
-	/* Dial-Up Networking Serial Cable between 2 PCs */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC031) },
-	/* Dial-Up Networking Parallel Cable between 2 PCs */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC032) },
-	/* Standard 9600 bps Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC100) },
-	/* Standard 14400 bps Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC101) },
-	/*  Standard 28800 bps Modem*/
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC102) },
-	/*  Standard Modem*/
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC103) },
-	/*  Standard 9600 bps Modem*/
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC104) },
-	/*  Standard 14400 bps Modem*/
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC105) },
-	/*  Standard 28800 bps Modem*/
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC106) },
-	/*  Standard Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC107) },
-	/* Standard 9600 bps Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC108) },
-	/* Standard 14400 bps Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC109) },
-	/* Standard 28800 bps Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10A) },
-	/* Standard Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10B) },
-	/* Standard 9600 bps Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10C) },
-	/* Standard 14400 bps Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10D) },
-	/* Standard 28800 bps Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10E) },
-	/* Standard Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10F) },
-	/* Standard PCMCIA Card Modem */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x2000) },
-	/* Rockwell */
-	/* Modular Technology */
-	/* Rockwell 33.6 DPF Internal PnP */
-	/* Modular Technology 33.6 Internal PnP */
-	{	ISAPNP_VENDOR('R', 'O', 'K'), ISAPNP_DEVICE(0x0030) },
-	/* Kortex International */
-	/* KORTEX 14400 Externe PnP */
-	{	ISAPNP_VENDOR('R', 'O', 'K'), ISAPNP_DEVICE(0x0100) },
-	/* Viking Components, Inc */
-	/* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
-	{	ISAPNP_VENDOR('R', 'O', 'K'), ISAPNP_DEVICE(0x4920) },
-	/* Rockwell */
-	/* British Telecom */
-	/* Modular Technology */
-	/* Rockwell 33.6 DPF External PnP */
-	/* BT Prologue 33.6 External PnP */
-	/* Modular Technology 33.6 External PnP */
-	{	ISAPNP_VENDOR('R', 'S', 'S'), ISAPNP_DEVICE(0x00A0) },
-	/* Viking 56K FAX INT */
-	{	ISAPNP_VENDOR('R', 'S', 'S'), ISAPNP_DEVICE(0x0262) },
-	/* SupraExpress 28.8 Data/Fax PnP modem */
-	{	ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1310) },
-	/* SupraExpress 33.6 Data/Fax PnP modem */
-	{	ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1421) },
-	/* SupraExpress 33.6 Data/Fax PnP modem */
-	{	ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1590) },
-	/* SupraExpress 33.6 Data/Fax PnP modem */
-	{	ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1760) },
-	/* Phoebe Micro */
-	/* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
-	{	ISAPNP_VENDOR('T', 'E', 'X'), ISAPNP_DEVICE(0x0011) },
-	/* Archtek America Corp. */
-	/* Archtek SmartLink Modem 3334BT Plug & Play */
-	{	ISAPNP_VENDOR('U', 'A', 'C'), ISAPNP_DEVICE(0x000F) },
-	/* 3Com Corp. */
-	/* Gateway Telepath IIvi 33.6 */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0000) },
-	/*  Sportster Vi 14.4 PnP FAX Voicemail */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0004) },
-	/* U.S. Robotics 33.6K Voice INT PnP */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0006) },
-	/* U.S. Robotics 33.6K Voice EXT PnP */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0007) },
-	/* U.S. Robotics 33.6K Voice INT PnP */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x2002) },
-	/* U.S. Robotics 56K Voice INT PnP */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x2070) },
-	/* U.S. Robotics 56K Voice EXT PnP */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x2080) },
-	/* U.S. Robotics 56K FAX INT */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3031) },
-	/* U.S. Robotics 56K Voice INT PnP */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3070) },
-	/* U.S. Robotics 56K Voice EXT PnP */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3080) },
-	/* U.S. Robotics 56K Voice INT PnP */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3090) },
-	/* U.S. Robotics 56K Message  */
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9100) },
-	/*  U.S. Robotics 56K FAX EXT PnP*/
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9160) },
-	/*  U.S. Robotics 56K FAX INT PnP*/
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9170) },
-	/*  U.S. Robotics 56K Voice EXT PnP*/
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9180) },
-	/*  U.S. Robotics 56K Voice INT PnP*/
-	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9190) },
-	{	0, }
-};
-
-static void inline avoid_irq_share(struct pci_dev *dev)
-{
-	int i;
-	unsigned long map = 0x1FF8;
-	struct serial_state *state = rs_table;
-	struct isapnp_irq *irq;
-	struct isapnp_resources *res = dev->sysdata;
-
-	for (i = 0; i < NR_PORTS; i++) {
-		if (state->type != PORT_UNKNOWN)
-			clear_bit(state->irq, &map);
-		state++;
-	}
-
-	for ( ; res; res = res->alt)
-		for(irq = res->irq; irq; irq = irq->next)
-			irq->map = map;
-}
-
-static char *modem_names[] __devinitdata = {
-       "MODEM", "Modem", "modem", "FAX", "Fax", "fax",
-       "56K", "56k", "K56", "33.6", "28.8", "14.4",
-       "33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
-       "33600", "28800", "14400", "V.90", "V.34", "V.32", 0
-};
-
-static int __devinit check_name(char *name)
-{
-       char **tmp = modem_names;
-
-       while (*tmp) {
-               if (strstr(name, *tmp))
-                       return 1;
-               tmp++;
-       }
-       return 0;
-}
-
-static int inline check_compatible_id(struct pci_dev *dev)
-{
-       int i;
-       for (i = 0; i < DEVICE_COUNT_COMPATIBLE; i++)
-	       if ((dev->vendor_compatible[i] ==
-		    ISAPNP_VENDOR('P', 'N', 'P')) &&
-		   (swab16(dev->device_compatible[i]) >= 0xc000) &&
-		   (swab16(dev->device_compatible[i]) <= 0xdfff))
-		       return 0;
-       return 1;
-}
-
-/*
- * Given a complete unknown ISA PnP device, try to use some heuristics to
- * detect modems. Currently use such heuristic set:
- *     - dev->name or dev->bus->name must contain "modem" substring;
- *     - device must have only one IO region (8 byte long) with base adress
- *       0x2e8, 0x3e8, 0x2f8 or 0x3f8.
- *
- * Such detection looks very ugly, but can detect at least some of numerous
- * ISA PnP modems, alternatively we must hardcode all modems in pnp_devices[]
- * table.
- */
-static int _INLINE_ serial_pnp_guess_board(struct pci_dev *dev,
-					  struct pci_board *board)
-{
-       struct isapnp_resources *res = (struct isapnp_resources *)dev->sysdata;
-       struct isapnp_resources *resa;
-
-       if (!(check_name(dev->name) || check_name(dev->bus->name)) &&
-	   !(check_compatible_id(dev)))
-	       return 1;
-
-       if (!res || res->next)
-	       return 1;
-
-       for (resa = res->alt; resa; resa = resa->alt) {
-	       struct isapnp_port *port;
-	       for (port = res->port; port; port = port->next)
-		       if ((port->size == 8) &&
-			   ((port->min == 0x2f8) ||
-			    (port->min == 0x3f8) ||
-			    (port->min == 0x2e8) ||
-			    (port->min == 0x3e8)))
-			       return 0;
-       }
-
-       return 1;
-}
-
-static void __devinit probe_serial_pnp(void)
-{
-       struct pci_dev *dev = NULL;
-       struct pnp_board *pnp_board;
-       struct pci_board board;
-
-#ifdef SERIAL_DEBUG_PNP
-       printk("Entered probe_serial_pnp()\n");
-#endif
-       if (!isapnp_present()) {
-#ifdef SERIAL_DEBUG_PNP
-               printk("Leaving probe_serial_pnp() (no isapnp)\n");
-#endif
-               return;
-       }
-
-       isapnp_for_each_dev(dev) {
-	       if (dev->active)
-		       continue;
-
-	       memset(&board, 0, sizeof(board));
-	       board.flags = SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT;
-	       board.num_ports = 1;
-	       board.base_baud = 115200;
-	       
-	       for (pnp_board = pnp_devices; pnp_board->vendor; pnp_board++)
-		       if ((dev->vendor == pnp_board->vendor) &&
-			   (dev->device == pnp_board->device))
-			       break;
-
-	       if (pnp_board->vendor) {
-		       /* Special case that's more efficient to hardcode */
-		       if ((pnp_board->vendor == ISAPNP_VENDOR('A', 'K', 'Y') &&
-			    pnp_board->device == ISAPNP_DEVICE(0x1021)))
-			       board.flags |= SPCI_FL_NO_SHIRQ;
-	       } else {
-		       if (serial_pnp_guess_board(dev, &board))
-			       continue;
-	       }
-	       
-	       if (board.flags & SPCI_FL_NO_SHIRQ)
-		       avoid_irq_share(dev);
-	       start_pci_pnp_board(dev, &board);
-       }
-
-#ifdef SERIAL_DEBUG_PNP
-       printk("Leaving probe_serial_pnp() (probe finished)\n");
-#endif
-       return;
-}
-
-#endif /* ENABLE_SERIAL_PNP */
-
-/*
- * The serial driver boot-time initialization code!
- */
-static int __init rs_init(void)
-{
-	int i;
-	struct serial_state * state;
-
-	init_bh(SERIAL_BH, do_serial_bh);
-	init_timer(&serial_timer);
-	serial_timer.function = rs_timer;
-	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
-
-	for (i = 0; i < NR_IRQS; i++) {
-		IRQ_ports[i] = 0;
-		IRQ_timeout[i] = 0;
-#ifdef CONFIG_SERIAL_MULTIPORT
-		memset(&rs_multiport[i], 0,
-		       sizeof(struct rs_multiport_struct));
-#endif
-	}
-#ifdef CONFIG_SERIAL_CONSOLE
-	/*
-	 *	The interrupt of the serial console port
-	 *	can't be shared.
-	 */
-	if (sercons.flags & CON_CONSDEV) {
-		for(i = 0; i < NR_PORTS; i++)
-			if (i != sercons.index &&
-			    rs_table[i].irq == rs_table[sercons.index].irq)
-				rs_table[i].irq = 0;
-	}
-#endif
-	show_serial_version();
-
-	/* Initialize the tty_driver structure */
-	
-	memset(&serial_driver, 0, sizeof(struct tty_driver));
-	serial_driver.magic = TTY_DRIVER_MAGIC;
-#if (LINUX_VERSION_CODE > 0x20100)
-	serial_driver.driver_name = "serial";
-#endif
-#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
-	serial_driver.name = "tts/%d";
-#else
-	serial_driver.name = "ttyS";
-#endif
-	serial_driver.major = TTY_MAJOR;
-	serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET;
-	serial_driver.num = NR_PORTS;
-	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
-	serial_driver.subtype = SERIAL_TYPE_NORMAL;
-	serial_driver.init_termios = tty_std_termios;
-	serial_driver.init_termios.c_cflag =
-		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
-	serial_driver.refcount = &serial_refcount;
-	serial_driver.table = serial_table;
-	serial_driver.termios = serial_termios;
-	serial_driver.termios_locked = serial_termios_locked;
-
-	serial_driver.open = rs_open;
-	serial_driver.close = rs_close;
-	serial_driver.write = rs_write;
-	serial_driver.put_char = rs_put_char;
-	serial_driver.flush_chars = rs_flush_chars;
-	serial_driver.write_room = rs_write_room;
-	serial_driver.chars_in_buffer = rs_chars_in_buffer;
-	serial_driver.flush_buffer = rs_flush_buffer;
-	serial_driver.ioctl = rs_ioctl;
-	serial_driver.throttle = rs_throttle;
-	serial_driver.unthrottle = rs_unthrottle;
-	serial_driver.set_termios = rs_set_termios;
-	serial_driver.stop = rs_stop;
-	serial_driver.start = rs_start;
-	serial_driver.hangup = rs_hangup;
-#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
-	serial_driver.break_ctl = rs_break;
-#endif
-#if (LINUX_VERSION_CODE >= 131343)
-	serial_driver.send_xchar = rs_send_xchar;
-	serial_driver.wait_until_sent = rs_wait_until_sent;
-	serial_driver.read_proc = rs_read_proc;
-#endif
-	
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
-	callout_driver.name = "cua/%d";
-#else
-	callout_driver.name = "cua";
-#endif
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-#if (LINUX_VERSION_CODE >= 131343)
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-#endif
-
-	if (tty_register_driver(&serial_driver))
-		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
-	
-	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
-		state->magic = SSTATE_MAGIC;
-		state->line = i;
-		state->type = PORT_UNKNOWN;
-		state->custom_divisor = 0;
-		state->close_delay = 5*HZ/10;
-		state->closing_wait = 30*HZ;
-		state->callout_termios = callout_driver.init_termios;
-		state->normal_termios = serial_driver.init_termios;
-		state->icount.cts = state->icount.dsr = 
-			state->icount.rng = state->icount.dcd = 0;
-		state->icount.rx = state->icount.tx = 0;
-		state->icount.frame = state->icount.parity = 0;
-		state->icount.overrun = state->icount.brk = 0;
-		state->irq = irq_cannonicalize(state->irq);
-		if (state->hub6)
-			state->io_type = SERIAL_IO_HUB6;
-		if (state->port && check_region(state->port,8))
-			continue;
-#ifdef CONFIG_MCA			
-		if ((state->flags & ASYNC_BOOT_ONLYMCA) && !MCA_bus)
-			continue;
-#endif			
-		if (state->flags & ASYNC_BOOT_AUTOCONF)
-			autoconfig(state);
-	}
-	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
-		if (state->type == PORT_UNKNOWN)
-			continue;
-		if (   (state->flags & ASYNC_BOOT_AUTOCONF)
-		    && (state->flags & ASYNC_AUTO_IRQ)
-		    && (state->port != 0 || state->iomem_base != 0))
-			state->irq = detect_uart_irq(state);
-		if (state->io_type == SERIAL_IO_MEM) {
-			printk(KERN_INFO"ttyS%02d%s at 0x%px (irq = %d) is a %s\n",
-	 		       state->line + SERIAL_DEV_OFFSET,
-			       (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
-			       state->iomem_base, state->irq,
-			       uart_config[state->type].name);
-		}
-		else {
-			printk(KERN_INFO "ttyS%02d%s at 0x%04lx (irq = %d) is a %s\n",
-	 		       state->line + SERIAL_DEV_OFFSET,
-			       (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
-			       state->port, state->irq,
-			       uart_config[state->type].name);
-		}
-		tty_register_devfs(&serial_driver, 0,
-				   serial_driver.minor_start + state->line);
-		tty_register_devfs(&callout_driver, 0,
-				   callout_driver.minor_start + state->line);
-	}
-#ifdef ENABLE_SERIAL_PCI
-	probe_serial_pci();
-#endif
-#ifdef ENABLE_SERIAL_PNP
-       probe_serial_pnp();
-#endif
-	return 0;
-}
-
-/*
- * This is for use by architectures that know their serial console 
- * attributes only at run time. Not to be invoked after rs_init().
- */
-int __init early_serial_setup(struct serial_struct *req)
-{
-	int i = req->line;
-
-	if (i >= NR_IRQS)
-		return(-ENOENT);
-	rs_table[i].magic = 0;
-	rs_table[i].baud_base = req->baud_base;
-	rs_table[i].port = req->port;
-	if (HIGH_BITS_OFFSET)
-		rs_table[i].port += (unsigned long) req->port_high << 
-							HIGH_BITS_OFFSET;
-	rs_table[i].irq = req->irq;
-	rs_table[i].flags = req->flags;
-	rs_table[i].close_delay = req->close_delay;
-	rs_table[i].io_type = req->io_type;
-	rs_table[i].hub6 = req->hub6;
-	rs_table[i].iomem_base = req->iomem_base;
-	rs_table[i].iomem_reg_shift = req->iomem_reg_shift;
-	rs_table[i].type = req->type;
-	rs_table[i].xmit_fifo_size = req->xmit_fifo_size;
-	rs_table[i].custom_divisor = req->custom_divisor;
-	rs_table[i].closing_wait = req->closing_wait;
-	return(0);
-}
-
-/*
- * register_serial and unregister_serial allows for 16x50 serial ports to be
- * configured at run-time, to support PCMCIA modems.
- */
- 
-/**
- *	register_serial - configure a 16x50 serial port at runtime
- *	@req: request structure
- *
- *	Configure the serial port specified by the request. If the
- *	port exists and is in use an error is returned. If the port
- *	is not currently in the table it is added.
- *
- *	The port is then probed and if neccessary the IRQ is autodetected
- *	If this fails an error is returned.
- *
- *	On success the port is ready to use and the line number is returned.
- */
- 
-int register_serial(struct serial_struct *req)
-{
-	int i;
-	unsigned long flags;
-	struct serial_state *state;
-	struct async_struct *info;
-	unsigned long port;
-
-	port = req->port;
-	if (HIGH_BITS_OFFSET)
-		port += (unsigned long) req->port_high << HIGH_BITS_OFFSET;
-
-	save_flags(flags); cli();
-	for (i = 0; i < NR_PORTS; i++) {
-		if ((rs_table[i].port == port) &&
-		    (rs_table[i].iomem_base == req->iomem_base))
-			break;
-	}
-#ifdef __i386__
-	if (i == NR_PORTS) {
-		for (i = 4; i < NR_PORTS; i++)
-			if ((rs_table[i].type == PORT_UNKNOWN) &&
-			    (rs_table[i].count == 0))
-				break;
-	}
-#endif
-	if (i == NR_PORTS) {
-		for (i = 0; i < NR_PORTS; i++)
-			if ((rs_table[i].type == PORT_UNKNOWN) &&
-			    (rs_table[i].count == 0))
-				break;
-	}
-	if (i == NR_PORTS) {
-		restore_flags(flags);
-		return -1;
-	}
-	state = &rs_table[i];
-	if (rs_table[i].count) {
-		restore_flags(flags);
-		printk("Couldn't configure serial #%d (port=%ld,irq=%d): "
-		       "device already open\n", i, port, req->irq);
-		return -1;
-	}
-	state->irq = req->irq;
-	state->port = port;
-	state->flags = req->flags;
-	state->io_type = req->io_type;
-	state->iomem_base = req->iomem_base;
-	state->iomem_reg_shift = req->iomem_reg_shift;
-	if (req->baud_base)
-		state->baud_base = req->baud_base;
-	if ((info = state->info) != NULL) {
-		info->port = port;
-		info->flags = req->flags;
-		info->io_type = req->io_type;
-		info->iomem_base = req->iomem_base;
-		info->iomem_reg_shift = req->iomem_reg_shift;
-	}
-	autoconfig(state);
-	if (state->type == PORT_UNKNOWN) {
-		restore_flags(flags);
-		printk("register_serial(): autoconfig failed\n");
-		return -1;
-	}
-	restore_flags(flags);
-
-	if ((state->flags & ASYNC_AUTO_IRQ) && CONFIGURED_SERIAL_PORT(state))
-		state->irq = detect_uart_irq(state);
-
-       printk(KERN_INFO "ttyS%02d at %s 0x%04lx (irq = %d) is a %s\n",
-	      state->line + SERIAL_DEV_OFFSET,
-	      state->iomem_base ? "iomem" : "port",
-	      state->iomem_base ? (unsigned long)state->iomem_base :
-	      state->port, state->irq, uart_config[state->type].name);
-	tty_register_devfs(&serial_driver, 0,
-			   serial_driver.minor_start + state->line); 
-	tty_register_devfs(&callout_driver, 0,
-			   callout_driver.minor_start + state->line);
-	return state->line + SERIAL_DEV_OFFSET;
-}
-
-/**
- *	unregister_serial - deconfigure a 16x50 serial port
- *	@line: line to deconfigure
- *
- *	The port specified is deconfigured and its resources are freed. Any
- *	user of the port is disconnected as if carrier was dropped. Line is
- *	the port number returned by register_serial().
- */
-
-void unregister_serial(int line)
-{
-	unsigned long flags;
-	struct serial_state *state = &rs_table[line];
-
-	save_flags(flags); cli();
-	if (state->info && state->info->tty)
-		tty_hangup(state->info->tty);
-	state->type = PORT_UNKNOWN;
-	printk(KERN_INFO "ttyS%02d unloaded\n", state->line);
-	/* These will be hidden, because they are devices that will no longer
-	 * be available to the system. (ie, PCMCIA modems, once ejected)
-	 */
-	tty_unregister_devfs(&serial_driver,
-			     serial_driver.minor_start + state->line);
-	tty_unregister_devfs(&callout_driver,
-			     callout_driver.minor_start + state->line);
-	restore_flags(flags);
-}
-
-static void __exit rs_fini(void) 
-{
-	unsigned long flags;
-	int e1, e2;
-	int i;
-	struct async_struct *info;
-
-	/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
-	del_timer_sync(&serial_timer);
-	save_flags(flags); cli();
-        remove_bh(SERIAL_BH);
-	if ((e1 = tty_unregister_driver(&serial_driver)))
-		printk("serial: failed to unregister serial driver (%d)\n",
-		       e1);
-	if ((e2 = tty_unregister_driver(&callout_driver)))
-		printk("serial: failed to unregister callout driver (%d)\n", 
-		       e2);
-	restore_flags(flags);
-
-	for (i = 0; i < NR_PORTS; i++) {
-		if ((info = rs_table[i].info)) {
-			rs_table[i].info = NULL;
-			kfree(info);
-		}
-		if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) {
-#ifdef CONFIG_SERIAL_RSA
-			if (rs_table[i].type == PORT_RSA)
-				release_region(rs_table[i].port +
-					       UART_RSA_BASE, 16);
-			else
-#endif
-				release_region(rs_table[i].port, 8);
-		}
-#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
-		if (rs_table[i].iomem_base)
-			iounmap(rs_table[i].iomem_base);
-#endif
-	}
-#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
-	for (i=0; i < NR_PCI_BOARDS; i++) {
-		struct pci_board_inst *brd = &serial_pci_board[i];
-
-		if (serial_pci_board[i].dev == 0)
-			continue;
-		if (brd->board.init_fn)
-			(brd->board.init_fn)(brd->dev, &brd->board, 0);
-		if (DEACTIVATE_FUNC(brd->dev))
-			(DEACTIVATE_FUNC(brd->dev))(brd->dev);
-	}
-#endif	
-	if (tmp_buf) {
-		unsigned long pg = (unsigned long) tmp_buf;
-		tmp_buf = NULL;
-		free_page(pg);
-	}
-	
-#ifdef ENABLE_SERIAL_PCI
-	if (serial_pci_driver.name[0])
-		pci_unregister_driver (&serial_pci_driver);
-#endif
-}
-
-module_init(rs_init);
-module_exit(rs_fini);
-MODULE_DESCRIPTION("Standard/generic (dumb) serial driver");
-MODULE_AUTHOR("Theodore Ts'o <tytso@mit.edu>");
-MODULE_LICENSE("GPL");
-
-
-/*
- * ------------------------------------------------------------
- * Serial console driver
- * ------------------------------------------------------------
- */
-#ifdef CONFIG_SERIAL_CONSOLE
-
-#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-
-static struct async_struct async_sercons;
-
-/*
- *	Wait for transmitter & holding register to empty
- */
-static inline void wait_for_xmitr(struct async_struct *info)
-{
-	unsigned int status, tmout = 1000000;
-
-	do {
-		status = serial_in(info, UART_LSR);
-
-		if (status & UART_LSR_BI)
-			lsr_break_flag = UART_LSR_BI;
-		
-		if (--tmout == 0)
-			break;
-	} while((status & BOTH_EMPTY) != BOTH_EMPTY);
-
-	/* Wait for flow control if necessary */
-	if (info->flags & ASYNC_CONS_FLOW) {
-		tmout = 1000000;
-		while (--tmout &&
-		       ((serial_in(info, UART_MSR) & UART_MSR_CTS) == 0));
-	}	
-}
-
-
-/*
- *	Print a string to the serial port trying not to disturb
- *	any possible real use of the port...
- *
- *	The console must be locked when we get here.
- */
-static void serial_console_write(struct console *co, const char *s,
-				unsigned count)
-{
-	static struct async_struct *info = &async_sercons;
-	int ier;
-	unsigned i;
-
-	/*
-	 *	First save the IER then disable the interrupts
-	 */
-	ier = serial_in(info, UART_IER);
-	serial_out(info, UART_IER, 0x00);
-
-	/*
-	 *	Now, do each character
-	 */
-	for (i = 0; i < count; i++, s++) {
-		wait_for_xmitr(info);
-
-		/*
-		 *	Send the character out.
-		 *	If a LF, also do CR...
-		 */
-		serial_out(info, UART_TX, *s);
-		if (*s == 10) {
-			wait_for_xmitr(info);
-			serial_out(info, UART_TX, 13);
-		}
-	}
-
-	/*
-	 *	Finally, Wait for transmitter & holding register to empty
-	 * 	and restore the IER
-	 */
-	wait_for_xmitr(info);
-	serial_out(info, UART_IER, ier);
-}
-
-static kdev_t serial_console_device(struct console *c)
-{
-	return mk_kdev(TTY_MAJOR, 64 + c->index);
-}
-
-/*
- *	Setup initial baud/bits/parity/flow control. We do two things here:
- *	- construct a cflag setting for the first rs_open()
- *	- initialize the serial port
- *	Return non-zero if we didn't find a serial port.
- */
-static int __init serial_console_setup(struct console *co, char *options)
-{
-	static struct async_struct *info;
-	struct serial_state *state;
-	unsigned cval;
-	int	baud = 9600;
-	int	bits = 8;
-	int	parity = 'n';
-	int	doflow = 0;
-	int	cflag = CREAD | HUPCL | CLOCAL;
-	int	quot = 0;
-	char	*s;
-
-	if (options) {
-		baud = simple_strtoul(options, NULL, 10);
-		s = options;
-		while(*s >= '0' && *s <= '9')
-			s++;
-		if (*s) parity = *s++;
-		if (*s) bits   = *s++ - '0';
-		if (*s) doflow = (*s++ == 'r');
-	}
-
-	/*
-	 *	Now construct a cflag setting.
-	 */
-	switch(baud) {
-		case 1200:
-			cflag |= B1200;
-			break;
-		case 2400:
-			cflag |= B2400;
-			break;
-		case 4800:
-			cflag |= B4800;
-			break;
-		case 19200:
-			cflag |= B19200;
-			break;
-		case 38400:
-			cflag |= B38400;
-			break;
-		case 57600:
-			cflag |= B57600;
-			break;
-		case 115200:
-			cflag |= B115200;
-			break;
-		case 9600:
-		default:
-			cflag |= B9600;
-			/*
-			 * Set this to a sane value to prevent a divide error
-			 */
-			baud  = 9600;
-			break;
-	}
-	switch(bits) {
-		case 7:
-			cflag |= CS7;
-			break;
-		default:
-		case 8:
-			cflag |= CS8;
-			break;
-	}
-	switch(parity) {
-		case 'o': case 'O':
-			cflag |= PARODD;
-			break;
-		case 'e': case 'E':
-			cflag |= PARENB;
-			break;
-	}
-	co->cflag = cflag;
-
-	/*
-	 *	Divisor, bytesize and parity
-	 */
-	state = rs_table + co->index;
-	if (doflow)
-		state->flags |= ASYNC_CONS_FLOW;
-	info = &async_sercons;
-	info->magic = SERIAL_MAGIC;
-	info->state = state;
-	info->port = state->port;
-	info->flags = state->flags;
-#ifdef CONFIG_HUB6
-	info->hub6 = state->hub6;
-#endif
-	info->io_type = state->io_type;
-	info->iomem_base = state->iomem_base;
-	info->iomem_reg_shift = state->iomem_reg_shift;
-	quot = state->baud_base / baud;
-	cval = cflag & (CSIZE | CSTOPB);
-#if defined(__powerpc__) || defined(__alpha__)
-	cval >>= 8;
-#else /* !__powerpc__ && !__alpha__ */
-	cval >>= 4;
-#endif /* !__powerpc__ && !__alpha__ */
-	if (cflag & PARENB)
-		cval |= UART_LCR_PARITY;
-	if (!(cflag & PARODD))
-		cval |= UART_LCR_EPAR;
-
-	/*
-	 *	Disable UART interrupts, set DTR and RTS high
-	 *	and set speed.
-	 */
-	serial_out(info, UART_LCR, cval | UART_LCR_DLAB);	/* set DLAB */
-	serial_out(info, UART_DLL, quot & 0xff);	/* LS of divisor */
-	serial_out(info, UART_DLM, quot >> 8);		/* MS of divisor */
-	serial_out(info, UART_LCR, cval);		/* reset DLAB */
-	serial_out(info, UART_IER, 0);
-	serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
-
-	/*
-	 *	If we read 0xff from the LSR, there is no UART here.
-	 */
-	if (serial_in(info, UART_LSR) == 0xff)
-		return -1;
-
-	return 0;
-}
-
-static struct console sercons = {
-	name:		"ttyS",
-	write:		serial_console_write,
-	device:		serial_console_device,
-	setup:		serial_console_setup,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
-};
-
-/*
- *	Register console.
- */
-void __init serial_console_init(void)
-{
-	register_console(&sercons);
-}
-#endif
-
-/*
-  Local variables:
-  compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h   -DEXPORT_SYMTAB -c serial.c"
-  End:
-*/
diff -Nru a/drivers/char/serial167.c b/drivers/char/serial167.c
--- a/drivers/char/serial167.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/char/serial167.c	Wed Jul 24 14:03:38 2002
@@ -62,6 +62,7 @@
 #include <linux/major.h>
 #include <linux/mm.h>
 #include <linux/console.h>
+#include <linux/module.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -236,8 +237,8 @@
 }
 
 static inline int
-serial_paranoia_check(struct cyclades_port *info,
-			dev_t device, const char *routine)
+serial_paranoia_check(struct cyclades_port *info, kdev_t device,
+		      const char *routine)
 {
 #ifdef SERIAL_PARANOIA_CHECK
     static const char *badmagic =
@@ -1261,7 +1262,7 @@
 			    break;
 		    }
 
-		    cli();
+		    save_flags(flags); cli();		
 		    c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 				   SERIAL_XMIT_SIZE - info->xmit_head));
 		    memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
@@ -1276,7 +1277,7 @@
 	    up(&tmp_buf_sem);
     } else {
 	    while (1) {
-		    cli();
+		    save_flags(flags); cli();		
 		    c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 				       SERIAL_XMIT_SIZE - info->xmit_head));
 		    if (c <= 0) {
@@ -1376,7 +1377,7 @@
 #ifdef SERIAL_DEBUG_THROTTLE
   char buf[64];
 	
-    printk("throttle %s: %d....\n", _tty_name(tty, buf),
+    printk("throttle %s: %d....\n", tty_name(tty, buf),
 	   tty->ldisc.chars_in_buffer(tty));
     printk("cy_throttle ttyS%d\n", info->line);
 #endif
@@ -1412,7 +1413,7 @@
 #ifdef SERIAL_DEBUG_THROTTLE
   char buf[64];
 	
-    printk("throttle %s: %d....\n", _tty_name(tty, buf),
+    printk("throttle %s: %d....\n", tty_name(tty, buf),
 	   tty->ldisc.chars_in_buffer(tty));
     printk("cy_unthrottle ttyS%d\n", info->line);
 #endif
@@ -2394,7 +2395,11 @@
     
     memset(&cy_serial_driver, 0, sizeof(struct tty_driver));
     cy_serial_driver.magic = TTY_DRIVER_MAGIC;
+#ifdef CONFIG_DEVFS_FS
+    cy_serial_driver.name = "tts/%d";
+#else
     cy_serial_driver.name = "ttyS";
+#endif
     cy_serial_driver.major = TTY_MAJOR;
     cy_serial_driver.minor_start = 64;
     cy_serial_driver.num = NR_PORTS;
@@ -2429,7 +2434,11 @@
      * major number and the subtype code.
      */
     cy_callout_driver = cy_serial_driver;
+#ifdef CONFIG_DEVFS_FS
+    cy_callout_driver.name = "cua/%d";
+#else
     cy_callout_driver.name = "cua";
+#endif
     cy_callout_driver.major = TTYAUX_MAJOR;
     cy_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/char/tty_io.c	Wed Jul 24 14:03:38 2002
@@ -150,8 +150,7 @@
 extern void tty3215_init(void);
 extern void tub3270_con_init(void);
 extern void tub3270_init(void);
-extern void rs285_console_init(void);
-extern void sa1100_rs_console_init(void);
+extern void uart_console_init(void);
 extern void sgi_serial_console_init(void);
 extern void sci_console_init(void);
 extern void tx3912_console_init(void);
@@ -456,11 +455,12 @@
 	}
 	file_list_unlock();
 	
-	/* FIXME! What are the locking issues here? This may me overdoing things.. */
+	/* FIXME! What are the locking issues here? This may me overdoing things..
+	* this question is especially important now that we've removed the irqlock. */
 	{
 		unsigned long flags;
 
-		save_flags(flags); cli();
+		local_irq_save(flags); // FIXME: is this safe?
 		if (tty->ldisc.flush_buffer)
 			tty->ldisc.flush_buffer(tty);
 		if (tty->driver.flush_buffer)
@@ -468,7 +468,7 @@
 		if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
 		    tty->ldisc.write_wakeup)
 			(tty->ldisc.write_wakeup)(tty);
-		restore_flags(flags);
+		local_irq_restore(flags); // FIXME: is this safe?
 	}
 
 	wake_up_interruptible(&tty->write_wait);
@@ -1900,7 +1900,7 @@
 		fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
 		tty->flip.buf_num = 0;
 
-		save_flags(flags); cli();
+		local_irq_save(flags); // FIXME: is this safe?
 		tty->flip.char_buf_ptr = tty->flip.char_buf;
 		tty->flip.flag_buf_ptr = tty->flip.flag_buf;
 	} else {
@@ -1908,13 +1908,13 @@
 		fp = tty->flip.flag_buf;
 		tty->flip.buf_num = 1;
 
-		save_flags(flags); cli();
+		local_irq_save(flags); // FIXME: is this safe?
 		tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
 		tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
 	}
 	count = tty->flip.count;
 	tty->flip.count = 0;
-	restore_flags(flags);
+	local_irq_restore(flags); // FIXME: is this safe?
 	
 	tty->ldisc.receive_buf(tty, cp, fp, count);
 }
@@ -2220,17 +2220,11 @@
 #ifdef CONFIG_STDIO_CONSOLE
 	stdio_console_init();
 #endif
-#ifdef CONFIG_SERIAL_21285_CONSOLE
-	rs285_console_init();
-#endif
-#ifdef CONFIG_SERIAL_SA1100_CONSOLE
-	sa1100_rs_console_init();
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+	uart_console_init();
 #endif
 #ifdef CONFIG_ARC_CONSOLE
 	arc_console_init();
-#endif
-#ifdef CONFIG_SERIAL_AMBA_CONSOLE
-	ambauart_console_init();
 #endif
 #ifdef CONFIG_SERIAL_TX3912_CONSOLE
 	tx3912_console_init();
diff -Nru a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
--- a/drivers/char/tty_ioctl.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/char/tty_ioctl.c	Wed Jul 24 14:03:38 2002
@@ -97,7 +97,7 @@
 	int canon_change;
 	struct termios old_termios = *tty->termios;
 
-	cli();
+	local_irq_disable(); // FIXME: is this safe?
 	*tty->termios = *new_termios;
 	unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
 	canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
@@ -107,7 +107,7 @@
 		tty->canon_data = 0;
 		tty->erasing = 0;
 	}
-	sti();
+	local_irq_enable(); // FIXME: is this safe?
 	if (canon_change && !L_ICANON(tty) && tty->read_cnt)
 		/* Get characters left over from canonical mode. */
 		wake_up_interruptible(&tty->read_wait);
diff -Nru a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
--- a/drivers/char/vme_scc.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/char/vme_scc.c	Wed Jul 24 14:03:35 2002
@@ -131,7 +131,11 @@
 	memset(&scc_driver, 0, sizeof(scc_driver));
 	scc_driver.magic = TTY_DRIVER_MAGIC;
 	scc_driver.driver_name = "scc";
+#ifdef CONFIG_DEVFS_FS
+	scc_driver.name = "tts/%d";
+#else
 	scc_driver.name = "ttyS";
+#endif
 	scc_driver.major = TTY_MAJOR;
 	scc_driver.minor_start = SCC_MINOR_BASE;
 	scc_driver.num = 2;
@@ -164,7 +168,11 @@
 	scc_driver.break_ctl = scc_break_ctl;
 
 	scc_callout_driver = scc_driver;
+#ifdef CONFIG_DEVFS_FS
+	scc_callout_driver.name = "cua/%d";
+#else
 	scc_callout_driver.name = "cua";
+#endif
 	scc_callout_driver.major = TTYAUX_MAJOR;
 	scc_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 
@@ -731,12 +739,10 @@
 #ifdef CONFIG_MVME147_SCC
 	if (MACH_IS_MVME147)
 		brgval = (M147_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2;
-	else
 #endif
 #ifdef CONFIG_MVME162_SCC
 	if (MACH_IS_MVME16x)
 		brgval = (MVME_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2;
-	else
 #endif
 #ifdef CONFIG_BVME6000_SCC
 	if (MACH_IS_BVME6000)
@@ -783,6 +789,15 @@
 }
 
 
+/* Comment taken from sx.c (2.4.0):
+   I haven't the foggiest why the decrement use count has to happen
+   here. The whole linux serial drivers stuff needs to be redesigned.
+   My guess is that this is a hack to minimize the impact of a bug
+   elsewhere. Thinking about it some more. (try it sometime) Try
+   running minicom on a serial port that is driven by a modularized
+   driver. Have the modem hangup. Then remove the driver module. Then
+   exit minicom.  I expect an "oops".  -- REW */
+
 static void scc_hungup(void *ptr)
 {
 	scc_disable_tx_interrupts(ptr);
@@ -795,6 +810,7 @@
 {
 	scc_disable_tx_interrupts(ptr);
 	scc_disable_rx_interrupts(ptr);
+	MOD_DEC_USE_COUNT;
 }
 
 
@@ -809,6 +825,7 @@
 	SCC_ACCESS_INIT(port);
 
 	save_flags(flags);
+	cli();
 	t = SCCread(TX_CTRL_REG);
 	if (dtr >= 0) t = dtr? (t | TCR_DTR): (t & ~TCR_DTR);
 	if (rts >= 0) t = rts? (t | TCR_RTS): (t & ~TCR_RTS);
@@ -933,7 +950,7 @@
 	if (port->gs.count == 1) {
 		MOD_INC_USE_COUNT;
 	}
-	retval = block_til_ready(port, filp);
+	retval = gs_block_til_ready(port, filp);
 
 	if (retval) {
 		MOD_DEC_USE_COUNT;
diff -Nru a/drivers/char/vt.c b/drivers/char/vt.c
--- a/drivers/char/vt.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/char/vt.c	Wed Jul 24 14:03:39 2002
@@ -33,10 +33,6 @@
 #include <linux/kbd_diacr.h>
 #include <linux/selection.h>
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-#endif /* CONFIG_FB_COMPAT_XPMAC */
-
 char vt_dont_switch;
 extern struct tty_driver console_driver;
 
@@ -113,8 +109,7 @@
 	if (hz > 20 && hz < 32767)
 		count = 1193180 / hz;
 	
-	save_flags(flags);
-	cli();
+	local_irq_save(flags); // FIXME: is this safe?
 	del_timer(&sound_timer);
 	if (count) {
 		/* enable counter 2 */
@@ -131,7 +126,7 @@
 		}
 	} else
 		kd_nosound(0);
-	restore_flags(flags);
+	local_irq_restore(flags);
 	return;
 }
 
@@ -1047,68 +1042,6 @@
 		   return -EPERM;
 		vt_dont_switch = 0;
 		return 0;
-#ifdef CONFIG_FB_COMPAT_XPMAC
-	case VC_GETMODE:
-		{
-			struct vc_mode mode;
-
-			i = verify_area(VERIFY_WRITE, (void *) arg,
-					sizeof(struct vc_mode));
-			if (i == 0)
-				i = console_getmode(&mode);
-			if (i)
-				return i;
-			if (copy_to_user((void *) arg, &mode, sizeof(mode)))
-				return -EFAULT;
-			return 0;
-		}
-	case VC_SETMODE:
-	case VC_INQMODE:
-		{
-			struct vc_mode mode;
-
-			if (!perm)
-				return -EPERM;
-			if (copy_from_user(&mode, (void *) arg, sizeof(mode)))
-				return -EFAULT;
-			return console_setmode(&mode, cmd == VC_SETMODE);
-		}
-	case VC_SETCMAP:
-		{
-			unsigned char cmap[3][256], *p;
-			int n_entries, cmap_size, i, j;
-
-			if (!perm)
-				return -EPERM;
-			if (arg == (unsigned long) VC_POWERMODE_INQUIRY
-			    || arg <= VESA_POWERDOWN) {
-				/* compatibility hack: VC_POWERMODE
-				   was changed from 0x766a to 0x766c */
-				return console_powermode((int) arg);
-			}
-			if (get_user(cmap_size, (int *) arg))
-				return -EFAULT;
-			if (cmap_size % 3)
-				return -EINVAL;
-			n_entries = cmap_size / 3;
-			if ((unsigned) n_entries > 256)
-				return -EINVAL;
-			p = (unsigned char *) (arg + sizeof(int));
-			for (j = 0; j < n_entries; ++j)
-				for (i = 0; i < 3; ++i)
-					if (get_user(cmap[i][j], p++))
-						return -EFAULT;
-			return console_setcmap(n_entries, cmap[0],
-					       cmap[1], cmap[2]);
-		}
-	case VC_GETCMAP:
-		/* not implemented yet */
-		return -ENOIOCTLCMD;
-	case VC_POWERMODE:
-		if (!perm)
-			return -EPERM;
-		return console_powermode((int) arg);
-#endif /* CONFIG_FB_COMPAT_XPMAC */
 	default:
 		return -ENOIOCTLCMD;
 	}
diff -Nru a/drivers/dio/dio.c b/drivers/dio/dio.c
--- a/drivers/dio/dio.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/dio/dio.c	Wed Jul 24 14:03:39 2002
@@ -115,8 +115,14 @@
 static int __init dio_find_slow(int deviceid)
 {
 	/* Called to find a DIO device before the full bus scan has run.  Basically
-	   only used by the console driver.  */
+         * only used by the console driver.
+         * We don't do the primary+secondary ID encoding thing here. Maybe we should.
+         * (that would break the topcat detection, though. I need to think about
+         * the whole primary/secondary ID thing.)
+         */
 	int scode;
+        u_char prid;
+
 	for (scode = 0; scode < DIO_SCMAX; scode++)
 	{
 		void *va;
@@ -128,12 +134,23 @@
                 if (!va || !hwreg_present(va + DIO_IDOFF))
                         continue;             /* no board present at that select code */
 
-		if (DIO_ID(va) == deviceid)
+                /* We aren't very likely to want to use this to get at the IHPIB,
+                 * but maybe it's returning the same ID as the card we do want...
+                 */
+                if (!DIO_ISIHPIB(scode))
+                        prid = DIO_ID(va);
+                else
+                        prid = DIO_ID_IHPIB;
+
+		if (prid == deviceid)
 			return scode;
 	}
 	return 0;
 }
 
+/* Aargh: we use 0 for an error return code, but select code 0 exists!
+ * FIXME (trivial, use -1, but requires changes to all the drivers :-< )
+ */
 int dio_find(int deviceid)
 {
 	if (blist) 
@@ -151,7 +168,7 @@
 /* This is the function that scans the DIO space and works out what
  * hardware is actually present.
  */
-void __init dio_init(void)
+static int __init dio_init(void)
 {
         int scode;
         struct dioboard *b, *bprev = NULL;
@@ -193,10 +210,10 @@
                 b->scode = scode;
                 b->ipl = DIO_IPL(va);
                 b->name = dio_getname(b->id);
-                printk("select code %3d: ID %02X", scode, prid);
+                printk("select code %3d: ipl %d: ID %02X", scode, b->ipl, prid);
                 if (DIO_NEEDSSECID(b->id))
                         printk(":%02X", secid);
-                printk(" %s\n", b->name);
+                printk(": %s\n", b->name);
                 
                 b->next = NULL;
 
@@ -206,6 +223,7 @@
                         blist = b;
                 bprev = b;
         }
+	return 0;
 }
 
 subsys_initcall(dio_init);
@@ -224,9 +242,9 @@
                 return 0;
         else if (DIO_SCINHOLE(scode))
                 return 0;
-        else if (scode == DIO_IHPIBSCODE) /* this should really be #ifdef CONFIG_IHPIB */
-                return (void*)DIO_IHPIBADDR;   /* or something similar... */
-        
+        else if (DIO_ISIHPIB(scode))
+                return (void*)DIO_IHPIBADDR;
+
         return (void*)(DIO_VIRADDRBASE + DIO_BASE + scode * 0x10000);
 }
 
diff -Nru a/drivers/hotplug/cpqphp_core.c b/drivers/hotplug/cpqphp_core.c
--- a/drivers/hotplug/cpqphp_core.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/hotplug/cpqphp_core.c	Wed Jul 24 14:03:35 2002
@@ -81,15 +81,15 @@
 static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
 
 static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
-	owner:			THIS_MODULE,
-	set_attention_status:	set_attention_status,
-	enable_slot:		process_SI,
-	disable_slot:		process_SS,
-	hardware_test:		hardware_test,
-	get_power_status:	get_power_status,
-	get_attention_status:	get_attention_status,
-	get_latch_status:	get_latch_status,
-	get_adapter_status:	get_adapter_status,
+	.owner =		THIS_MODULE,
+	.set_attention_status =	set_attention_status,
+	.enable_slot =		process_SI,
+	.disable_slot =		process_SS,
+	.hardware_test =	hardware_test,
+	.get_power_status =	get_power_status,
+	.get_attention_status =	get_attention_status,
+	.get_latch_status =	get_latch_status,
+	.get_adapter_status =	get_adapter_status,
 };
 
 
@@ -1387,14 +1387,14 @@
 static struct pci_device_id hpcd_pci_tbl[] __devinitdata = {
 	{
 	/* handle any PCI Hotplug controller */
-	class:          ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
-	class_mask:     ~0,
+	.class =        ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
+	.class_mask =   ~0,
 	
 	/* no matter who makes it */
-	vendor:         PCI_ANY_ID,
-	device:         PCI_ANY_ID,
-	subvendor:      PCI_ANY_ID,
-	subdevice:      PCI_ANY_ID,
+	.vendor =       PCI_ANY_ID,
+	.device =       PCI_ANY_ID,
+	.subvendor =    PCI_ANY_ID,
+	.subdevice =    PCI_ANY_ID,
 	
 	}, { /* end: all zeroes */ }
 };
@@ -1404,9 +1404,9 @@
 
 
 static struct pci_driver cpqhpc_driver = {
-	name:		"pci_hotplug",
-	id_table:	hpcd_pci_tbl,
-	probe:		cpqhpc_probe,
+	.name =		"pci_hotplug",
+	.id_table =	hpcd_pci_tbl,
+	.probe =	cpqhpc_probe,
 	/* remove:	cpqhpc_remove_one, */
 };
 
diff -Nru a/drivers/hotplug/cpqphp_pci.c b/drivers/hotplug/cpqphp_pci.c
--- a/drivers/hotplug/cpqphp_pci.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/hotplug/cpqphp_pci.c	Wed Jul 24 14:03:39 2002
@@ -232,17 +232,17 @@
 
 
 static struct pci_visit configure_functions = {
-	visit_pci_dev:		configure_visit_pci_dev,
+	.visit_pci_dev =	configure_visit_pci_dev,
 };
 
 
 static struct pci_visit unconfigure_functions_phase1 = {
-	post_visit_pci_dev:	unconfigure_visit_pci_dev_phase1
+	.post_visit_pci_dev =	unconfigure_visit_pci_dev_phase1
 };
 
 static struct pci_visit unconfigure_functions_phase2 = {
-	post_visit_pci_bus:	unconfigure_visit_pci_bus_phase2,               
-	post_visit_pci_dev:	unconfigure_visit_pci_dev_phase2
+	.post_visit_pci_bus =	unconfigure_visit_pci_bus_phase2,               
+	.post_visit_pci_dev =	unconfigure_visit_pci_dev_phase2
 };
 
 
diff -Nru a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c
--- a/drivers/hotplug/ibmphp_core.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/hotplug/ibmphp_core.c	Wed Jul 24 14:03:38 2002
@@ -893,12 +893,12 @@
 }
 
 static struct pci_visit ibm_unconfigure_functions_phase1 = {
-	post_visit_pci_dev:	ibm_unconfigure_visit_pci_dev_phase1,
+	.post_visit_pci_dev =	ibm_unconfigure_visit_pci_dev_phase1,
 };
 
 static struct pci_visit ibm_unconfigure_functions_phase2 = {
-	post_visit_pci_bus:	ibm_unconfigure_visit_pci_bus_phase2,
-	post_visit_pci_dev:	ibm_unconfigure_visit_pci_dev_phase2,
+	.post_visit_pci_bus =	ibm_unconfigure_visit_pci_bus_phase2,
+	.post_visit_pci_dev =	ibm_unconfigure_visit_pci_dev_phase2,
 };
 
 static int ibm_unconfigure_device (struct pci_func *func)
@@ -962,7 +962,7 @@
 }
 
 static struct pci_visit configure_functions = {
-	visit_pci_dev:	configure_visit_pci_dev,
+	.visit_pci_dev =configure_visit_pci_dev,
 };
 
 static int ibm_configure_device (struct pci_func *func)
@@ -1494,19 +1494,19 @@
 }
 
 struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
-	owner:				THIS_MODULE,
-	set_attention_status:		set_attention_status,
-	enable_slot:			enable_slot,
-	disable_slot:			ibmphp_disable_slot,
-	hardware_test:			NULL,
-	get_power_status:		get_power_status,
-	get_attention_status:		get_attention_status,
-	get_latch_status:		get_latch_status,
-	get_adapter_status:		get_adapter_present,
+	.owner =			THIS_MODULE,
+	.set_attention_status =		set_attention_status,
+	.enable_slot =			enable_slot,
+	.disable_slot =			ibmphp_disable_slot,
+	.hardware_test =		NULL,
+	.get_power_status =		get_power_status,
+	.get_attention_status =		get_attention_status,
+	.get_latch_status =		get_latch_status,
+	.get_adapter_status =		get_adapter_present,
 /*	get_max_bus_speed_status:	get_max_bus_speed,
-	get_max_adapter_speed_status:	get_max_adapter_speed,
-	get_cur_bus_speed_status:	get_cur_bus_speed,
-	get_card_bus_names_status:	get_card_bus_names,
+	.get_max_adapter_speed_status =	get_max_adapter_speed,
+	.get_cur_bus_speed_status =	get_cur_bus_speed,
+	.get_card_bus_names_status =	get_card_bus_names,
 */
 };
 
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
--- a/drivers/hotplug/pci_hotplug_core.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/hotplug/pci_hotplug_core.c	Wed Jul 24 14:03:37 2002
@@ -48,7 +48,7 @@
 	#define MY_NAME	THIS_MODULE->name
 #endif
 
-#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt, MY_NAME, __FUNCTION__, ## arg); } while (0)
+#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)
 #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
 #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
@@ -109,6 +109,9 @@
 		case S_IFDIR:
 			inode->i_op = &pcihpfs_dir_inode_operations;
 			inode->i_fop = &simple_dir_operations;
+
+			/* directory inodes start off with i_nlink == 2 (for "." entry) */
+			inode->i_nlink++;
 			break;
 		}
 	}
@@ -227,71 +230,71 @@
 }
 
 static struct file_operations default_file_operations = {
-	read:		default_read_file,
-	write:		default_write_file,
-	open:		default_open,
-	llseek:		default_file_lseek,
+	.read =		default_read_file,
+	.write =	default_write_file,
+	.open =		default_open,
+	.llseek =	default_file_lseek,
 };
 
 /* file ops for the "power" files */
 static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
 static ssize_t power_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
 static struct file_operations power_file_operations = {
-	read:		power_read_file,
-	write:		power_write_file,
-	open:		default_open,
-	llseek:		default_file_lseek,
+	.read =		power_read_file,
+	.write =	power_write_file,
+	.open =		default_open,
+	.llseek =	default_file_lseek,
 };
 
 /* file ops for the "attention" files */
 static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
 static ssize_t attention_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
 static struct file_operations attention_file_operations = {
-	read:		attention_read_file,
-	write:		attention_write_file,
-	open:		default_open,
-	llseek:		default_file_lseek,
+	.read =		attention_read_file,
+	.write =	attention_write_file,
+	.open =		default_open,
+	.llseek =	default_file_lseek,
 };
 
 /* file ops for the "latch" files */
 static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
 static struct file_operations latch_file_operations = {
-	read:		latch_read_file,
-	write:		default_write_file,
-	open:		default_open,
-	llseek:		default_file_lseek,
+	.read =		latch_read_file,
+	.write =	default_write_file,
+	.open =		default_open,
+	.llseek =	default_file_lseek,
 };
 
 /* file ops for the "presence" files */
 static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
 static struct file_operations presence_file_operations = {
-	read:		presence_read_file,
-	write:		default_write_file,
-	open:		default_open,
-	llseek:		default_file_lseek,
+	.read =		presence_read_file,
+	.write =	default_write_file,
+	.open =		default_open,
+	.llseek =	default_file_lseek,
 };
 
 /* file ops for the "test" files */
 static ssize_t test_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
 static struct file_operations test_file_operations = {
-	read:		default_read_file,
-	write:		test_write_file,
-	open:		default_open,
-	llseek:		default_file_lseek,
+	.read =		default_read_file,
+	.write =	test_write_file,
+	.open =		default_open,
+	.llseek =	default_file_lseek,
 };
 
 static struct inode_operations pcihpfs_dir_inode_operations = {
-	create:		pcihpfs_create,
-	lookup:		simple_lookup,
-	unlink:		pcihpfs_unlink,
-	mkdir:		pcihpfs_mkdir,
-	rmdir:		pcihpfs_rmdir,
-	mknod:		pcihpfs_mknod,
+	.create =	pcihpfs_create,
+	.lookup =	simple_lookup,
+	.unlink =	pcihpfs_unlink,
+	.mkdir =	pcihpfs_mkdir,
+	.rmdir =	pcihpfs_rmdir,
+	.mknod =	pcihpfs_mknod,
 };
 
 static struct super_operations pcihpfs_ops = {
-	statfs:		simple_statfs,
-	drop_inode:	generic_delete_inode,
+	.statfs =	simple_statfs,
+	.drop_inode =	generic_delete_inode,
 };
 
 static int pcihpfs_fill_super(struct super_block *sb, void *data, int silent)
@@ -327,10 +330,10 @@
 }
 
 static struct file_system_type pcihpfs_type = {
-	owner:		THIS_MODULE,
-	name:		"pcihpfs",
-	get_sb:		pcihpfs_get_sb,
-	kill_sb:	kill_litter_super,
+	.owner =	THIS_MODULE,
+	.name =		"pcihpfs",
+	.get_sb =	pcihpfs_get_sb,
+	.kill_sb =	kill_litter_super,
 };
 
 static int get_mount (void)
diff -Nru a/drivers/hotplug/pci_hotplug_util.c b/drivers/hotplug/pci_hotplug_util.c
--- a/drivers/hotplug/pci_hotplug_util.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/hotplug/pci_hotplug_util.c	Wed Jul 24 14:03:38 2002
@@ -41,7 +41,7 @@
 	#define MY_NAME	THIS_MODULE->name
 #endif
 
-#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt, MY_NAME, __FUNCTION__, ## arg); } while (0)
+#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)
 #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
 #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
diff -Nru a/drivers/hotplug/pcihp_skeleton.c b/drivers/hotplug/pcihp_skeleton.c
--- a/drivers/hotplug/pcihp_skeleton.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/hotplug/pcihp_skeleton.c	Wed Jul 24 14:03:38 2002
@@ -89,15 +89,15 @@
 static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
 
 static struct hotplug_slot_ops skel_hotplug_slot_ops = {
-	owner:			THIS_MODULE,
-	enable_slot:		enable_slot,
-	disable_slot:		disable_slot,
-	set_attention_status:	set_attention_status,
-	hardware_test:		hardware_test,
-	get_power_status:	get_power_status,
-	get_attention_status:	get_attention_status,
-	get_latch_status:	get_latch_status,
-	get_adapter_status:	get_adapter_status,
+	.owner =		THIS_MODULE,
+	.enable_slot =		enable_slot,
+	.disable_slot =		disable_slot,
+	.set_attention_status =	set_attention_status,
+	.hardware_test =	hardware_test,
+	.get_power_status =	get_power_status,
+	.get_attention_status =	get_attention_status,
+	.get_latch_status =	get_latch_status,
+	.get_adapter_status =	get_adapter_status,
 };
 
 
diff -Nru a/drivers/ide/device.c b/drivers/ide/device.c
--- a/drivers/ide/device.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/ide/device.c	Wed Jul 24 14:03:37 2002
@@ -150,16 +150,16 @@
 	if (!ata_status(drive, 0, BUSY_STAT)) {
 		unsigned long flags;
 
-		__save_flags(flags);
+		local_save_flags(flags);
 		local_irq_enable();
 		timeout += jiffies;
 		while (!ata_status(drive, 0, BUSY_STAT)) {
 			if (time_after(jiffies, timeout)) {
-				__restore_flags(flags);
+				local_irq_restore(flags);
 				return ata_error(drive, rq, "status timeout");
 			}
 		}
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 
 	/*
diff -Nru a/drivers/ide/hd.c b/drivers/ide/hd.c
--- a/drivers/ide/hd.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/ide/hd.c	Wed Jul 24 14:03:36 2002
@@ -83,9 +83,6 @@
 
 static char recalibrate[MAX_HD];
 static char special_op[MAX_HD];
-static int access_count[MAX_HD];
-static char busy[MAX_HD];
-static DECLARE_WAIT_QUEUE_HEAD(busy_wait);
 
 static int reset;
 static int hd_error;
@@ -644,7 +641,7 @@
 			g.heads = hd_info[dev].head;
 			g.sectors = hd_info[dev].sect;
 			g.cylinders = hd_info[dev].cyl;
-			g.start = get_start_sect(inode->i_rdev);
+			g.start = get_start_sect(inode->i_bdev);
 			return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
 		}
 
@@ -653,14 +650,6 @@
 				return -EACCES;
 			return revalidate_hddisk(inode->i_rdev, 1);
 
-         	case BLKGETSIZE:
-		case BLKGETSIZE64:
-		case BLKROSET:
-		case BLKROGET:
-		case BLKFLSBUF:
-		case BLKPG:
-			return blk_ioctl(inode->i_bdev, cmd, arg);
-
 		default:
 			return -EINVAL;
 	}
@@ -668,14 +657,9 @@
 
 static int hd_open(struct inode * inode, struct file * filp)
 {
-	int target;
-	target =  DEVICE_NR(inode->i_rdev);
-
+	int target =  DEVICE_NR(inode->i_rdev);
 	if (target >= NR_HD)
 		return -ENODEV;
-	while (busy[target])
-		sleep_on(&busy_wait);
-	access_count[target]++;
 	return 0;
 }
 
@@ -683,12 +667,6 @@
  * Releasing a block device means we sync() it, so that it can safely
  * be forgotten about...
  */
-static int hd_release(struct inode * inode, struct file * file)
-{
-        int target =  DEVICE_NR(inode->i_rdev);
-	access_count[target]--;
-	return 0;
-}
 
 extern struct block_device_operations hd_fops;
 
@@ -715,7 +693,6 @@
 
 static struct block_device_operations hd_fops = {
 	.open =		hd_open,
-	.release =	hd_release,
 	.ioctl =	hd_ioctl,
 };
 
@@ -854,13 +831,9 @@
 	return 0;
 }
 
-#define DEVICE_BUSY busy[target]
-#define USAGE access_count[target]
 #define CAPACITY (hd_info[target].head*hd_info[target].sect*hd_info[target].cyl)
 /* We assume that the BIOS parameters do not change, so the disk capacity
    will not change */
-#undef MAYBE_REINIT
-#define GENDISK_STRUCT hd_gendisk
 
 /*
  * This routine is called to flush all partitions and partition tables
@@ -872,36 +845,15 @@
  */
 static int revalidate_hddisk(kdev_t dev, int maxusage)
 {
-	int target;
-	struct gendisk * gdev;
-	int res;
-	long flags;
-
-	target = DEVICE_NR(dev);
-	gdev = &GENDISK_STRUCT;
-
-	save_flags(flags);
-	cli();
-	if (DEVICE_BUSY || USAGE > maxusage) {
-		restore_flags(flags);
-		return -EBUSY;
-	}
-	DEVICE_BUSY = 1;
-	restore_flags(flags);
-
-	res = wipe_partitions(dev);
-	if (res)
-		goto leave;
-
-#ifdef MAYBE_REINIT
-	MAYBE_REINIT;
-#endif
-
-	grok_partitions(dev, CAPACITY);
-
-leave:
-	DEVICE_BUSY = 0;
-	wake_up(&busy_wait);
+	int target = DEVICE_NR(dev);
+	kdev_t device = mk_kdev(MAJOR_NR, target << 6);
+	int res = dev_lock_part(device);
+	if (res < 0)
+		return res;
+	res = wipe_partitions(device);
+	if (!res)
+		grok_partitions(device, CAPACITY);
+	dev_unlock_part(device);
 	return res;
 }
 
diff -Nru a/drivers/ide/hptraid.c b/drivers/ide/hptraid.c
--- a/drivers/ide/hptraid.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/ide/hptraid.c	Wed Jul 24 14:03:39 2002
@@ -122,11 +122,6 @@
 			return 0;
 		}
 
-	case BLKROSET:
-	case BLKROGET:
-	case BLKSSZGET:
-		return blk_ioctl(inode->i_bdev, cmd, arg);
-
 	default:
 		return -EINVAL;
 	};
diff -Nru a/drivers/ide/ide-pmac.c b/drivers/ide/ide-pmac.c
--- a/drivers/ide/ide-pmac.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/ide/ide-pmac.c	Wed Jul 24 14:03:39 2002
@@ -419,10 +419,10 @@
 	OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
 	OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
 	udelay(1);
-	__save_flags(flags);
+	local_save_flags(flags);
 	local_irq_enable();
 	result = wait_for_ready(drive);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	ata_irq_enable(drive, 1);
 	if (result)
 		printk(KERN_ERR "pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n");
diff -Nru a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
--- a/drivers/ide/ide-taskfile.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/ide/ide-taskfile.c	Wed Jul 24 14:03:38 2002
@@ -194,22 +194,16 @@
 	request_queue_t *q = &drive->queue;
 	struct list_head *queue_head = &q->queue_head;
 	DECLARE_COMPLETION(wait);
+	struct request req;
 
 #ifdef CONFIG_BLK_DEV_PDC4030
 	if (ch->chipset == ide_pdc4030 && buf)
 		return -ENOSYS;  /* special drive cmds not supported */
 #endif
 
-	rq = __blk_get_request(&drive->queue, READ);
-	if (!rq)
-		rq = __blk_get_request(&drive->queue, WRITE);
-
-	/*
-	 * FIXME: Make sure there is a free slot on the list!
-	 */
-
-	BUG_ON(!rq);
-
+	memset(&req, 0, sizeof(req));
+	rq = &req;
+	
 	rq->flags = REQ_SPECIAL;
 	rq->buffer = buf;
 	rq->special = ar;
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/ide/ide.c	Wed Jul 24 14:03:39 2002
@@ -288,7 +288,7 @@
 	u8 err = 0;
 
 	/* FIXME:  --bzolnier */
-	__save_flags(flags);
+	local_save_flags(flags);
 	local_irq_enable();
 
 	printk("%s: %s: status=0x%02x", drive->name, msg, drive->status);
@@ -337,7 +337,7 @@
 #endif
 		printk("\n");
 	}
-	__restore_flags (flags);
+	local_irq_restore (flags);
 
 	return err;
 }
@@ -1104,9 +1104,6 @@
 
 	if (drive->driver == NULL)
 		ide_driver_module();
-
-	while (drive->busy)
-		sleep_on(&drive->wqueue);
 
 	++drive->usage;
 	if (ata_ops(drive) && ata_ops(drive)->open)
diff -Nru a/drivers/ide/ioctl.c b/drivers/ide/ioctl.c
--- a/drivers/ide/ioctl.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/ide/ioctl.c	Wed Jul 24 14:03:37 2002
@@ -343,19 +343,6 @@
 		case BLKRRPART: /* Re-read partition tables */
 			return ata_revalidate(inode->i_rdev);
 
-		case BLKGETSIZE:
-		case BLKGETSIZE64:
-		case BLKROSET:
-		case BLKROGET:
-		case BLKFLSBUF:
-		case BLKSSZGET:
-		case BLKPG:
-		case BLKELVGET:
-		case BLKELVSET:
-		case BLKBSZGET:
-		case BLKBSZSET:
-			return blk_ioctl(inode->i_bdev, cmd, arg);
-
 		/* Now check whatever this particular ioctl has a device type
 		 * specific implementation.
 		 */
diff -Nru a/drivers/ide/main.c b/drivers/ide/main.c
--- a/drivers/ide/main.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/ide/main.c	Wed Jul 24 14:03:35 2002
@@ -249,28 +249,22 @@
  */
 int ata_revalidate(kdev_t i_rdev)
 {
+	kdev_t device = mk_kdev(major(i_rdev), minor(i_rdev) & ~PARTN_MASK);
 	struct ata_device *drive;
-	unsigned long flags;
 	int res;
 
-	if ((drive = get_info_ptr(i_rdev)) == NULL)
+	if ((drive = get_info_ptr(device)) == NULL)
 		return -ENODEV;
 
-	/* FIXME: The locking here doesn't make the slightest sense! */
-	spin_lock_irqsave(&ide_lock, flags);
-
-	if (drive->busy || (drive->usage > 1)) {
-		spin_unlock_irqrestore(&ide_lock, flags);
-
-		return -EBUSY;
-	}
-
-	drive->busy = 1;
 	MOD_INC_USE_COUNT;
 
-	spin_unlock_irqrestore(&ide_lock, flags);
+	res = dev_lock_part(device);
+	if (res < 0) {
+		MOD_DEC_USE_COUNT;
+		return res;
+	}
 
-	res = wipe_partitions(i_rdev);
+	res = wipe_partitions(device);
 	if (!res) {
 		if (ata_ops(drive) && ata_ops(drive)->revalidate) {
 			ata_get(ata_ops(drive));
@@ -281,14 +275,11 @@
 			ata_ops(drive)->revalidate(drive);
 			ata_put(ata_ops(drive));
 		} else
-			grok_partitions(i_rdev, ata_capacity(drive));
+			grok_partitions(device, ata_capacity(drive));
 	}
 
-	drive->busy = 0;
-	wake_up(&drive->wqueue);
-
+	dev_unlock_part(device);
 	MOD_DEC_USE_COUNT;
-
 	return res;
 }
 
@@ -1089,29 +1080,18 @@
  */
 int ide_unregister_subdriver(struct ata_device *drive)
 {
-	unsigned long flags;
-
-	save_flags(flags);		/* all CPUs */
-	cli();				/* all CPUs */
-
 #if 0
-	if (__MOD_IN_USE(ata_ops(drive)->owner)) {
-		restore_flags(flags);
+	if (__MOD_IN_USE(ata_ops(drive)->owner))
 		return 1;
-	}
 #endif
 
-	if (drive->usage || drive->busy || !ata_ops(drive)) {
-		restore_flags(flags);	/* all CPUs */
+	if (drive->usage || drive->busy || !ata_ops(drive))
 		return 1;
-	}
 
 #if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP) && defined(MODULE)
 	pnpide_init(0);
 #endif
 	drive->driver = NULL;
-
-	restore_flags(flags);		/* all CPUs */
 
 	return 0;
 }
diff -Nru a/drivers/ide/pdcraid.c b/drivers/ide/pdcraid.c
--- a/drivers/ide/pdcraid.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/ide/pdcraid.c	Wed Jul 24 14:03:38 2002
@@ -152,11 +152,6 @@
 			return 0;
 		}
 
-	case BLKROSET:
-	case BLKROGET:
-	case BLKSSZGET:
-		return blk_ioctl(inode->i_bdev, cmd, arg);
-
 	default:
 		printk("Invalid ioctl \n");
 		return -EINVAL;
diff -Nru a/drivers/ide/probe.c b/drivers/ide/probe.c
--- a/drivers/ide/probe.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/ide/probe.c	Wed Jul 24 14:03:35 2002
@@ -733,7 +733,7 @@
 
 	ch->straight8 = 0;
 
-	__save_flags(flags);
+	local_save_flags(flags);
 	local_irq_enable();	/* needed for jiffies and irq probing */
 
 	/*
@@ -852,7 +852,7 @@
 	if (ch->reset)
 		ata_reset(ch);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	/*
 	 * Now setup the PIO transfer modes of the drives on this channel.
@@ -869,7 +869,7 @@
 	return;
 
 not_found:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
diff -Nru a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
--- a/drivers/ide/q40ide.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/ide/q40ide.c	Wed Jul 24 14:03:38 2002
@@ -79,8 +79,8 @@
     for (i = 0; i < Q40IDE_NUM_HWIFS; i++) {
 	hw_regs_t hw;
 
-	ide_setup_ports(&hw,(ide_ioreg_t) pcide_bases[i], (int *)pcide_offsets,
-			pcide_bases[i] + 0x206,
+	ide_setup_ports(&hw, (ide_ioreg_t)pcide_bases[i], (int *)pcide_offsets,
+			(ide_ioreg_t)pcide_bases[i]+0x206,
 			0, NULL, q40ide_default_irq(pcide_bases[i]));
 	ide_register_hw(&hw);
     }
diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
--- a/drivers/ieee1394/sbp2.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/ieee1394/sbp2.c	Wed Jul 24 14:03:36 2002
@@ -3097,7 +3097,7 @@
 /*
  * Called by scsi stack to get bios parameters (used by fdisk, and at boot).
  */
-static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[]) 
+static int sbp2scsi_biosparam (Scsi_Disk *disk, struct block_device *dev, int geom[]) 
 {
 	int heads, sectors, cylinders;
 
diff -Nru a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
--- a/drivers/ieee1394/sbp2.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/ieee1394/sbp2.h	Wed Jul 24 14:03:36 2002
@@ -542,7 +542,7 @@
 static int sbp2scsi_detect (Scsi_Host_Template *tpnt);
 static const char *sbp2scsi_info (struct Scsi_Host *host);
 void sbp2scsi_setup(char *str, int *ints);
-static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[]);
+static int sbp2scsi_biosparam (Scsi_Disk *disk, struct block_device *dev, int geom[]);
 static int sbp2scsi_abort (Scsi_Cmnd *SCpnt); 
 static int sbp2scsi_reset (Scsi_Cmnd *SCpnt); 
 static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
diff -Nru a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
--- a/drivers/input/joystick/a3d.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/input/joystick/a3d.c	Wed Jul 24 14:03:35 2002
@@ -84,8 +84,7 @@
 	t = gameport_time(gameport, A3D_MAX_START);
 	s = gameport_time(gameport, A3D_MAX_STROBE);
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 	gameport_trigger(gameport);
 	v = gameport_read(gameport);
 
@@ -98,7 +97,7 @@
 		}
 	}
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return i;
 }
diff -Nru a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
--- a/drivers/input/joystick/adi.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/input/joystick/adi.c	Wed Jul 24 14:03:37 2002
@@ -152,8 +152,7 @@
 		s[i] = 0;
 	}
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 
 	gameport_trigger(gameport);
 	v = z = gameport_read(gameport);
@@ -172,7 +171,7 @@
 		}
 	} while (t[0] > 0 || t[1] > 0);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return;
 }
diff -Nru a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
--- a/drivers/input/joystick/analog.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/input/joystick/analog.c	Wed Jul 24 14:03:37 2002
@@ -232,11 +232,10 @@
 	loopout = (ANALOG_LOOP_TIME * port->loop) / 1000;
 	timeout = ANALOG_MAX_TIME * port->speed;
 	
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 	gameport_trigger(gameport);
 	GET_TIME(now);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	start = now;
 	this = port->mask;
@@ -246,10 +245,10 @@
 		loop = now;
 		last = this;
 
-		__cli();
+		local_irq_disable();
 		this = gameport_read(gameport) & port->mask;
 		GET_TIME(now);
-		__restore_flags(flags);
+		local_irq_restore(flags);
 
 		if ((last ^ this) && (DELTA(loop, now) < loopout)) {
 			data[i] = last ^ this;
diff -Nru a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
--- a/drivers/input/joystick/cobra.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/input/joystick/cobra.c	Wed Jul 24 14:03:38 2002
@@ -73,8 +73,7 @@
 		t[i] = COBRA_MAX_STROBE;
 	}
 	
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 
 	u = gameport_read(gameport);
 
@@ -91,7 +90,7 @@
 			}
 	} while (t[0] > 0 || t[1] > 0);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	ret = 0;
 
diff -Nru a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
--- a/drivers/input/joystick/gamecon.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/input/joystick/gamecon.c	Wed Jul 24 14:03:39 2002
@@ -113,13 +113,12 @@
  * Request the pad to transmit data
  */
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 	for (i = 0; i < GC_N64_REQUEST_LENGTH; i++) {
 		parport_write_data(gc->pd->port, GC_N64_POWER_W | ((GC_N64_REQUEST >> i) & 1 ? GC_N64_OUT : 0));
 		udelay(GC_N64_DWS);
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 /*
  * Wait for the pad response to be loaded into the 33-bit register of the adapter
@@ -270,8 +269,7 @@
 	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER);			/* Deselect, begin command */
 	udelay(GC_PSX_DELAY * 2);
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 
 	gc_psx_command(gc, 0x01);							/* Access pad */
 	id = gc_psx_command(gc, 0x42);							/* Get device id */
@@ -280,7 +278,7 @@
 			data[i] = gc_psx_command(gc, 0);
 	} else id = 0;
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER);
 
diff -Nru a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
--- a/drivers/input/joystick/gf2k.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/input/joystick/gf2k.c	Wed Jul 24 14:03:36 2002
@@ -106,8 +106,7 @@
 
 	i = 0;
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 
 	gameport_trigger(gameport);
 	v = gameport_read(gameport);;
@@ -121,7 +120,7 @@
 		}
 	}
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return i;
 }
@@ -137,8 +136,7 @@
 	unsigned long flags;
 	int i, t;
 
-        __save_flags(flags);
-        __cli();
+        local_irq_save(flags);
 
 	i = 0;
         do {
@@ -150,7 +148,7 @@
 
 	gameport_trigger(gameport);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
diff -Nru a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
--- a/drivers/input/joystick/grip.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/input/joystick/grip.c	Wed Jul 24 14:03:37 2002
@@ -98,8 +98,7 @@
 	t = strobe;
 	i = 0;
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 
 	v = gameport_read(gameport) >> shift;
 
@@ -112,7 +111,7 @@
 		}
 	} while (i < GRIP_LENGTH_GPP && t > 0);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	if (i < GRIP_LENGTH_GPP) return -1;
 
@@ -140,8 +139,7 @@
 	status = buf = i = j = 0;
 	t = strobe;
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 
 	v = w = (gameport_read(gameport) >> shift) & 3;
 
@@ -176,7 +174,7 @@
 
 	} while (status != 0xf && i < GRIP_MAX_BITS_XT && j < GRIP_MAX_CHUNKS_XT && t > 0);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return -(status != 0xf);
 }
diff -Nru a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
--- a/drivers/input/joystick/guillemot.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/input/joystick/guillemot.c	Wed Jul 24 14:03:37 2002
@@ -98,8 +98,7 @@
 	t = gameport_time(gameport, GUILLEMOT_MAX_START);
 	s = gameport_time(gameport, GUILLEMOT_MAX_STROBE);
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 	gameport_trigger(gameport);
 	v = gameport_read(gameport);
 
@@ -113,7 +112,7 @@
 		}
 	}
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return i;
 }
diff -Nru a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
--- a/drivers/input/joystick/interact.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/input/joystick/interact.c	Wed Jul 24 14:03:35 2002
@@ -103,8 +103,7 @@
 	t = gameport_time(gameport, INTERACT_MAX_START);
 	s = gameport_time(gameport, INTERACT_MAX_STROBE);
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 	gameport_trigger(gameport);
 	v = gameport_read(gameport);
 
@@ -120,7 +119,7 @@
 		}
 	}
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return i;
 }
diff -Nru a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
--- a/drivers/input/joystick/sidewinder.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/input/joystick/sidewinder.c	Wed Jul 24 14:03:39 2002
@@ -149,8 +149,7 @@
 	pending = 0;
 	sched = 0;
 
-        __save_flags(flags);					/* Quiet, please */
-        __cli();
+        local_irq_save(flags);					/* Quiet, please */
 
 	gameport_trigger(gameport);				/* Trigger */
 	v = gameport_read(gameport);
@@ -193,7 +192,7 @@
 		}
 	}
 
-	__restore_flags(flags);					/* Done - relax */
+	local_irq_restore(flags);					/* Done - relax */
 
 #ifdef SW_DEBUG
 	{
@@ -245,8 +244,7 @@
 	unsigned long flags;
 	int i, t;
 
-        __save_flags(flags);
-        __cli();
+        local_irq_save(flags);
 
 	i = 0;
         do {
@@ -258,7 +256,7 @@
 
 	gameport_trigger(gameport);				/* Last trigger */
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /*
diff -Nru a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
--- a/drivers/input/joystick/tmdc.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/input/joystick/tmdc.c	Wed Jul 24 14:03:37 2002
@@ -125,8 +125,7 @@
 		i[k] = j[k] = 0;
 	}
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 	gameport_trigger(gameport);
 	
 	w = gameport_read(gameport) >> 4;
@@ -153,7 +152,7 @@
 		}
 	} while (t[0] > 0 || t[1] > 0);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return (i[0] == TMDC_MAX_LENGTH) | ((i[1] == TMDC_MAX_LENGTH) << 1);
 }
diff -Nru a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
--- a/drivers/macintosh/Makefile	Wed Jul 24 14:03:37 2002
+++ b/drivers/macintosh/Makefile	Wed Jul 24 14:03:37 2002
@@ -17,7 +17,9 @@
 
 obj-$(CONFIG_PMAC_PBOOK)	+= mediabay.o
 obj-$(CONFIG_MAC_SERIAL)	+= macserial.o
-obj-$(CONFIG_NVRAM)		+= nvram.o
+ifneq ($(CONFIG_MAC),y)
+  obj-$(CONFIG_NVRAM)		+= nvram.o
+endif
 obj-$(CONFIG_MAC_HID)		+= mac_hid.o
 obj-$(CONFIG_INPUT_ADBHID)	+= adbhid.o
 obj-$(CONFIG_PPC_RTC)		+= rtc.o
diff -Nru a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
--- a/drivers/macintosh/adb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/macintosh/adb.c	Wed Jul 24 14:03:38 2002
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/completion.h>
+#include <linux/tqueue.h>
 #include <asm/uaccess.h>
 #ifdef CONFIG_PPC
 #include <asm/prom.h>
@@ -64,7 +65,7 @@
 #ifdef CONFIG_ADB_IOP
 	&adb_iop_driver,
 #endif
-#ifdef CONFIG_ADB_PMU
+#if defined(CONFIG_ADB_PMU) || defined(CONFIG_ADB_PMU68K)
 	&via_pmu_driver,
 #endif
 #ifdef CONFIG_ADB_MACIO
@@ -311,9 +312,11 @@
 #ifdef CONFIG_PMAC_PBOOK
 		pmu_register_sleep_notifier(&adb_sleep_notifier);
 #endif /* CONFIG_PMAC_PBOOK */
+#ifdef CONFIG_PPC
 		if (machine_is_compatible("AAPL,PowerBook1998") ||
 			machine_is_compatible("PowerBook1,1"))
 			sleepy_trackpad = 1;
+#endif /* CONFIG_PPC */
 		init_completion(&adb_probe_task_comp);
 		adbdev_init();
 		adb_reset_bus();
diff -Nru a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
--- a/drivers/macintosh/adbhid.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/macintosh/adbhid.c	Wed Jul 24 14:03:38 2002
@@ -944,8 +944,10 @@
 
 static int __init adbhid_init(void)
 {
+#ifndef CONFIG_MAC
 	if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
 	    return 0;
+#endif
 
 	led_request.complete = 1;
 
diff -Nru a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
--- a/drivers/macintosh/via-cuda.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/macintosh/via-cuda.c	Wed Jul 24 14:03:36 2002
@@ -191,7 +191,9 @@
     if (via == NULL)
 	return -ENODEV;
 
+#ifdef CONFIG_PPC
     request_OF_resource(vias, 0, NULL);
+#endif
 
     if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
 	printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ);
@@ -224,12 +226,19 @@
 static int __init
 cuda_init(void)
 {
+#ifdef CONFIG_PPC
     if (via == NULL)
 	return -ENODEV;
-#ifndef CONFIG_PPC
+    return 0;
+#else 
+    int err = cuda_init_via();
+    if (err) {
+	printk(KERN_ERR "cuda_init_via() failed\n");
+	return -ENODEV;
+    }
+
     return via_cuda_start();
 #endif
-    return 0;
 }
 #endif /* CONFIG_ADB */
 
diff -Nru a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
--- a/drivers/macintosh/via-macii.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/macintosh/via-macii.c	Wed Jul 24 14:03:36 2002
@@ -10,6 +10,8 @@
  * Rewrite for Unified ADB by Joshua M. Thompson (funaho@jurai.org)
  *
  * 1999-08-02 (jmt) - Initial rewrite for Unified ADB.
+ * 2000-03-29 Tony Mantler <tonym@mac.linux-m68k.org>
+ * 				- Big overhaul, should actually work now.
  */
  
 #include <stdarg.h>
@@ -98,7 +100,6 @@
 
 static enum macii_state {
 	idle,
-	sent_first_byte,
 	sending,
 	reading,
 	read_done,
@@ -133,7 +134,7 @@
 
 	via = via1;
 
-	printk("adb: Mac II ADB Driver v0.4 for Unified ADB\n");
+	printk("adb: Mac II ADB Driver v1.0 for Unified ADB\n");
 	return 0;
 }
 
@@ -186,7 +187,7 @@
 	static int in_poll=0;
 	static struct adb_request req;
 	unsigned long flags;
-
+	
 	if (in_poll) printk("macii_queue_poll: double poll!\n");
 
 	in_poll++;
@@ -212,7 +213,7 @@
 	static int in_retransmit = 0;
 	static struct adb_request rt;
 	unsigned long flags;
-
+	
 	if (in_retransmit) printk("macii_retransmit: double retransmit!\n");
 
 	in_retransmit++;
@@ -256,11 +257,11 @@
 {
 	unsigned long flags;
 
-	if (req->nbytes < 2 || req->data[0] != ADB_PACKET) {
+	if (req->nbytes < 2 || req->data[0] != ADB_PACKET || req->nbytes > 15) {
 		req->complete = 1;
 		return -EINVAL;
 	}
-
+	
 	req->next = 0;
 	req->sent = 0;
 	req->complete = 0;
@@ -319,7 +320,7 @@
 
 	req = current_req;
 	if (!req) return;
-
+	
 	/* assert macii_state == idle */
 	if (macii_state != idle) {
 		printk("macii_start: called while driver busy (%p %x %x)!\n",
@@ -333,7 +334,9 @@
 	 * IRQ signaled ?? (means ADB controller wants to send, or might 
 	 * be end of packet if we were reading)
 	 */
+#if 0 /* FIXME: This is broke broke broke, for some reason */
 	if ((via[B] & TREQ) == 0) {
+		printk("macii_start: weird poll stuff. huh?\n");
 		/*
 		 *	FIXME - we need to restart this on a timer
 		 *	or a collision at boot hangs us.
@@ -359,6 +362,7 @@
 			need_poll = 0;
 		}
 	}
+#endif
 	/*
 	 * Another retry pending? (sanity check)
 	 */
@@ -368,7 +372,7 @@
 
 	/* Now send it. Be careful though, that first byte of the request */
 	/* is actually ADB_PACKET; the real data begins at index 1!	  */
-
+	
 	/* store command byte */
 	command_byte = req->data[1];
 	/* Output mode */
@@ -378,7 +382,7 @@
 	/* set ADB state to 'command' */
 	via[B] = (via[B] & ~ST_MASK) | ST_CMD;
 
-	macii_state = sent_first_byte;
+	macii_state = sending;
 	data_index = 2;
 
 	restore_flags(flags);
@@ -441,7 +445,7 @@
 			reply_len = 1;
 			prefix_len = 1;
 			reading_reply = 0;
-
+			
 			macii_state = reading;
 			break;
 
@@ -461,15 +465,14 @@
 			macii_state = reading;			
 			break;
 
-		case sent_first_byte:
+		case sending:
 			req = current_req;
-			/* maybe we're already done (Talk, or Poll)? */
 			if (data_index >= req->nbytes) {
-				/* reset to shift in */
-				/* If it's a Listen command and we're done, someone's doing weird stuff. */
+				/* print an error message if a listen command has no data */
 				if (((command_byte & 0x0C) == 0x08)
-				    && (console_loglevel == 10))
-					printk("macii_interrupt: listen command with no data: %x!\n", 
+				 /* && (console_loglevel == 10) */
+				    && (data_index == 2))
+					printk("MacII ADB: listen command with no data: %x!\n", 
 						command_byte);
 				/* reset to shift in */
 				via[ACR] &= ~SR_OUT;
@@ -492,42 +495,15 @@
 						macii_retransmit((command_byte & 0xF0) >> 4);
 				}
 			} else {
-				/* SR already set to shift out; send byte */
-				via[SR] = current_req->data[data_index++];
-				/* set state to ST_EVEN (first byte was: ST_CMD) */
-				via[B] = (via[B] & ~ST_MASK) | ST_EVEN;
-				macii_state = sending;
-			}
-			break;
-
-		case sending:
-			req = current_req;
-			if (data_index >= req->nbytes) {
-				/* reset to shift in */
-				via[ACR] &= ~SR_OUT;
-				x = via[SR];
-				/* set ADB state idle - might get SRQ */
-				via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
-
-				req->sent = 1;
+				via[SR] = req->data[data_index++];
 
-				if (req->reply_expected) {
-					macii_state = awaiting_reply;
+				if ( (via[B] & ST_MASK) == ST_CMD ) {
+					/* just sent the command byte, set to EVEN */
+					via[B] = (via[B] & ~ST_MASK) | ST_EVEN;
 				} else {
-					req->complete = 1;
-					current_req = req->next;
-					if (req->done) (*req->done)(req);
-					macii_state = idle;
-					if (current_req || retry_req)
-						macii_start();
-					else
-						macii_retransmit((command_byte & 0xF0) >> 4);
+					/* invert state bits, toggle ODD/EVEN */
+					via[B] ^= ST_MASK;
 				}
-			} else {
-				via[SR] = req->data[data_index++];
-
-				/* invert state bits, toggle ODD/EVEN */
-				via[B] ^= ST_MASK;
 			}
 			break;
 
@@ -551,7 +527,7 @@
 				 * on /INT, meaning we missed it :-(
 				 */
 				x = via[SR];
-				if (x != 0xFF) printk("macii_interrupt: mistaken timeout/SRQ!\n");
+				if (x != 0xFF) printk("MacII ADB: mistaken timeout/SRQ!\n");
 
 				if ((status & TREQ) == (last_status & TREQ)) {
 					/* Not a timeout. Unsolicited SRQ? weird. */
@@ -598,7 +574,7 @@
 			 * byte of timeout packet! 
 			 * Timeouts are signaled by 4x FF.
 			 */
-			if (!(status & TREQ) && (x == 0x00)) { /* != 0xFF */
+			if (((status & TREQ) == 0) && (x == 0x00)) { /* != 0xFF */
 				/* invert state bits, toggle ODD/EVEN */
 				via[B] ^= ST_MASK;
 
@@ -646,12 +622,12 @@
 				need_poll = 0;
 				break;
 			}
-
+			
+			/* set ADB state to idle */
+			via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
+			
 			/* /IRQ seen, so the ADB controller has data for us */
-			if (!(status & TREQ)) {
-				/* set ADB state to idle */
-				via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
-
+			if ((via[B] & TREQ) != 0) {
 				macii_state = reading;
 
 				reply_buf[0] = command_byte;
diff -Nru a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c
--- a/drivers/macintosh/via-maciisi.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/macintosh/via-maciisi.c	Wed Jul 24 14:03:39 2002
@@ -9,7 +9,11 @@
  *
  * Original sources (c) Alan Cox, Paul Mackerras, and others.
  *
- * Rewritten for Unified ADB by David Huggins-Daines <dhd@debian.org> */
+ * Rewritten for Unified ADB by David Huggins-Daines <dhd@debian.org>
+ * 
+ * 7/13/2000- extensive changes by Andrew McPherson <andrew@macduff.dhs.org>
+ * Works about 30% of the time now.
+ */
 
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -56,6 +60,8 @@
 
 #define ADB_DELAY 150
 
+#undef DEBUG_MACIISI_ADB
+
 static struct adb_request* current_req = NULL;
 static struct adb_request* last_req = NULL;
 static unsigned char maciisi_rbuf[16];
@@ -63,6 +69,8 @@
 static int data_index;
 static int reading_reply;
 static int reply_len;
+static int tmp;
+static int need_sync;
 
 static enum maciisi_state {
     idle,
@@ -73,12 +81,13 @@
 static int maciisi_probe(void);
 static int maciisi_init(void);
 static int maciisi_send_request(struct adb_request* req, int sync);
+static void maciisi_sync(struct adb_request *req);
 static int maciisi_write(struct adb_request* req);
 static void maciisi_interrupt(int irq, void* arg, struct pt_regs* regs);
 static void maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs);
 static int maciisi_init_via(void);
 static void maciisi_poll(void);
-static void maciisi_start(void);
+static int maciisi_start(void);
 
 struct adb_driver via_maciisi_driver = {
 	"Mac IIsi",
@@ -114,63 +123,105 @@
 		return err;
 	}
 
-	if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK, 
+	if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST, 
 			"ADB", maciisi_interrupt)) {
 		printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB);
 		return -EAGAIN;
 	}
 
-	printk("adb: Mac IIsi driver v0.1 for Unified ADB.\n");
+	printk("adb: Mac IIsi driver v0.2 for Unified ADB.\n");
 	return 0;
 }
 
+/* Flush data from the ADB controller */
 static void
 maciisi_stfu(void)
 {
 	int status = via[B] & (TIP|TREQ);
 
 	if (status & TREQ) {
+#ifdef DEBUG_MACIISI_ADB
 		printk (KERN_DEBUG "maciisi_stfu called with TREQ high!\n");
+#endif
 		return;
 	}
+	
+	udelay(ADB_DELAY);
+	via[ACR] &= ~SR_OUT;
+	via[IER] = IER_CLR | SR_INT;
 
-	/* start transfer */
-	via[B] |= TIP;
-	while (!(status & TREQ)) {
-		int poll_timeout = ADB_DELAY * 5;
-		/* Poll for SR interrupt */
-		while (!(via[IFR] & SR_INT) && poll_timeout-- > 0)
-			status = via[B] & (TIP|TREQ);
-		via[SR]; /* Clear shift register */
-		printk(KERN_DEBUG "maciisi_stfu: status %x timeout %d\n",
-		       status, poll_timeout);
-		
-		/* ACK on-off */
-		via[B] |= TACK;
+	udelay(ADB_DELAY);
+
+	status = via[B] & (TIP|TREQ);
+
+	if (!(status & TREQ))
+	{
+		via[B] |= TIP;
+
+		while(1)
+		{
+			int poll_timeout = ADB_DELAY * 5;
+			/* Poll for SR interrupt */
+			while (!(via[IFR] & SR_INT) && poll_timeout-- > 0)
+				status = via[B] & (TIP|TREQ);
+
+			tmp = via[SR]; /* Clear shift register */
+#ifdef DEBUG_MACIISI_ADB
+			printk(KERN_DEBUG "maciisi_stfu: status %x timeout %d data %x\n",
+			       status, poll_timeout, tmp);
+#endif	
+			if(via[B] & TREQ)
+				break;
+	
+			/* ACK on-off */
+			via[B] |= TACK;
+			udelay(ADB_DELAY);
+			via[B] &= ~TACK;
+		}
+
+		/* end frame */
+		via[B] &= ~TIP;
 		udelay(ADB_DELAY);
-		via[B] &= ~TACK;
 	}
-	/* end frame */
-	via[B] &= ~TIP;
+
+	via[IER] = IER_SET | SR_INT;	
 }
 
 /* All specifically VIA-related initialization goes here */
 static int
 maciisi_init_via(void)
 {
+	int	i;
+	
 	/* Set the lines up. We want TREQ as input TACK|TIP as output */
 	via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;
 	/* Shift register on input */
 	via[ACR]  = (via[ACR] & ~SR_CTRL) | SR_EXT;
+#ifdef DEBUG_MACIISI_ADB
 	printk(KERN_DEBUG "maciisi_init_via: initial status %x\n", via[B] & (TIP|TREQ));
+#endif
+	/* Wipe any pending data and int */
+	tmp = via[SR];
+	/* Enable keyboard interrupts */
+	via[IER] = IER_SET | SR_INT;
 	/* Set initial state: idle */
 	via[B] &= ~(TACK|TIP);
-	/* Wipe any pending data and int */
-	via[SR];
-	if (!(via[B] & TREQ))
+	/* Clear interrupt bit */
+	via[IFR] = SR_INT;
+
+	for(i = 0; i < 60; i++) {
+		udelay(ADB_DELAY);
 		maciisi_stfu();
-	via[IER] = IER_SET | SR_INT;
+		udelay(ADB_DELAY);
+		if(via[B] & TREQ)
+			break;
+	}
+	if (i == 60)
+		printk(KERN_ERR "maciisi_init_via: bus jam?\n");
+
 	maciisi_state = idle;
+	need_sync = 0;
+
 	return 0;
 }
 
@@ -179,41 +230,76 @@
 maciisi_send_request(struct adb_request* req, int sync)
 {
 	int i;
-	static int dump_packet = 1;
+
+#ifdef DEBUG_MACIISI_ADB
+	static int dump_packet = 0;
+#endif
 
 	if (via == NULL) {
 		req->complete = 1;
 		return -ENXIO;
 	}
 
+#ifdef DEBUG_MACIISI_ADB
 	if (dump_packet) {
 		printk(KERN_DEBUG "maciisi_send_request:");
 		for (i = 0; i < req->nbytes; i++) {
 			printk(" %.2x", req->data[i]);
 		}
-		printk("\n");
+		printk(" sync %d\n", sync);
 	}
+#endif
+
 	req->reply_expected = 1;
 	
 	i = maciisi_write(req);
 	if (i)
+	{
+		/* Normally, if a packet requires syncing, that happens at the end of
+		 * maciisi_send_request. But if the transfer fails, it will be restarted
+		 * by maciisi_interrupt(). We use need_sync to tell maciisi_interrupt
+		 * when to sync a packet that it sends out.
+		 * 
+		 * Suggestions on a better way to do this are welcome.
+		 */
+		if(i == -EBUSY && sync)
+			need_sync = 1;
+		else
+			need_sync = 0;
 		return i;
-	
-	if (sync) {
-		while (!req->complete) {
-			maciisi_poll();
-		}
 	}
+	if(sync)
+		maciisi_sync(req);
+	
 	return 0;
 }
 
+/* Poll the ADB chip until the request completes */
+static void maciisi_sync(struct adb_request *req)
+{
+	int count = 0; 
+
+#ifdef DEBUG_MACIISI_ADB
+	printk(KERN_DEBUG "maciisi_sync called\n");
+#endif
+
+	/* If for some reason the ADB chip shuts up on us, we want to avoid an endless loop. */
+	while (!req->complete && count++ < 50) {
+		maciisi_poll();
+	}
+	/* This could be BAD... when the ADB controller doesn't respond
+	 * for this long, it's probably not coming back :-( */
+	if(count >= 50) /* Hopefully shouldn't happen */
+		printk(KERN_ERR "maciisi_send_request: poll timed out!\n");
+}
+
 /* Enqueue a request, and run the queue if possible */
 static int
 maciisi_write(struct adb_request* req)
 {
 	unsigned long flags;
+	int i;
 
-  	printk(KERN_DEBUG "maciisi_write called, state=%d ifr=%x\n", maciisi_state, via[IFR]);
 	/* We will accept CUDA packets - the VIA sends them to us, so
            it figures that we should be able to send them to it */
 	if (req->nbytes < 2 || req->data[0] > CUDA_PACKET) {
@@ -225,7 +311,9 @@
 	req->sent = 0;
 	req->complete = 0;
 	req->reply_len = 0;
-	save_flags(flags); cli();
+	
+	save_flags(flags);
+	cli();
 
 	if (current_req) {
 		last_req->next = req;
@@ -235,44 +323,68 @@
 		last_req = req;
 	}
 	if (maciisi_state == idle)
-		maciisi_start();
+	{
+		i = maciisi_start();
+		if(i != 0)
+		{
+			restore_flags(flags);
+			return i;
+		}
+	}
 	else
+	{
+#ifdef DEBUG_MACIISI_ADB
 		printk(KERN_DEBUG "maciisi_write: would start, but state is %d\n", maciisi_state);
+#endif
+		restore_flags(flags);
+		return -EBUSY;
+	}
 
 	restore_flags(flags);
+
 	return 0;
 }
 
-static void
+static int
 maciisi_start(void)
 {
 	struct adb_request* req;
 	int status;
 
-	printk(KERN_DEBUG "maciisi_start called, state=%d, ifr=%x\n", maciisi_state, via[IFR]);
+#ifdef DEBUG_MACIISI_ADB
+	status = via[B] & (TIP | TREQ);
+
+	printk(KERN_DEBUG "maciisi_start called, state=%d, status=%x, ifr=%x\n", maciisi_state, status, via[IFR]);
+#endif
+
 	if (maciisi_state != idle) {
 		/* shouldn't happen */
 		printk(KERN_ERR "maciisi_start: maciisi_start called when driver busy!\n");
-		return;
+		return -EBUSY;
 	}
 
 	req = current_req;
 	if (req == NULL)
-		return;
+		return -EINVAL;
 
 	status = via[B] & (TIP|TREQ);
 	if (!(status & TREQ)) {
-		/* Bus is busy, set up for reading */
+#ifdef DEBUG_MACIISI_ADB
 		printk(KERN_DEBUG "maciisi_start: bus busy - aborting\n");
-		return;
+#endif
+		return -EBUSY;
 	}
 
 	/* Okay, send */
+#ifdef DEBUG_MACIISI_ADB
 	printk(KERN_DEBUG "maciisi_start: sending\n");
+#endif
 	/* Set state to active */
 	via[B] |= TIP;
 	/* ACK off */
 	via[B] &= ~TACK;
+	/* Delay */
+	udelay(ADB_DELAY);
 	/* Shift out and send */
 	via[ACR] |= SR_OUT;
 	via[SR] = req->data[0];
@@ -280,6 +392,8 @@
 	/* ACK on */
 	via[B] |= TACK;
 	maciisi_state = sending;
+
+	return 0;
 }
 
 void
@@ -292,6 +406,9 @@
 	if (via[IFR] & SR_INT) {
 		maciisi_interrupt(0, 0, 0);
 	}
+	else /* avoid calling this function too quickly in a loop */
+		udelay(ADB_DELAY);
+
 	restore_flags(flags);
 }
 
@@ -303,31 +420,44 @@
 {
 	int status;
 	struct adb_request *req;
-	static int dump_reply = 1;
+#ifdef DEBUG_MACIISI_ADB
+	static int dump_reply = 0;
+#endif
+	int i;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	status = via[B] & (TIP|TREQ);
+#ifdef DEBUG_MACIISI_ADB
+	printk(KERN_DEBUG "state %d status %x ifr %x\n", maciisi_state, status, via[IFR]);
+#endif
 
 	if (!(via[IFR] & SR_INT)) {
 		/* Shouldn't happen, we hope */
-		printk(KERN_DEBUG "maciisi_interrupt: called without interrupt flag set\n");
+		printk(KERN_ERR "maciisi_interrupt: called without interrupt flag set\n");
+		restore_flags(flags);
 		return;
 	}
 
-	status = via[B] & (TIP|TREQ);
-	printk(KERN_DEBUG "state %d status %x ifr %x\n", maciisi_state, status, via[IFR]);
+	/* Clear the interrupt */
+	/* via[IFR] = SR_INT; */
 
  switch_start:
 	switch (maciisi_state) {
 	case idle:
-		printk(KERN_DEBUG "maciisi_interrupt: state=idle, status %x\n", status);
 		if (status & TIP)
-			printk(KERN_DEBUG "maciisi_interrupt: state is idle but TIP asserted!\n");
+			printk(KERN_ERR "maciisi_interrupt: state is idle but TIP asserted!\n");
 
-		udelay(ADB_DELAY);
+		if(!reading_reply)
+			udelay(ADB_DELAY);
 		/* Shift in */
 		via[ACR] &= ~SR_OUT;
  		/* Signal start of frame */
 		via[B] |= TIP;
 		/* Clear the interrupt (throw this value on the floor, it's useless) */
-		via[SR];
+		tmp = via[SR];
 		/* ACK adb chip, high-low */
 		via[B] |= TACK;
 		udelay(ADB_DELAY);
@@ -337,37 +467,39 @@
 		if (reading_reply) {
 			reply_ptr = current_req->reply;
 		} else {
-			printk(KERN_DEBUG "maciisi_interrupt: received unsolicited packet\n");
 			reply_ptr = maciisi_rbuf;
 		}
 		break;
 
 	case sending:
-		printk(KERN_DEBUG "maciisi_interrupt: state=sending, status=%x\n", status);
-		/* Clear interrupt */
-		via[SR];
+		/* via[SR]; */
 		/* Set ACK off */
 		via[B] &= ~TACK;
 		req = current_req;
 
 		if (!(status & TREQ)) {
 			/* collision */
-			printk(KERN_DEBUG "maciisi_interrupt: send collision\n");
+			printk(KERN_ERR "maciisi_interrupt: send collision\n");
 			/* Set idle and input */
-			via[B] &= ~TIP;
 			via[ACR] &= ~SR_OUT;
+			tmp = via[SR];
+			via[B] &= ~TIP;
 			/* Must re-send */
 			reading_reply = 0;
 			reply_len = 0;
 			maciisi_state = idle;
+			udelay(ADB_DELAY);
 			/* process this now, because the IFR has been cleared */
 			goto switch_start;
 		}
 
+		udelay(ADB_DELAY);
+
 		if (data_index >= req->nbytes) {
 			/* Sent the whole packet, put the bus back in idle state */
 			/* Shift in, we are about to read a reply (hopefully) */
 			via[ACR] &= ~SR_OUT;
+			tmp = via[SR];
 			/* End of frame */
 			via[B] &= ~TIP;
 			req->sent = 1;
@@ -380,13 +512,19 @@
 				current_req = req->next;
 				if (req->done)
 					(*req->done)(req);
+				/* Do any queued requests now */
+				i = maciisi_start();
+				if(i == 0 && need_sync) {
+					/* Packet needs to be synced */
+					maciisi_sync(current_req);
+				}
+				if(i != -EBUSY)
+					need_sync = 0;
 			}
 		} else {
 			/* Sending more stuff */
 			/* Shift out */
 			via[ACR] |= SR_OUT;
-			/* Delay */
-			udelay(ADB_DELAY);
 			/* Write */
 			via[SR] = req->data[data_index++];
 			/* Signal 'byte ready' */
@@ -395,18 +533,24 @@
 		break;
 
 	case reading:
-		printk(KERN_DEBUG "maciisi_interrupt: state=reading, status=%x\n", status);
 		/* Shift in */
-		via[ACR] &= ~SR_OUT;
+		/* via[ACR] &= ~SR_OUT; */ /* Not in 2.2 */
 		if (reply_len++ > 16) {
 			printk(KERN_ERR "maciisi_interrupt: reply too long, aborting read\n");
 			via[B] |= TACK;
 			udelay(ADB_DELAY);
 			via[B] &= ~(TACK|TIP);
 			maciisi_state = idle;
-			maciisi_start();
+			i = maciisi_start();
+			if(i == 0 && need_sync) {
+				/* Packet needs to be synced */
+				maciisi_sync(current_req);
+			}
+			if(i != -EBUSY)
+				need_sync = 0;
 			break;
 		}
+		/* Read data */
 		*reply_ptr++ = via[SR];
 		status = via[B] & (TIP|TREQ);
 		/* ACK on/off */
@@ -418,6 +562,8 @@
 		
 		/* end of frame */
 		via[B] &= ~TIP;
+		tmp = via[SR]; /* That's what happens in 2.2 */
+		udelay(ADB_DELAY); /* Give controller time to recover */
 
 		/* end of packet, deal with it */
 		if (reading_reply) {
@@ -434,6 +580,7 @@
 					memmove(req->reply, req->reply + 2, req->reply_len);
 				}
 			}
+#ifdef DEBUG_MACIISI_ADB
 			if (dump_reply) {
 				int i;
 				printk(KERN_DEBUG "maciisi_interrupt: reply is ");
@@ -441,6 +588,7 @@
 					printk(" %.2x", req->reply[i]);
 				printk("\n");
 			}
+#endif
 			req->complete = 1;
 			current_req = req->next;
 			if (req->done)
@@ -453,34 +601,62 @@
 		maciisi_state = idle;
 		status = via[B] & (TIP|TREQ);
 		if (!(status & TREQ)) {
-			/* Timeout?! */
+			/* Timeout?! More likely, another packet coming in already */
+#ifdef DEBUG_MACIISI_ADB
 			printk(KERN_DEBUG "extra data after packet: status %x ifr %x\n",
 			       status, via[IFR]);
-			maciisi_stfu();
+#endif
+#if 0
+			udelay(ADB_DELAY);
+			via[B] |= TIP;
+
+			maciisi_state = reading;
+			reading_reply = 0;
+			reply_ptr = maciisi_rbuf;
+#else
+			/* Process the packet now */
+			reading_reply = 0;
+			goto switch_start;
+#endif
+			/* We used to do this... but the controller might actually have data for us */
+			/* maciisi_stfu(); */
+		}
+		else {
+			/* Do any queued requests now if possible */
+			i = maciisi_start();
+			if(i == 0 && need_sync) {
+				/* Packet needs to be synced */
+				maciisi_sync(current_req);
+			}
+			if(i != -EBUSY)
+				need_sync = 0;
 		}
-		/* Do any queued requests now if possible */
-		maciisi_start();
 		break;
 
 	default:
 		printk("maciisi_interrupt: unknown maciisi_state %d?\n", maciisi_state);
 	}
+	restore_flags(flags);
 }
 
 static void
 maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs)
 {
+#ifdef DEBUG_MACIISI_ADB
     int i;
+#endif
 
     switch (buf[0]) {
     case ADB_PACKET:
 	    adb_input(buf+2, nb-2, regs, buf[1] & 0x40);
 	    break;
     default:
+#ifdef DEBUG_MACIISI_ADB
 	    printk(KERN_DEBUG "data from IIsi ADB (%d bytes):", nb);
 	    for (i = 0; i < nb; ++i)
 		    printk(" %.2x", buf[i]);
 	    printk("\n");
-
+#endif
+	    break;
     }
 }
diff -Nru a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
--- a/drivers/macintosh/via-pmu68k.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/macintosh/via-pmu68k.c	Wed Jul 24 14:03:36 2002
@@ -120,6 +120,8 @@
 static void pmu_handle_data(unsigned char *data, int len,
 			    struct pt_regs *regs);
 static void set_volume(int level);
+static void pmu_enable_backlight(int on);
+static void pmu_set_brightness(int level);
 
 struct adb_driver via_pmu_driver = {
 	"68K PMU",
@@ -746,7 +748,7 @@
 
 #define LEVEL_TO_BRIGHT(lev)	((lev) < 1? 0x7f: 0x4a - ((lev) << 1))
 
-void 
+static void 
 pmu_enable_backlight(int on)
 {
 	struct adb_request req;
@@ -780,7 +782,7 @@
 	backlight_enabled = on;
 }
 
-void 
+static void 
 pmu_set_brightness(int level)
 {
 	int bright;
diff -Nru a/drivers/md/linear.c b/drivers/md/linear.c
--- a/drivers/md/linear.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/md/linear.c	Wed Jul 24 14:03:37 2002
@@ -193,11 +193,11 @@
 
 static mdk_personality_t linear_personality=
 {
-	name:		"linear",
-	make_request:	linear_make_request,
-	run:		linear_run,
-	stop:		linear_stop,
-	status:		linear_status,
+	.name		= "linear",
+	.make_request	= linear_make_request,
+	.run		= linear_run,
+	.stop		= linear_stop,
+	.status		= linear_status,
 };
 
 static int __init linear_init (void)
diff -Nru a/drivers/md/lvm.c b/drivers/md/lvm.c
--- a/drivers/md/lvm.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/md/lvm.c	Wed Jul 24 14:03:38 2002
@@ -872,17 +872,6 @@
 			return -EFAULT;
 		break;
 
-
-	case BLKFLSBUF:
-		/* flush buffer cache */
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-
-		P_IOCTL("BLKFLSBUF\n");
-
-		fsync_bdev(inode->i_bdev);
-		invalidate_buffers(inode->i_rdev);
-		break;
-
 	case HDIO_GETGEO:
 		/* get disk geometry */
 		P_IOCTL("%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name);
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/md/md.c	Wed Jul 24 14:03:37 2002
@@ -118,14 +118,14 @@
 
 static struct gendisk md_gendisk=
 {
-	major: MD_MAJOR,
-	major_name: "md",
-	minor_shift: 0,
-	part: md_hd_struct,
-	sizes: md_size,
-	nr_real: MAX_MD_DEVS,
-	next: NULL,
-	fops: &md_fops,
+	.major		= MD_MAJOR,
+	.major_name	= "md",
+	.minor_shift	= 0,
+	.part		= md_hd_struct,
+	.sizes		= md_size,
+	.nr_real	= MAX_MD_DEVS,
+	.next		= NULL,
+	.fops		= &md_fops,
 };
 
 /*
@@ -847,7 +847,7 @@
 		MD_BUG();
 		return;
 	}
-	rdev = list_entry(&mddev->disks.next, mdk_rdev_t, same_set);
+	rdev = list_entry(mddev->disks.next, mdk_rdev_t, same_set);
 	sb = rdev->sb;
 
 	memset(sb, 0, sizeof(*sb));
@@ -1044,8 +1044,6 @@
 	}
 	INIT_LIST_HEAD(&rdev->same_set);
 
-	if (rdev->faulty && rdev->sb)
-		free_disk_sb(rdev);
 	return rdev;
 
 abort_free:
@@ -2241,28 +2239,6 @@
 			autostart_arrays();
 			goto done;
 #endif
-
-		case BLKGETSIZE:	/* Return device size */
-			if (!arg) {
-				err = -EINVAL;
-				MD_BUG();
-				goto abort;
-			}
-			err = put_user(md_hd_struct[minor].nr_sects,
-						(unsigned long *) arg);
-			goto done;
-
-		case BLKGETSIZE64:	/* Return device size */
-			err = put_user((u64)md_hd_struct[minor].nr_sects << 9,
-						(u64 *) arg);
-			goto done;
-
-		case BLKFLSBUF:
-		case BLKBSZGET:
-		case BLKBSZSET:
-			err = blk_ioctl(inode->i_bdev, cmd, arg);
-			goto abort;
-
 		default:;
 	}
 
@@ -2386,7 +2362,7 @@
 						(short *) &loc->cylinders);
 			if (err)
 				goto abort_unlock;
-			err = put_user (get_start_sect(dev),
+			err = put_user (get_start_sect(inode->i_bdev),
 						(long *) &loc->start);
 			goto done_unlock;
 	}
@@ -2498,10 +2474,10 @@
 
 static struct block_device_operations md_fops =
 {
-	owner:		THIS_MODULE,
-	open:		md_open,
-	release:	md_release,
-	ioctl:		md_ioctl,
+	.owner		= THIS_MODULE,
+	.open		= md_open,
+	.release	= md_release,
+	.ioctl		= md_ioctl,
 };
 
 
@@ -3189,9 +3165,9 @@
 }
 
 struct notifier_block md_notifier = {
-	notifier_call:	md_notify_reboot,
-	next:		NULL,
-	priority:	INT_MAX, /* before any real devices */
+	.notifier_call	= md_notify_reboot,
+	.next		= NULL,
+	.priority	= INT_MAX, /* before any real devices */
 };
 
 static void md_geninit(void)
diff -Nru a/drivers/md/multipath.c b/drivers/md/multipath.c
--- a/drivers/md/multipath.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/md/multipath.c	Wed Jul 24 14:03:38 2002
@@ -562,14 +562,14 @@
 
 static mdk_personality_t multipath_personality=
 {
-	name:		"multipath",
-	make_request:	multipath_make_request,
-	run:		multipath_run,
-	stop:		multipath_stop,
-	status:		multipath_status,
-	error_handler:	multipath_error,
-	hot_add_disk:	multipath_add_disk,
-	hot_remove_disk:multipath_remove_disk,
+	.name		= "multipath",
+	.make_request	= multipath_make_request,
+	.run		= multipath_run,
+	.stop		= multipath_stop,
+	.status		= multipath_status,
+	.error_handler	= multipath_error,
+	.hot_add_disk	= multipath_add_disk,
+	.hot_remove_disk= multipath_remove_disk,
 };
 
 static int __init multipath_init (void)
diff -Nru a/drivers/md/raid0.c b/drivers/md/raid0.c
--- a/drivers/md/raid0.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/md/raid0.c	Wed Jul 24 14:03:38 2002
@@ -366,11 +366,11 @@
 
 static mdk_personality_t raid0_personality=
 {
-	name:		"raid0",
-	make_request:	raid0_make_request,
-	run:		raid0_run,
-	stop:		raid0_stop,
-	status:		raid0_status,
+	.name		= "raid0",
+	.make_request	= raid0_make_request,
+	.run		= raid0_run,
+	.stop		= raid0_stop,
+	.status		= raid0_status,
 };
 
 static int __init raid0_init (void)
diff -Nru a/drivers/md/raid1.c b/drivers/md/raid1.c
--- a/drivers/md/raid1.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/md/raid1.c	Wed Jul 24 14:03:35 2002
@@ -1346,18 +1346,18 @@
 
 static mdk_personality_t raid1_personality =
 {
-	name:		"raid1",
-	make_request:	make_request,
-	run:		run,
-	stop:		stop,
-	status:		status,
-	error_handler:	error,
-	hot_add_disk:	raid1_add_disk,
-	hot_remove_disk:raid1_remove_disk,
-	spare_write:	raid1_spare_write,
-	spare_inactive:	raid1_spare_inactive,
-	spare_active:	raid1_spare_active,
-	sync_request:	sync_request
+	.name		= "raid1",
+	.make_request	= make_request,
+	.run		= run,
+	.stop		= stop,
+	.status		= status,
+	.error_handler	= error,
+	.hot_add_disk	= raid1_add_disk,
+	.hot_remove_disk= raid1_remove_disk,
+	.spare_write	= raid1_spare_write,
+	.spare_inactive	= raid1_spare_inactive,
+	.spare_active	= raid1_spare_active,
+	.sync_request	= sync_request,
 };
 
 static int __init raid_init(void)
diff -Nru a/drivers/md/raid5.c b/drivers/md/raid5.c
--- a/drivers/md/raid5.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/md/raid5.c	Wed Jul 24 14:03:36 2002
@@ -1820,18 +1820,18 @@
 
 static mdk_personality_t raid5_personality=
 {
-	name:		"raid5",
-	make_request:	make_request,
-	run:		run,
-	stop:		stop,
-	status:		status,
-	error_handler:	error,
-	hot_add_disk:	raid5_add_disk,
-	hot_remove_disk:raid5_remove_disk,
-	spare_write:	raid5_spare_write,
-	spare_inactive:	raid5_spare_inactive,
-	spare_active:	raid5_spare_active,
-	sync_request:	sync_request
+	.name		= "raid5",
+	.make_request	= make_request,
+	.run		= run,
+	.stop		= stop,
+	.status		= status,
+	.error_handler	= error,
+	.hot_add_disk	= raid5_add_disk,
+	.hot_remove_disk= raid5_remove_disk,
+	.spare_write	= raid5_spare_write,
+	.spare_inactive	= raid5_spare_inactive,
+	.spare_active	= raid5_spare_active,
+	.sync_request	= sync_request,
 };
 
 static int __init raid5_init (void)
diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
--- a/drivers/message/fusion/mptscsih.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/message/fusion/mptscsih.c	Wed Jul 24 14:03:37 2002
@@ -3576,7 +3576,7 @@
  */
 
 int
-mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip)
+mptscsih_bios_param(Disk * disk, struct block_device *dev, int *ip)
 {
 	int size;
 
diff -Nru a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
--- a/drivers/message/fusion/mptscsih.h	Wed Jul 24 14:03:39 2002
+++ b/drivers/message/fusion/mptscsih.h	Wed Jul 24 14:03:39 2002
@@ -201,7 +201,7 @@
 extern	int		 x_scsi_old_abort(Scsi_Cmnd *);
 extern	int		 x_scsi_old_reset(Scsi_Cmnd *, unsigned int);
 #endif
-extern	int		 x_scsi_bios_param(Disk *, kdev_t, int *);
+extern	int		 x_scsi_bios_param(Disk *, struct block_device *, int *);
 extern	void		 x_scsi_select_queue_depths(struct Scsi_Host *, Scsi_Device *);
 extern	void		 x_scsi_taskmgmt_bh(void *);
 
diff -Nru a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
--- a/drivers/message/i2o/i2o_block.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/message/i2o/i2o_block.c	Wed Jul 24 14:03:39 2002
@@ -1050,13 +1050,7 @@
 		return -EBUSY;
 	}
 	
-	for( i = 15; i>=0 ; i--)
-	{
-		int m = minor+i;
-		invalidate_device(mk_kdev(MAJOR_NR, m), 1);
-		i2ob_gendisk.part[m].start_sect = 0;
-		i2ob_gendisk.part[m].nr_sects = 0;
-	}
+	wipe_partitions(mk_kdev(MAJOR_NR, minor), 1);
 
 	/*
 	 *	Do a physical check and then reconfigure
@@ -1089,7 +1083,7 @@
 			int u = minor(inode->i_rdev) & 0xF0;
 			i2o_block_biosparam(i2ob_sizes[u]<<1, 
 				&g.cylinders, &g.heads, &g.sectors);
-			g.start = get_start_sect(inode->i_rdev);
+			g.start = get_start_sect(inode->i_bdev);
 			return copy_to_user((void *)arg, &g, sizeof(g))
 				? -EFAULT : 0;
 		}
@@ -1099,14 +1093,6 @@
 				return -EACCES;
 			return do_i2ob_revalidate(inode->i_rdev,1);
 			
-		case BLKGETSIZE:
-		case BLKGETSIZE64:
-		case BLKFLSBUF:
-		case BLKROSET:
-		case BLKROGET:
-		case BLKPG:
-			return blk_ioctl(inode->i_bdev, cmd, arg);
-			
 		default:
 			return -EINVAL;
 	}
@@ -1815,7 +1801,6 @@
 	 *	Now fill in the boiler plate
 	 */
 	 
-	blk_size[MAJOR_NR] = i2ob_sizes;
 	blk_dev[MAJOR_NR].queue = i2ob_get_queue;
 	
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), i2ob_request);
diff -Nru a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
--- a/drivers/message/i2o/i2o_scsi.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/message/i2o/i2o_scsi.c	Wed Jul 24 14:03:36 2002
@@ -902,7 +902,7 @@
  *	This is anyones guess quite frankly.
  */
  
-int i2o_scsi_bios_param(Disk * disk, kdev_t dev, int *ip)
+int i2o_scsi_bios_param(Disk * disk, struct block_device *dev, int *ip)
 {
 	int size;
 
diff -Nru a/drivers/message/i2o/i2o_scsi.h b/drivers/message/i2o/i2o_scsi.h
--- a/drivers/message/i2o/i2o_scsi.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/message/i2o/i2o_scsi.h	Wed Jul 24 14:03:38 2002
@@ -20,7 +20,7 @@
 extern int i2o_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int i2o_scsi_abort(Scsi_Cmnd *);
 extern int i2o_scsi_reset(Scsi_Cmnd *, unsigned int);
-extern int i2o_scsi_bios_param(Disk *, kdev_t, int *);
+extern int i2o_scsi_bios_param(Disk *, struct block_device *, int *);
 extern void i2o_scsi_setup(char *str, int *ints);
 extern int i2o_scsi_release(struct Scsi_Host *host);
 
diff -Nru a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
--- a/drivers/mtd/ftl.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/mtd/ftl.c	Wed Jul 24 14:03:37 2002
@@ -880,9 +880,6 @@
     
     DEBUG(0, "ftl_cs: ftl_close(%d)\n", minor);
 
-    /* Flush all writes */
-    invalidate_device(inode->i_rdev, 1);
-
     /* Wait for any pending erase operations to complete */
     if (part->mtd->sync)
 	    part->mtd->sync(part->mtd);
@@ -1126,22 +1123,11 @@
 	put_user(1, (char *)&geo->heads);
 	put_user(8, (char *)&geo->sectors);
 	put_user((sect>>3), (short *)&geo->cylinders);
-	put_user(get_start_sect(inode->i_rdev), (u_long *)&geo->start);
-	break;
-    case BLKGETSIZE:
-	ret = put_user(ftl_hd[minor].nr_sects, (unsigned long *)arg);
-	break;
-    case BLKGETSIZE64:
-	ret = put_user((u64)ftl_hd[minor].nr_sects << 9, (u64 *)arg);
+	put_user(get_start_sect(inode->i_bdev), (u_long *)&geo->start);
 	break;
     case BLKRRPART:
 	ret = ftl_reread_partitions(inode->i_rdev);
 	break;
-    case BLKROSET:
-    case BLKROGET:
-    case BLKFLSBUF:
-	ret = blk_ioctl(inode->i_bdev, cmd, arg);
-	break;
     default:
 	ret = -EINVAL;
     }
@@ -1157,25 +1143,20 @@
 
 static int ftl_reread_partitions(kdev_t dev)
 {
-    int minor = minor(dev);
-    partition_t *part = myparts[minor >> 4];
-    int res;
-
-    DEBUG(0, "ftl_cs: ftl_reread_partition(%d)\n", minor);
-    if ((atomic_read(&part->open) > 1)) {
-	    return -EBUSY;
-    }
-
-    res = wipe_partitions(dev);
-    if (res)
-	goto leave;
-
-    scan_header(part);
-
-    register_disk(&ftl_gendisk, whole >> PART_BITS, MAX_PART,
-		  &ftl_blk_fops, le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
-
-    return res;
+	int minor = minor(dev);
+	partition_t *part = myparts[minor >> 4];
+	kdev_t device = mk_kdev(MAJOR_NR, minor & ~15);
+	int res = dev_lock_part(device);
+	if (rec < 0)
+		return res;
+	res = wipe_partitions(device);
+	if (!res) {
+		scan_header(part);
+		grok_partitions(device,
+			le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
+	}
+	dev_unlock_part(device);
+	return res;
 }
 
 /*======================================================================
@@ -1285,13 +1266,13 @@
 
 	partition->mtd = mtd;
 
-	if ((scan_header(partition) == 0) && 
-	    (build_maps(partition) == 0)) {
-		
+	if ((scan_header(partition) == 0) && (build_maps(partition) == 0)) {
 		partition->state = FTL_FORMATTED;
 		atomic_set(&partition->open, 0);
 		myparts[device] = partition;
-		ftl_reread_partitions(device << 4);
+		register_disk(&ftl_gendisk, mk_kdev(MAJOR_NR, device << 4),
+			      MAX_PART, &ftl_blk_fops,
+			      le32_to_cpu(partition->header.FormattedSize)/SECTOR_SIZE);
 #ifdef PCMCIA_DEBUG
 		printk(KERN_INFO "ftl_cs: opening %d kb FTL partition\n",
 		       le32_to_cpu(partition->header.FormattedSize) >> 10);
diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
--- a/drivers/mtd/mtdblock.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/mtd/mtdblock.c	Wed Jul 24 14:03:37 2002
@@ -354,8 +354,6 @@
 	if (inode == NULL)
 		release_return(-ENODEV);
 
-	invalidate_device(inode->i_rdev, 1);
-
 	dev = minor(inode->i_rdev);
 	mtdblk = mtdblks[dev];
 
diff -Nru a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
--- a/drivers/mtd/mtdblock_ro.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/mtd/mtdblock_ro.c	Wed Jul 24 14:03:38 2002
@@ -76,8 +76,6 @@
 	if (inode == NULL)
 		release_return(-ENODEV);
    
-	invalidate_device(inode->i_rdev, 1);
-
 	dev = minor(inode->i_rdev);
 	mtd = __get_mtd_device(NULL, dev);
 
diff -Nru a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
--- a/drivers/mtd/nftlcore.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/mtd/nftlcore.c	Wed Jul 24 14:03:35 2002
@@ -115,7 +115,6 @@
 #endif
 
         /* linux stuff */
-	nftl->usecount = 0;
 	nftl->cylinders = 1024;
 	nftl->heads = 16;
 
@@ -153,8 +152,9 @@
 #if LINUX_VERSION_CODE < 0x20328
 	resetup_one_dev(&nftl_gendisk, firstfree);
 #else
-	grok_partitions(mk_kdev(MAJOR_NR,firstfree<<NFTL_PARTN_BITS),
-			nftl->nr_sects);
+	register_disk(&nftl_gendisk,
+		      mk_kdev(MAJOR_NR,firstfree<<NFTL_PARTN_BITS),
+		      1<<NFTL_PARTN_BITS, &nftl_fops, nftl->nr_sects);
 #endif
 }
 
@@ -787,7 +787,7 @@
 		g.heads = nftl->heads;
 		g.sectors = nftl->sectors;
 		g.cylinders = nftl->cylinders;
-		g.start = get_start_sect(inode->i_rdev);
+		g.start = get_start_sect(inode->i_bdev);
 		return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
 	}
 	case BLKFLSBUF:
@@ -800,29 +800,18 @@
 
 	case BLKRRPART:
 		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-		if (nftl->usecount > 1) return -EBUSY;
-		/* 
-		 * We have to flush all buffers and invalidate caches,
-		 * or we won't be able to re-use the partitions,
-		 * if there was a change and we don't want to reboot
-		 */
-		res = wipe_partitions(inode->i_rdev);
+		{
+		kdev_t device = mk_kdev(MAJOR_NR,
+			minor(inode->i_rdev) & -(1<<NFTL_PARTN_BITS));
+		res = dev_lock_part(device);
+		if (res < 0)
+			return res;
+		res = wipe_partitions(device);
 		if (!res)
-			grok_partitions(inode->i_rdev, nftl->nr_sects);
-
+			grok_partitions(device, nftl->nr_sects);
+		dev_unlock_part(device);
+		}
 		return res;
-
-#if (LINUX_VERSION_CODE < 0x20303)		
-	RO_IOCTLS(inode->i_rdev, arg);  /* ref. linux/blk.h */
-#else
-	case BLKGETSIZE:
-	case BLKGETSIZE64:
-	case BLKROSET:
-	case BLKROGET:
-	case BLKSSZGET:
-		return blk_ioctl(inode->i_bdev, cmd, arg);
-#endif
-
 	default:
 		return -EINVAL;
 	}
@@ -955,7 +944,6 @@
 		return -EROFS;
 #endif /* !CONFIG_NFTL_RW */
 
-	thisNFTL->usecount++;
 	if (!get_mtd_device(thisNFTL->mtd, -1))
 		return /* -E'SBUGGEREDOFF */ -ENXIO;
 
@@ -970,11 +958,8 @@
 
 	DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n");
 
-	invalidate_device(inode->i_rdev, 1);
-
 	if (thisNFTL->mtd->sync)
 		thisNFTL->mtd->sync(thisNFTL->mtd);
-	thisNFTL->usecount--;
 
 	put_mtd_device(thisNFTL->mtd);
 
diff -Nru a/drivers/net/7990.c b/drivers/net/7990.c
--- a/drivers/net/7990.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/net/7990.c	Wed Jul 24 14:03:39 2002
@@ -569,7 +569,7 @@
         volatile u16 *mcast_table = (u16 *)&ib->filter;
         struct dev_mc_list *dmi=dev->mc_list;
         char *addrs;
-        int i, j, bit, byte;
+        int i;
         u32 crc;
         
         /* set all multicast bits */
diff -Nru a/drivers/net/8139cp.c b/drivers/net/8139cp.c
--- a/drivers/net/8139cp.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/net/8139cp.c	Wed Jul 24 14:03:38 2002
@@ -926,13 +926,15 @@
 
 static void cp_stop_hw (struct cp_private *cp)
 {
+	struct net_device *dev = cp->dev;
+
 	cpw16(IntrMask, 0);
 	cpr16(IntrMask);
 	cpw8(Cmd, 0);
 	cpw16(CpCmd, 0);
 	cpr16(CpCmd);
 	cpw16(IntrStatus, ~(cpr16(IntrStatus)));
-	synchronize_irq();
+	synchronize_irq(dev->irq);
 	udelay(10);
 
 	cp->rx_tail = 0;
diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/net/8139too.c	Wed Jul 24 14:03:35 2002
@@ -2130,7 +2130,9 @@
 
 	spin_unlock_irqrestore (&tp->lock, flags);
 
-	synchronize_irq ();
+	/* TODO: isn't this code racy? we synchronize the IRQ and then free it, */ 
+	/* but another IRQ could've happened in between the sync and free */ 
+	synchronize_irq (dev->irq);
 	free_irq (dev->irq, dev);
 
 	rtl8139_tx_clear (tp);
diff -Nru a/drivers/net/82596.c b/drivers/net/82596.c
--- a/drivers/net/82596.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/net/82596.c	Wed Jul 24 14:03:36 2002
@@ -64,7 +64,7 @@
 #include <asm/pgalloc.h>
 
 static char version[] __initdata =
-	"82596.c $Revision: 1.4 $\n";
+	"82596.c $Revision: 1.5 $\n";
 
 /* DEBUG flags
  */
@@ -421,7 +421,7 @@
 	while (--delcnt && lp->iscp.stat)
 		udelay(10);
 	if (!delcnt) {
-		printk("%s: %s, status %4.4x, cmd %4.4x.\n",
+		printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n",
 		     dev->name, str, lp->scb.status, lp->scb.command);
 		return -1;
 	}
@@ -435,7 +435,7 @@
 	while (--delcnt && lp->scb.command)
 		udelay(10);
 	if (!delcnt) {
-		printk("%s: %s, status %4.4x, cmd %4.4x.\n",
+		printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n",
 		     dev->name, str, lp->scb.status, lp->scb.command);
 		return -1;
 	}
@@ -444,6 +444,21 @@
 }
 
 
+static inline int wait_cfg(struct net_device *dev, struct i596_cmd *cmd, int delcnt, char *str)
+{
+	volatile struct i596_cmd *c = cmd;
+	
+	while (--delcnt && c->command)
+		udelay(10);
+	if (!delcnt) {
+		printk(KERN_ERR "%s: %s.\n", dev->name, str);
+		return -1;
+	}
+	else
+		return 0;
+}
+
+ 
 static void i596_display_data(struct net_device *dev)
 {
 	struct i596_private *lp = (struct i596_private *) dev->priv;
@@ -451,37 +466,37 @@
 	struct i596_rfd *rfd;
 	struct i596_rbd *rbd;
 
-	printk("lp and scp at %p, .sysbus = %08lx, .iscp = %p\n",
+	printk(KERN_ERR "lp and scp at %p, .sysbus = %08lx, .iscp = %p\n",
 	       &lp->scp, lp->scp.sysbus, lp->scp.iscp);
-	printk("iscp at %p, iscp.stat = %08lx, .scb = %p\n",
+	printk(KERN_ERR "iscp at %p, iscp.stat = %08lx, .scb = %p\n",
 	       &lp->iscp, lp->iscp.stat, lp->iscp.scb);
-	printk("scb at %p, scb.status = %04x, .command = %04x,"
+	printk(KERN_ERR "scb at %p, scb.status = %04x, .command = %04x,"
 		" .cmd = %p, .rfd = %p\n",
 	       &lp->scb, lp->scb.status, lp->scb.command,
 		lp->scb.cmd, lp->scb.rfd);
-	printk("   errors: crc %lx, align %lx, resource %lx,"
+	printk(KERN_ERR "   errors: crc %lx, align %lx, resource %lx,"
                " over %lx, rcvdt %lx, short %lx\n",
 		lp->scb.crc_err, lp->scb.align_err, lp->scb.resource_err,
 		lp->scb.over_err, lp->scb.rcvdt_err, lp->scb.short_err);
 	cmd = lp->cmd_head;
 	while (cmd != I596_NULL) {
-		printk("cmd at %p, .status = %04x, .command = %04x, .b_next = %p\n",
+		printk(KERN_ERR "cmd at %p, .status = %04x, .command = %04x, .b_next = %p\n",
 		  cmd, cmd->status, cmd->command, cmd->b_next);
 		cmd = cmd->v_next;
 	}
 	rfd = lp->rfd_head;
-	printk("rfd_head = %p\n", rfd);
+	printk(KERN_ERR "rfd_head = %p\n", rfd);
 	do {
-		printk ("   %p .stat %04x, .cmd %04x, b_next %p, rbd %p,"
+		printk(KERN_ERR "   %p .stat %04x, .cmd %04x, b_next %p, rbd %p,"
                         " count %04x\n",
 			rfd, rfd->stat, rfd->cmd, rfd->b_next, rfd->rbd,
 			rfd->count);
 		rfd = rfd->v_next;
 	} while (rfd != lp->rfd_head);
 	rbd = lp->rbd_head;
-	printk("rbd_head = %p\n", rbd);
+	printk(KERN_ERR "rbd_head = %p\n", rbd);
 	do {
-		printk("   %p .count %04x, b_next %p, b_data %p, size %04x\n",
+		printk(KERN_ERR "   %p .count %04x, b_next %p, b_data %p, size %04x\n",
 			rbd, rbd->count, rbd->b_next, rbd->b_data, rbd->size);
 		rbd = rbd->v_next;
 	} while (rbd != lp->rbd_head);
@@ -492,11 +507,23 @@
 static void i596_error(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = dev_id;
-	volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
+#ifdef ENABLE_MVME16x_NET
+	if (MACH_IS_MVME16x) {
+		volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
+
+		pcc2[0x28] = 1;
+		pcc2[0x2b] = 0x1d;
+	}
+#endif
+#ifdef ENABLE_BVME6000_NET
+	if (MACH_IS_BVME6000) {
+		volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG;
 
-	pcc2[0x28] = 1;
-	pcc2[0x2b] = 0x1d;
-	printk("%s: Error interrupt\n", dev->name);
+		*ethirq = 1;
+		*ethirq = 3;
+	}
+#endif
+	printk(KERN_ERR "%s: Error interrupt\n", dev->name);
 	i596_display_data(dev);
 }
 #endif
@@ -660,7 +687,14 @@
 
 	lp->cmd_head = lp->scb.cmd = I596_NULL;
 
-	DEB(DEB_INIT,printk("%s: starting i82596.\n", dev->name));
+#ifdef ENABLE_BVME6000_NET
+	if (MACH_IS_BVME6000) {
+		lp->scb.t_on  = 7 * 25;
+		lp->scb.t_off = 1 * 25;
+	}
+#endif
+
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: starting i82596.\n", dev->name));
 
 #if defined(ENABLE_APRICOT)
 	(void) inb(ioaddr + 0x10);
@@ -670,7 +704,7 @@
 
 	if (wait_istat(dev,lp,1000,"initialization timed out"))
 		goto failed;
-	DEB(DEB_INIT,printk("%s: i82596 initialization successful\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: i82596 initialization successful\n", dev->name));
 
 	/* Ensure rx frame/buffer descriptors are tidy */
 	rebuild_rx_bufs(dev);
@@ -694,17 +728,17 @@
 #endif
 
 
-	DEB(DEB_INIT,printk("%s: queuing CmdConfigure\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdConfigure\n", dev->name));
 	memcpy(lp->cf_cmd.i596_config, init_setup, 14);
 	lp->cf_cmd.cmd.command = CmdConfigure;
 	i596_add_cmd(dev, &lp->cf_cmd.cmd);
 
-	DEB(DEB_INIT,printk("%s: queuing CmdSASetup\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdSASetup\n", dev->name));
 	memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6);
 	lp->sa_cmd.cmd.command = CmdSASetup;
 	i596_add_cmd(dev, &lp->sa_cmd.cmd);
 
-	DEB(DEB_INIT,printk("%s: queuing CmdTDR\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdTDR\n", dev->name));
 	lp->tdr_cmd.cmd.command = CmdTDR;
 	i596_add_cmd(dev, &lp->tdr_cmd.cmd);
 
@@ -714,7 +748,7 @@
 		spin_unlock_irqrestore (&lp->lock, flags);
 		goto failed;
 	}
-	DEB(DEB_INIT,printk("%s: Issuing RX_START\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Issuing RX_START\n", dev->name));
 	lp->scb.command = RX_START;
 	CA(dev);
 
@@ -722,11 +756,11 @@
 
 	if (wait_cmd(dev,lp,1000,"RX_START not processed"))
 		goto failed;
-	DEB(DEB_INIT,printk("%s: Receive unit started OK\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Receive unit started OK\n", dev->name));
 	return 0;
 
 failed:
-	printk("%s: Failed to initialise 82596\n", dev->name);
+	printk(KERN_CRIT "%s: Failed to initialise 82596\n", dev->name);
 	MPU_PORT(dev, PORT_RESET, 0);
 	return -1;
 }
@@ -738,7 +772,7 @@
 	struct i596_rbd *rbd;
 	int frames = 0;
 
-	DEB(DEB_RXFRAME,printk ("i596_rx(), rfd_head %p, rbd_head %p\n",
+	DEB(DEB_RXFRAME,printk(KERN_DEBUG "i596_rx(), rfd_head %p, rbd_head %p\n",
 			lp->rfd_head, lp->rbd_head));
 
 	rfd = lp->rfd_head;		/* Ref next frame to check */
@@ -749,11 +783,11 @@
 		else if (rfd->rbd == lp->rbd_head->b_addr)
 			rbd = lp->rbd_head;
 		else {
-			printk("%s: rbd chain broken!\n", dev->name);
+			printk(KERN_CRIT "%s: rbd chain broken!\n", dev->name);
 			/* XXX Now what? */
 			rbd = I596_NULL;
 		}
-		DEB(DEB_RXFRAME, printk("  rfd %p, rfd.rbd %p, rfd.stat %04x\n",
+		DEB(DEB_RXFRAME, printk(KERN_DEBUG "  rfd %p, rfd.rbd %p, rfd.stat %04x\n",
 			rfd, rfd->rbd, rfd->stat));
 		
 		if (rbd != I596_NULL && ((rfd->stat) & STAT_OK)) {
@@ -794,7 +828,7 @@
 memory_squeeze:
 			if (skb == NULL) {
 				/* XXX tulip.c can defer packets here!! */
-				printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
+				printk(KERN_WARNING "%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
 				lp->stats.rx_dropped++;
 			}
 			else {
@@ -817,7 +851,7 @@
 			}
 		}
 		else {
-			DEB(DEB_ERRORS, printk("%s: Error, rfd.stat = 0x%04x\n",
+			DEB(DEB_ERRORS, printk(KERN_DEBUG "%s: Error, rfd.stat = 0x%04x\n",
 					dev->name, rfd->stat));
 			lp->stats.rx_errors++;
 			if ((rfd->stat) & 0x0001)
@@ -861,7 +895,7 @@
 		rfd = lp->rfd_head;
 	}
 
-	DEB(DEB_RXFRAME,printk ("frames %d\n", frames));
+	DEB(DEB_RXFRAME,printk(KERN_DEBUG "frames %d\n", frames));
 
 	return 0;
 }
@@ -904,7 +938,7 @@
 {
 	unsigned long flags;
 
-	DEB(DEB_RESET,printk("i596_reset\n"));
+	DEB(DEB_RESET,printk(KERN_DEBUG "i596_reset\n"));
 
 	spin_lock_irqsave (&lp->lock, flags);
 
@@ -932,7 +966,7 @@
 	int ioaddr = dev->base_addr;
 	unsigned long flags;
 
-	DEB(DEB_ADDCMD,printk("i596_add_cmd\n"));
+	DEB(DEB_ADDCMD,printk(KERN_DEBUG "i596_add_cmd\n"));
 
 	cmd->status = 0;
 	cmd->command |= (CMD_EOL | CMD_INTR);
@@ -961,7 +995,7 @@
 		if (tickssofar < ticks_limit)
 			return;
 
-		printk("%s: command unit timed out, status resetting.\n", dev->name);
+		printk(KERN_NOTICE "%s: command unit timed out, status resetting.\n", dev->name);
 
 		i596_reset(dev, lp, ioaddr);
 	}
@@ -971,10 +1005,10 @@
 {
 	int res = 0;
 
-	DEB(DEB_OPEN,printk("%s: i596_open() irq %d.\n", dev->name, dev->irq));
+	DEB(DEB_OPEN,printk(KERN_DEBUG "%s: i596_open() irq %d.\n", dev->name, dev->irq));
 
 	if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) {
-		printk("%s: IRQ %d not free\n", dev->name, dev->irq);
+		printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
 #ifdef ENABLE_MVME16x_NET
@@ -1004,19 +1038,19 @@
 	int ioaddr = dev->base_addr;
 
 	/* Transmitter timeout, serious problems. */
-	DEB(DEB_ERRORS,printk("%s: transmit timed out, status resetting.\n",
+	DEB(DEB_ERRORS,printk(KERN_ERR "%s: transmit timed out, status resetting.\n",
 			dev->name));
 
 	lp->stats.tx_errors++;
 
 	/* Try to restart the adaptor */
 	if (lp->last_restart == lp->stats.tx_packets) {
-		DEB(DEB_ERRORS,printk ("Resetting board.\n"));
+		DEB(DEB_ERRORS,printk(KERN_ERR "Resetting board.\n"));
 		/* Shutdown and restart */
 		i596_reset (dev, lp, ioaddr);
 	} else {
 		/* Issue a channel attention signal */
-		DEB(DEB_ERRORS,printk ("Kicking board.\n"));
+		DEB(DEB_ERRORS,printk(KERN_ERR "Kicking board.\n"));
 		lp->scb.command = CUC_START | RX_START;
 		CA (dev);
 		lp->last_restart = lp->stats.tx_packets;
@@ -1035,7 +1069,7 @@
 	short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 	dev->trans_start = jiffies;
 
-	DEB(DEB_STARTTX,printk("%s: i596_start_xmit(%x,%x) called\n", dev->name,
+	DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%x) called\n", dev->name,
 				skb->len, (unsigned int)skb->data));
 
 	netif_stop_queue(dev);
@@ -1044,8 +1078,8 @@
 	tbd = lp->tbds + lp->next_tx_cmd;
 
 	if (tx_cmd->cmd.command) {
-		DEB(DEB_ERRORS,printk ("%s: xmit ring full, dropping packet.\n",
-				dev->name));
+		printk(KERN_NOTICE "%s: xmit ring full, dropping packet.\n",
+				dev->name);
 		lp->stats.tx_dropped++;
 
 		dev_kfree_skb(skb);
@@ -1084,7 +1118,7 @@
 {
 	int i;
 
-	printk("i596 0x%p, ", add);
+	printk(KERN_DEBUG "i596 0x%p, ", add);
 	for (i = 0; i < 6; i++)
 		printk(" %02X", add[i + 6]);
 	printk(" -->");
@@ -1106,7 +1140,7 @@
 #ifdef ENABLE_MVME16x_NET
 	if (MACH_IS_MVME16x) {
 		if (mvme16x_config & MVME16x_CONFIG_NO_ETHERNET) {
-			printk("Ethernet probe disabled - chip not present\n");
+			printk(KERN_NOTICE "Ethernet probe disabled - chip not present\n");
 			return -ENODEV;
 		}
 		memcpy(eth_addr, (void *) 0xfffc1f2c, 6);	/* YUCK! Get addr from NOVRAM */
@@ -1137,7 +1171,7 @@
 		/* first check nothing is already registered here */
 
 		if (!request_region(ioaddr, I596_TOTAL_SIZE, dev->name)) {
-			printk("82596: IO address 0x%04x in use\n", ioaddr);
+			printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr);
 			return -EBUSY;
 		}
 
@@ -1171,14 +1205,14 @@
 	}
 
 	ether_setup(dev);
-	DEB(DEB_PROBE,printk("%s: 82596 at %#3lx,", dev->name, dev->base_addr));
+	DEB(DEB_PROBE,printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));
 
 	for (i = 0; i < 6; i++)
 		DEB(DEB_PROBE,printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]));
 
 	DEB(DEB_PROBE,printk(" IRQ %d.\n", dev->irq));
 
-	DEB(DEB_PROBE,printk(version));
+	DEB(DEB_PROBE,printk(KERN_INFO "%s", version));
 
 	/* The 82596-specific entries in the device structure. */
 	dev->open = i596_open;
@@ -1192,7 +1226,7 @@
 	dev->priv = (void *)(dev->mem_start);
 
 	lp = (struct i596_private *) dev->priv;
-	DEB(DEB_INIT,printk ("%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n",
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n",
 			dev->name, (unsigned long)lp,
 			sizeof(struct i596_private), (unsigned long)&lp->scb));
 	memset((void *) lp, 0, sizeof(struct i596_private));
@@ -1220,13 +1254,13 @@
 #ifdef ENABLE_BVME6000_NET
 	if (MACH_IS_BVME6000) {
 		if (*(char *) BVME_LOCAL_IRQ_STAT & BVME_ETHERR) {
-			i596_error(BVME_IRQ_I596, NULL, NULL);
+			i596_error(irq, dev_id, regs);
 			return;
 		}
 	}
 #endif
 	if (dev == NULL) {
-		printk("i596_interrupt(): irq %d for unknown device.\n", irq);
+		printk(KERN_ERR "i596_interrupt(): irq %d for unknown device.\n", irq);
 		return;
 	}
 
@@ -1238,7 +1272,7 @@
 	wait_cmd(dev,lp,100,"i596 interrupt, timeout");
 	status = lp->scb.status;
 
-	DEB(DEB_INTS,printk("%s: i596 interrupt, IRQ %d, status %4.4x.\n",
+	DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt, IRQ %d, status %4.4x.\n",
 			dev->name, irq, status));
 
 	ack_cmd = status & 0xf000;
@@ -1247,14 +1281,14 @@
 		struct i596_cmd *ptr;
 
 		if ((status & 0x8000))
-			DEB(DEB_INTS,printk("%s: i596 interrupt completed command.\n", dev->name));
+			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt completed command.\n", dev->name));
 		if ((status & 0x2000))
-			DEB(DEB_INTS,printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
+			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
 
 		while ((lp->cmd_head != I596_NULL) && (lp->cmd_head->status & STAT_C)) {
 			ptr = lp->cmd_head;
 
-			DEB(DEB_STATUS,printk("cmd_head->status = %04x, ->command = %04x\n",
+			DEB(DEB_STATUS,printk(KERN_DEBUG "cmd_head->status = %04x, ->command = %04x\n",
 				       lp->cmd_head->status, lp->cmd_head->command));
 			lp->cmd_head = ptr->v_next;
 			lp->cmd_backlog--;
@@ -1291,20 +1325,21 @@
 				unsigned short status = ((struct tdr_cmd *)ptr)->status;
 
 				if (status & 0x8000) {
-					DEB(DEB_ANY,printk("%s: link ok.\n", dev->name));
+					DEB(DEB_TDR,printk(KERN_INFO "%s: link ok.\n", dev->name));
 				} else {
 					if (status & 0x4000)
-						printk("%s: Transceiver problem.\n", dev->name);
+						printk(KERN_ERR "%s: Transceiver problem.\n", dev->name);
 					if (status & 0x2000)
-						printk("%s: Termination problem.\n", dev->name);
+						printk(KERN_ERR "%s: Termination problem.\n", dev->name);
 					if (status & 0x1000)
-						printk("%s: Short circuit.\n", dev->name);
+						printk(KERN_ERR "%s: Short circuit.\n", dev->name);
 
-					DEB(DEB_TDR,printk("%s: Time %d.\n", dev->name, status & 0x07ff));
+					DEB(DEB_TDR,printk(KERN_INFO "%s: Time %d.\n", dev->name, status & 0x07ff));
 				}
 				break;
 			    }
 			case CmdConfigure:
+			case CmdMulticastList:
 				/* Zap command so set_multicast_list() knows it is free */
 				ptr->command = 0;
 				break;
@@ -1325,12 +1360,12 @@
 	}
 	if ((status & 0x1000) || (status & 0x4000)) {
 		if ((status & 0x4000))
-			DEB(DEB_INTS,printk("%s: i596 interrupt received a frame.\n", dev->name));
+			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt received a frame.\n", dev->name));
 		i596_rx(dev);
 		/* Only RX_START if stopped - RGH 07-07-96 */
 		if (status & 0x1000) {
 			if (netif_running(dev)) {
-				DEB(DEB_ERRORS,printk("%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
+				DEB(DEB_ERRORS,printk(KERN_ERR "%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
 				ack_cmd |= RX_START;
 				lp->stats.rx_errors++;
 				lp->stats.rx_fifo_errors++;
@@ -1364,7 +1399,7 @@
 #endif
 	CA(dev);
 
-	DEB(DEB_INTS,printk("%s: exiting interrupt.\n", dev->name));
+	DEB(DEB_INTS,printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name));
 
 	spin_unlock (&lp->lock);
 	return;
@@ -1377,7 +1412,7 @@
 
 	netif_stop_queue(dev);
 
-	DEB(DEB_INIT,printk("%s: Shutting down ethercard, status was %4.4x.\n",
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
 		       dev->name, lp->scb.status));
 
 	save_flags(flags);
@@ -1434,7 +1469,13 @@
 	struct i596_private *lp = (struct i596_private *) dev->priv;
 	int config = 0, cnt;
 
-	DEB(DEB_MULTI,printk("%s: set multicast list, %d entries, promisc %s, allmulti %s\n", dev->name, dev->mc_count, dev->flags & IFF_PROMISC ? "ON" : "OFF", dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
+	DEB(DEB_MULTI,printk(KERN_DEBUG "%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
+		dev->name, dev->mc_count,
+		dev->flags & IFF_PROMISC  ? "ON" : "OFF",
+		dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
+
+	if (wait_cfg(dev, &lp->cf_cmd.cmd, 1000, "config change request timed out"))
+		return;
 
 	if ((dev->flags & IFF_PROMISC) && !(lp->cf_cmd.i596_config[8] & 0x01)) {
 		lp->cf_cmd.i596_config[8] |= 0x01;
@@ -1453,20 +1494,15 @@
 		config = 1;
 	}
 	if (config) {
-		if (lp->cf_cmd.cmd.command)
-			printk("%s: config change request already queued\n",
-			       dev->name);
-		else {
-			lp->cf_cmd.cmd.command = CmdConfigure;
-			i596_add_cmd(dev, &lp->cf_cmd.cmd);
-		}
+		lp->cf_cmd.cmd.command = CmdConfigure;
+		i596_add_cmd(dev, &lp->cf_cmd.cmd);
 	}
 
 	cnt = dev->mc_count;
 	if (cnt > MAX_MC_CNT)
 	{
 		cnt = MAX_MC_CNT;
-		printk("%s: Only %d multicast addresses supported",
+		printk(KERN_ERR "%s: Only %d multicast addresses supported",
 			dev->name, cnt);
 	}
 	
@@ -1475,6 +1511,8 @@
 		unsigned char *cp;
 		struct mc_cmd *cmd;
 
+		if (wait_cfg(dev, &lp->mc_cmd.cmd, 1000, "multicast list change request timed out"))
+			return;
 		cmd = &lp->mc_cmd;
 		cmd->cmd.command = CmdMulticastList;
 		cmd->mc_cnt = dev->mc_count * 6;
@@ -1482,7 +1520,7 @@
 		for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) {
 			memcpy(cp, dmi->dmi_addr, 6);
 			if (i596_debug > 1)
-				DEB(DEB_MULTI,printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
+				DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
 						dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5]));
 		}
 		i596_add_cmd(dev, &cmd->cmd);
diff -Nru a/drivers/net/8390.h b/drivers/net/8390.h
--- a/drivers/net/8390.h	Wed Jul 24 14:03:39 2002
+++ b/drivers/net/8390.h	Wed Jul 24 14:03:39 2002
@@ -106,13 +106,24 @@
 
 /*
  *	Only generate indirect loads given a machine that needs them.
+ *      - removed AMIGA_PCMCIA from this list, handled as ISA io now
  */
  
-#if defined(CONFIG_MAC) || defined(CONFIG_AMIGA_PCMCIA) || \
+#if defined(CONFIG_MAC) ||  \
     defined(CONFIG_ARIADNE2) || defined(CONFIG_ARIADNE2_MODULE) || \
     defined(CONFIG_HYDRA) || defined(CONFIG_HYDRA_MODULE) || \
     defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE)
 #define EI_SHIFT(x)	(ei_local->reg_offset[x])
+#undef inb
+#undef inb_p
+#undef outb
+#undef outb_p
+
+#define inb(port)   in_8(port)
+#define outb(val,port)  out_8(port,val)
+#define inb_p(port)   in_8(port)
+#define outb_p(val,port)  out_8(port,val)
+
 #else
 #define EI_SHIFT(x)	(x)
 #endif
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/net/Space.c	Wed Jul 24 14:03:36 2002
@@ -99,7 +99,7 @@
 extern int mvme147lance_probe(struct net_device *dev);
 extern int tc515_probe(struct net_device *dev);
 extern int lance_probe(struct net_device *dev);
-extern int mace68k_probe(struct net_device *dev);
+extern int mace_probe(struct net_device *dev);
 extern int macsonic_probe(struct net_device *dev);
 extern int mac8390_probe(struct net_device *dev);
 extern int mac89x0_probe(struct net_device *dev);
@@ -354,7 +354,7 @@
 	{mvme147lance_probe, 0},
 #endif
 #ifdef CONFIG_MACMACE		/* Mac 68k Quadra AV builtin Ethernet */
-	{mace68k_probe, 0},
+	{mace_probe, 0},
 #endif
 #ifdef CONFIG_MACSONIC		/* Mac SONIC-based Ethernet of all sorts */ 
 	{macsonic_probe, 0},
diff -Nru a/drivers/net/a2065.c b/drivers/net/a2065.c
--- a/drivers/net/a2065.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/net/a2065.c	Wed Jul 24 14:03:38 2002
@@ -639,7 +639,7 @@
 	volatile u16 *mcast_table = (u16 *)&ib->filter;
 	struct dev_mc_list *dmi=dev->mc_list;
 	char *addrs;
-	int i, j, bit, byte;
+	int i;
 	u32 crc;
 	
 	/* set all multicast bits */
diff -Nru a/drivers/net/acenic.c b/drivers/net/acenic.c
--- a/drivers/net/acenic.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/net/acenic.c	Wed Jul 24 14:03:38 2002
@@ -3389,14 +3389,13 @@
 	 * Don't take interrupts on this CPU will bit banging
 	 * the %#%#@$ I2C device
 	 */
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 
 	eeprom_start(regs);
 
 	eeprom_prep(regs, EEPROM_WRITE_SELECT);
 	if (eeprom_check_ack(regs)) {
-		__restore_flags(flags);
+		local_irq_restore(flags);
 		printk(KERN_ERR "%s: Unable to sync eeprom\n", dev->name);
 		result = -EIO;
 		goto eeprom_read_error;
@@ -3404,7 +3403,7 @@
 
 	eeprom_prep(regs, (offset >> 8) & 0xff);
 	if (eeprom_check_ack(regs)) {
-		__restore_flags(flags);
+		local_irq_restore(flags);
 		printk(KERN_ERR "%s: Unable to set address byte 0\n",
 		       dev->name);
 		result = -EIO;
@@ -3413,7 +3412,7 @@
 
 	eeprom_prep(regs, offset & 0xff);
 	if (eeprom_check_ack(regs)) {
-		__restore_flags(flags);
+		local_irq_restore(flags);
 		printk(KERN_ERR "%s: Unable to set address byte 1\n",
 		       dev->name);
 		result = -EIO;
@@ -3423,7 +3422,7 @@
 	eeprom_start(regs);
 	eeprom_prep(regs, EEPROM_READ_SELECT);
 	if (eeprom_check_ack(regs)) {
-		__restore_flags(flags);
+		local_irq_restore(flags);
 		printk(KERN_ERR "%s: Unable to set READ_SELECT\n",
 		       dev->name);
 		result = -EIO;
@@ -3469,7 +3468,7 @@
 	udelay(ACE_SHORT_DELAY);
 	eeprom_stop(regs);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
  out:
 	return result;
 
diff -Nru a/drivers/net/atarilance.c b/drivers/net/atarilance.c
--- a/drivers/net/atarilance.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/net/atarilance.c	Wed Jul 24 14:03:36 2002
@@ -565,7 +565,7 @@
 		}
 		if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
 		            "Riebl-VME Ethernet", dev)) {
-			printk( "Lance: request for irq %d failed\n", irq );
+			printk( "Lance: request for irq %ld failed\n", irq );
 			return( 0 );
 		}
 		dev->irq = irq;
@@ -926,7 +926,7 @@
 #ifndef final_version
 			if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
 				DPRINTK( 0, ( "out-of-sync dirty pointer,"
-							  " %d vs. %d, full=%d.\n",
+							  " %d vs. %d, full=%ld.\n",
 							  dirty_tx, lp->cur_tx, lp->tx_full ));
 				dirty_tx += TX_RING_SIZE;
 			}
diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c
--- a/drivers/net/eepro100.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/net/eepro100.c	Wed Jul 24 14:03:38 2002
@@ -1354,7 +1354,7 @@
 		udelay(10);
 		/* Disable interrupts. */
 		outw(SCBMaskAll, ioaddr + SCBCmd);
-		synchronize_irq();
+		synchronize_irq(dev->irq);
 		speedo_tx_buffer_gc(dev);
 		/* Free as much as possible.
 		   It helps to recover from a hang because of out-of-memory.
diff -Nru a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c
--- a/drivers/net/fc/iph5526.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/net/fc/iph5526.c	Wed Jul 24 14:03:36 2002
@@ -3891,7 +3891,7 @@
 }
 
 
-int iph5526_biosparam(Disk * disk, kdev_t n, int ip[])
+int iph5526_biosparam(Disk * disk, struct block_device *n, int ip[])
 {
 int size = disk->capacity;
 	ip[0] = 64;
diff -Nru a/drivers/net/fc/iph5526_scsi.h b/drivers/net/fc/iph5526_scsi.h
--- a/drivers/net/fc/iph5526_scsi.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/net/fc/iph5526_scsi.h	Wed Jul 24 14:03:35 2002
@@ -25,7 +25,7 @@
 int iph5526_release(struct Scsi_Host *host);
 int iph5526_abort(Scsi_Cmnd *Cmnd);
 const char *iph5526_info(struct Scsi_Host *host);
-int iph5526_biosparam(Disk * disk, kdev_t n, int ip[]);
+int iph5526_biosparam(Disk * disk, struct block_device *n, int ip[]);
 
 #endif
 
diff -Nru a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c
--- a/drivers/net/hamradio/baycom_par.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/net/hamradio/baycom_par.c	Wed Jul 24 14:03:39 2002
@@ -288,14 +288,14 @@
 		par96_rx(dev, bc);
 		if (--bc->modem.arb_divider <= 0) {
 			bc->modem.arb_divider = 6;
-			__sti();
+			local_irq_enable();
 			hdlcdrv_arbitrate(dev, &bc->hdrv);
 		}
 	}
-	__sti();
+	local_irq_enable();
 	hdlcdrv_transmitter(dev, &bc->hdrv);
 	hdlcdrv_receiver(dev, &bc->hdrv);
-        __cli();
+        local_irq_disable();
 }
 
 /* --------------------------------------------------------------------- */
diff -Nru a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
--- a/drivers/net/hamradio/baycom_ser_fdx.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/net/hamradio/baycom_ser_fdx.c	Wed Jul 24 14:03:38 2002
@@ -350,7 +350,7 @@
 		bc->modem.ser12.txshreg >>= 1;
 	}
  end_transmit:
-	__sti();
+	local_irq_enable();
 	if (!bc->modem.ptt && txcount) {
 		hdlcdrv_arbitrate(dev, &bc->hdrv);
 		if (hdlcdrv_ptt(&bc->hdrv)) {
@@ -361,7 +361,7 @@
 	}
 	hdlcdrv_transmitter(dev, &bc->hdrv);
 	hdlcdrv_receiver(dev, &bc->hdrv);
-	__cli();
+	local_irq_disable();
 }
 
 /* --------------------------------------------------------------------- */
diff -Nru a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c
--- a/drivers/net/hamradio/baycom_ser_hdx.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/net/hamradio/baycom_ser_hdx.c	Wed Jul 24 14:03:35 2002
@@ -416,13 +416,13 @@
 	} while (!(iir & 1));
 	if (bc->modem.arb_divider <= 0) {
 		bc->modem.arb_divider = SER12_ARB_DIVIDER(bc);
-		__sti();
+		local_irq_enable();
 		hdlcdrv_arbitrate(dev, &bc->hdrv);
 	}
-	__sti();
+	local_irq_enable();
 	hdlcdrv_transmitter(dev, &bc->hdrv);
 	hdlcdrv_receiver(dev, &bc->hdrv);
-	__cli();
+	local_irq_disable();
 }
 
 /* --------------------------------------------------------------------- */
diff -Nru a/drivers/net/hplance.c b/drivers/net/hplance.c
--- a/drivers/net/hplance.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/net/hplance.c	Wed Jul 24 14:03:38 2002
@@ -58,9 +58,9 @@
 static int hplance_init(struct net_device *dev, int scode);
 static int hplance_open(struct net_device *dev);
 static int hplance_close(struct net_device *dev);
-static void hplance_writerap(struct hplance_private *lp, unsigned short value);
-static void hplance_writerdp(struct hplance_private *lp, unsigned short value);
-static unsigned short hplance_readrdp(struct hplance_private *lp);
+static void hplance_writerap(void *priv, unsigned short value);
+static void hplance_writerdp(void *priv, unsigned short value);
+static unsigned short hplance_readrdp(void *priv);
 
 #ifdef MODULE
 static struct hplance_private *root_hplance_dev;
@@ -100,8 +100,7 @@
 /* Initialise a single lance board at the given select code */
 static int __init hplance_init(struct net_device *dev, int scode)
 {
-        /* const char *name = dio_scodetoname(scode); */
-        static const char name[] = "HP LANCE";
+        const char *name = dio_scodetoname(scode);
         void *va = dio_scodetoviraddr(scode);
         struct hplance_private *lp;
         int i;
@@ -118,10 +117,10 @@
 #endif
 	SET_MODULE_OWNER(dev);
 
-        printk("%s: HP LANCE; select code %d, addr", dev->name, scode);
+        printk("%s: %s; select code %d, addr", dev->name, name, scode);
 
         /* reset the board */
-        writeb(0xff,va+DIO_IDOFF);
+        out_8(va+DIO_IDOFF, 0xff);
         udelay(100);                              /* ariba! ariba! udelay! udelay! */
 
         /* Fill the dev fields */
@@ -138,8 +137,8 @@
                 /* The NVRAM holds our ethernet address, one nibble per byte,
                  * at bytes NVRAMOFF+1,3,5,7,9...
                  */
-                dev->dev_addr[i] = ((readb(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4)
-                        | (readb(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF);
+                dev->dev_addr[i] = ((in_8(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4)
+                        | (in_8(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF);
                 printk("%c%2.2x", i == 0 ? ' ' : ':', dev->dev_addr[i]);
         }
         
@@ -175,25 +174,28 @@
 /* This is disgusting. We have to check the DIO status register for ack every
  * time we read or write the LANCE registers.
  */
-static void hplance_writerap(struct hplance_private *lp, unsigned short value)
+static void hplance_writerap(void *priv, unsigned short value)
 {
+	struct hplance_private *lp = (struct hplance_private *)priv;
         struct hplance_reg *hpregs = (struct hplance_reg *)lp->base;
         do {
                 lp->lance.ll->rap = value;
         } while ((hpregs->status & LE_ACK) == 0);
 }
 
-static void hplance_writerdp(struct hplance_private *lp, unsigned short value)
+static void hplance_writerdp(void *priv, unsigned short value)
 {
+	struct hplance_private *lp = (struct hplance_private *)priv;
         struct hplance_reg *hpregs = (struct hplance_reg *)lp->base;
         do {
                 lp->lance.ll->rdp = value;
         } while ((hpregs->status & LE_ACK) == 0);
 }
 
-static unsigned short hplance_readrdp(struct hplance_private *lp)
+static unsigned short hplance_readrdp(void *priv)
 {
         unsigned short val;
+	struct hplance_private *lp = (struct hplance_private *)priv;
         struct hplance_reg *hpregs = (struct hplance_reg *)lp->base;
         do {
                 val = lp->lance.ll->rdp;
@@ -211,7 +213,7 @@
         if (status)
                 return status;
         /* enable interrupts at board level. */
-        writeb(LE_IE, &(hpregs->status));
+        out_8(&(hpregs->status), LE_IE);
 
         return 0;
 }
@@ -220,7 +222,7 @@
 {
         struct hplance_private *lp = (struct hplance_private *)dev->priv;
         struct hplance_reg *hpregs = (struct hplance_reg *)lp->base;
-        writeb(0,&(hpregs->status));              /* disable interrupts at boardlevel */
+        out_8(&(hpregs->status), 8);              /* disable interrupts at boardlevel */
         lance_close(dev);
         return 0;
 }
diff -Nru a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c
--- a/drivers/net/mac89x0.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/net/mac89x0.c	Wed Jul 24 14:03:38 2002
@@ -144,28 +144,28 @@
 static int inline
 readreg_io(struct net_device *dev, int portno)
 {
-	writew(swab16(portno), dev->base_addr + ADD_PORT);
-	return swab16(readw(dev->base_addr + DATA_PORT));
+	nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
+	return swab16(nubus_readw(dev->base_addr + DATA_PORT));
 }
 
 static void inline
 writereg_io(struct net_device *dev, int portno, int value)
 {
-	writew(swab16(portno), dev->base_addr + ADD_PORT);
-	writew(swab16(value), dev->base_addr + DATA_PORT);
+	nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
+	nubus_writew(swab16(value), dev->base_addr + DATA_PORT);
 }
 
 /* These are for reading/writing registers in shared memory */
 static int inline
 readreg(struct net_device *dev, int portno)
 {
-	return swab16(readw(dev->mem_start + portno));
+	return swab16(nubus_readw(dev->mem_start + portno));
 }
 
 static void inline
 writereg(struct net_device *dev, int portno, int value)
 {
-	writew(swab16(value), dev->mem_start + portno);
+	nubus_writew(swab16(value), dev->mem_start + portno);
 }
 
 /* Probe for the CS8900 card in slot E.  We won't bother looking
@@ -210,8 +210,8 @@
 			return -ENODEV;
 	}
 
-	writew(0, ioaddr + ADD_PORT);
-	sig = readw(ioaddr + DATA_PORT);
+	nubus_writew(0, ioaddr + ADD_PORT);
+	sig = nubus_readw(ioaddr + DATA_PORT);
 	if (sig != swab16(CHIP_EISA_ID_SIG))
 		return -ENODEV;
 
@@ -450,7 +450,7 @@
            course, if you're on a slow machine, and packets are arriving
            faster than you can read them off, you're screwed.  Hasta la
            vista, baby!  */
-	while ((status = swab16(readw(dev->base_addr + ISQ_PORT)))) {
+	while ((status = swab16(nubus_readw(dev->base_addr + ISQ_PORT)))) {
 		if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
 		switch(status & ISQ_EVENT_MASK) {
 		case ISQ_RECEIVER_EVENT:
@@ -653,7 +653,7 @@
 
 #endif
 #ifdef MODULE
-	writew(0, dev_cs89x0.base_addr + ADD_PORT);
+	nubus_writew(0, dev_cs89x0.base_addr + ADD_PORT);
 #endif
 #ifdef MODULE
 
diff -Nru a/drivers/net/macmace.c b/drivers/net/macmace.c
--- a/drivers/net/macmace.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/net/macmace.c	Wed Jul 24 14:03:37 2002
@@ -10,15 +10,17 @@
  *
  *	Copyright (C) 1996 Paul Mackerras.
  *	Copyright (C) 1998 Alan Cox <alan@redhat.com>
+ *
+ *	Modified heavily by Joshua M. Thompson based on Dave Huang's NetBSD driver
  */
 
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
 #include <linux/string.h>
-#include <linux/timer.h>
 #include <linux/crc32.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -26,14 +28,13 @@
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_psc.h>
+#include <asm/page.h>
 #include "mace.h"
 
+#define N_TX_RING	1
 #define N_RX_RING	8
-#define N_TX_RING	2
-#define MAX_TX_ACTIVE	1
-#define NCMDS_TX	1	/* dma commands per element in tx ring */
-#define RX_BUFLEN	(ETH_FRAME_LEN + 8)
-#define TX_TIMEOUT	HZ	/* 1 second */
+#define N_RX_PAGES	((N_RX_RING * 0x0800 + PAGE_SIZE - 1) / PAGE_SIZE)
+#define TX_TIMEOUT	HZ
 
 /* Bits in transmit DMA status */
 #define TX_DMA_ERR	0x80
@@ -43,22 +44,19 @@
 #define MACE_BASE	(void *)(0x50F1C000)
 #define MACE_PROM	(void *)(0x50F08001)
 
-struct mace68k_data
-{
+struct mace_data {
 	volatile struct mace *mace;
 	volatile unsigned char *tx_ring;
+	volatile unsigned char *tx_ring_phys;
 	volatile unsigned char *rx_ring;
+	volatile unsigned char *rx_ring_phys;
 	int dma_intr;
-	unsigned char maccc;
 	struct net_device_stats stats;
-	struct timer_list tx_timeout;
-	int timeout_active;
-	int rx_slot, rx_done;
-	int tx_slot, tx_count;
+	int rx_slot, rx_tail;
+	int tx_slot, tx_sloti, tx_count;
 };
 
-struct mace_frame
-{
+struct mace_frame {
 	u16	len;
 	u16	status;
 	u16	rntpc;
@@ -69,271 +67,226 @@
 	/* And frame continues.. */
 };
 
-#define PRIV_BYTES	sizeof(struct mace68k_data)
+#define PRIV_BYTES	sizeof(struct mace_data)
 
 extern void psc_debug_dump(void);
 
-static int mace68k_open(struct net_device *dev);
-static int mace68k_close(struct net_device *dev);
-static int mace68k_xmit_start(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *mace68k_stats(struct net_device *dev);
-static void mace68k_set_multicast(struct net_device *dev);
-static void mace68k_reset(struct net_device *dev);
-static int mace68k_set_address(struct net_device *dev, void *addr);
-static void mace68k_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void mace68k_dma_intr(int irq, void *dev_id, struct pt_regs *regs);
-static void mace68k_set_timeout(struct net_device *dev);
-static void mace68k_tx_timeout(unsigned long data);
+static int mace_open(struct net_device *dev);
+static int mace_close(struct net_device *dev);
+static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static struct net_device_stats *mace_stats(struct net_device *dev);
+static void mace_set_multicast(struct net_device *dev);
+static int mace_set_address(struct net_device *dev, void *addr);
+static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs);
+static void mace_tx_timeout(struct net_device *dev);
 
-/*
- *	PSC DMA engine control. As you'd expect on a macintosh its
- *	more like a lawnmower engine supplied without instructions
- *
- *	The basic theory of operation appears to be as follows.
- *
- *	There are two sets of receive DMA registers and two sets
- *	of transmit DMA registers. Instead of the more traditional
- *	"ring buffer" approach the Mac68K DMA engine expects you
- *	to be loading one chain while the other runs, and then
- *	to flip register set. Each entry in the chain is a fixed 
- *	length.
- */
+/* Bit-reverse one byte of an ethernet hardware address. */
+
+static int bitrev(int b)
+{
+	int d = 0, i;
+
+	for (i = 0; i < 8; ++i, b >>= 1) {
+		d = (d << 1) | (b & 1);
+	}
+
+	return d;
+}
 
 /*
- *	Load a receive DMA channel with a base address and ring length
+ * Load a receive DMA channel with a base address and ring length
  */
-  
-static void psc_load_rxdma_base(int set, void *base)
+
+static void mace_load_rxdma_base(struct net_device *dev, int set)
 {
+	struct mace_data *mp = (struct mace_data *) dev->priv;
+
 	psc_write_word(PSC_ENETRD_CMD + set, 0x0100);
-	psc_write_long(PSC_ENETRD_ADDR + set, (u32)base);
+	psc_write_long(PSC_ENETRD_ADDR + set, (u32) mp->rx_ring_phys);
 	psc_write_long(PSC_ENETRD_LEN + set, N_RX_RING);
 	psc_write_word(PSC_ENETRD_CMD + set, 0x9800);
+	mp->rx_tail = 0;
 }
 
 /*
- *	Reset the receive DMA subsystem
+ * Reset the receive DMA subsystem
  */
-  
-static void mace68k_rxdma_reset(struct net_device *dev)
+
+static void mace_rxdma_reset(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mace = mp->mace;
-	u8 mcc = mace->maccc;
-	
-	/*
-	 *	Turn off receive
-	 */
-	 
-	mcc&=~ENRCV;
-	mace->maccc=mcc;
+	u8 maccc = mace->maccc;
 	
-	/*
-	 *	Program the DMA
-	 */
+	mace->maccc = maccc & ~ENRCV;
 	
 	psc_write_word(PSC_ENETRD_CTL, 0x8800);
-	psc_load_rxdma_base(0x0, (void *)virt_to_bus(mp->rx_ring));
+	mace_load_rxdma_base(dev, 0x00);
 	psc_write_word(PSC_ENETRD_CTL, 0x0400);
 	
 	psc_write_word(PSC_ENETRD_CTL, 0x8800);
-	psc_load_rxdma_base(0x10, (void *)virt_to_bus(mp->rx_ring));
+	mace_load_rxdma_base(dev, 0x10);
 	psc_write_word(PSC_ENETRD_CTL, 0x0400);
 	
-	mace->maccc=mcc|ENRCV;
-	
-#if 0
-	psc_write_word(PSC_ENETRD_CTL, 0x9800);
-	psc_write_word(PSC_ENETRD_CTL+0x10, 0x9800);
-#endif
+	mace->maccc = maccc;
+	mp->rx_slot = 0;
+
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET0, 0x9800);
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET1, 0x9800);
 }
 
 /*
- *	Reset the transmit DMA subsystem
+ * Reset the transmit DMA subsystem
  */
  
-static void mace68k_txdma_reset(struct net_device *dev)
+static void mace_txdma_reset(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mace = mp->mace;
-	u8 mcc = mace->maccc;
+	u8 maccc;
 
-	psc_write_word(PSC_ENETWR_CTL,0x8800);
-	
-	mace->maccc = mcc&~ENXMT;
-	psc_write_word(PSC_ENETWR_CTL,0x0400);
-	mace->maccc = mcc;
+	psc_write_word(PSC_ENETWR_CTL, 0x8800);
+
+	maccc = mace->maccc;
+	mace->maccc = maccc & ~ENXMT;
+
+	mp->tx_slot = mp->tx_sloti = 0;
+	mp->tx_count = N_TX_RING;
+
+	psc_write_word(PSC_ENETWR_CTL, 0x0400);
+	mace->maccc = maccc;
 }
 
 /*
- *	Disable DMA
+ * Disable DMA
  */
  
-static void mace68k_dma_off(struct net_device *dev)
+static void mace_dma_off(struct net_device *dev)
 {
 	psc_write_word(PSC_ENETRD_CTL, 0x8800);
 	psc_write_word(PSC_ENETRD_CTL, 0x1000);
-	psc_write_word(PSC_ENETRD_CMD, 0x1100);
-	psc_write_word(PSC_ENETRD_CMD+0x10, 0x1100);
-                                        
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET0, 0x1100);
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET1, 0x1100);
+
 	psc_write_word(PSC_ENETWR_CTL, 0x8800);
 	psc_write_word(PSC_ENETWR_CTL, 0x1000);
-	psc_write_word(PSC_ENETWR_CMD, 0x1100);
-	psc_write_word(PSC_ENETWR_CMD+0x10, 0x1100);
-}
-
-/* Bit-reverse one byte of an ethernet hardware address. */
-
-static int bitrev(int b)
-{
-    int d = 0, i;
-
-    for (i = 0; i < 8; ++i, b >>= 1)
-	d = (d << 1) | (b & 1);
-    return d;
+	psc_write_word(PSC_ENETWR_CMD + PSC_SET0, 0x1100);
+	psc_write_word(PSC_ENETWR_CMD + PSC_SET1, 0x1100);
 }
 
 /*
- * 	Not really much of a probe. The hardware table tells us if this
- *	model of Macintrash has a MACE (AV macintoshes)
+ * Not really much of a probe. The hardware table tells us if this
+ * model of Macintrash has a MACE (AV macintoshes)
  */
  
-int mace68k_probe(struct net_device *unused)
+int mace_probe(struct net_device *unused)
 {
 	int j;
-	static int once;
-	struct mace68k_data *mp;
+	struct mace_data *mp;
 	unsigned char *addr;
 	struct net_device *dev;
 	unsigned char checksum = 0;
+	static int found = 0;
 	
-	/*
-	 *	There can be only one...
-	 */
-	 
-	if (once) return -ENODEV;
-	
-	once = 1;
+	if (found || macintosh_config->ether_type != MAC_ETHER_MACE) return -ENODEV;
 
-	if (macintosh_config->ether_type != MAC_ETHER_MACE) return -ENODEV;
+	found = 1;	/* prevent 'finding' one on every device probe */
 
-	printk("MACE ethernet should be present ");
-	
 	dev = init_etherdev(0, PRIV_BYTES);
-	if(dev==NULL)
-	{
-		printk("no free memory.\n");
-		return -ENOMEM;
-	}		
-	mp = (struct mace68k_data *) dev->priv;
+	if (!dev) return -ENOMEM;
+
+	mp = (struct mace_data *) dev->priv;
 	dev->base_addr = (u32)MACE_BASE;
 	mp->mace = (volatile struct mace *) MACE_BASE;
 	
-	printk("at 0x%p", mp->mace);
-	
-	/*
-	 *	16K RX ring and 4K TX ring should do nicely
-	 */
-
-	mp->rx_ring=(void *)__get_free_pages(GFP_KERNEL, 2);
-	mp->tx_ring=(void *)__get_free_page(GFP_KERNEL);
-	
-	printk(".");
-	
-	if(mp->tx_ring==NULL || mp->rx_ring==NULL)
-	{
-		if(mp->tx_ring)
-			free_page((u32)mp->tx_ring);
-//		if(mp->rx_ring)
-//			__free_pages(mp->rx_ring,2);
-		printk("\nNo memory for ring buffers.\n");
-		return -ENOMEM;
-	}
-
-	/* We want the receive data to be uncached. We dont care about the
-	   byte reading order */
-
-	printk(".");	
-	kernel_set_cachemode((void *)mp->rx_ring, 16384, IOMAP_NOCACHE_NONSER);	
-	
-	printk(".");	
-	/* The transmit buffer needs to be write through */
-	kernel_set_cachemode((void *)mp->tx_ring, 4096, IOMAP_WRITETHROUGH);
-
-	printk(" Ok\n");	
 	dev->irq = IRQ_MAC_MACE;
-	printk(KERN_INFO "%s: MACE at", dev->name);
+	mp->dma_intr = IRQ_MAC_MACE_DMA;
 
 	/*
-	 *	The PROM contains 8 bytes which total 0xFF when XOR'd
-	 *	together. Due to the usual peculiar apple brain damage
-	 *	the bytes are spaced out in a strange boundary and the
-	 * 	bits are reversed.
+	 * The PROM contains 8 bytes which total 0xFF when XOR'd
+	 * together. Due to the usual peculiar apple brain damage
+	 * the bytes are spaced out in a strange boundary and the
+	 * bits are reversed.
 	 */
 
 	addr = (void *)MACE_PROM;
 		 
-	for (j = 0; j < 6; ++j)
-	{
+	for (j = 0; j < 6; ++j) {
 		u8 v=bitrev(addr[j<<4]);
-		checksum^=v;
+		checksum ^= v;
 		dev->dev_addr[j] = v;
-		printk("%c%.2x", (j ? ':' : ' '), dev->dev_addr[j]);
 	}
-	for (; j < 8; ++j)
-	{
-		checksum^=bitrev(addr[j<<4]);
+	for (; j < 8; ++j) {
+		checksum ^= bitrev(addr[j<<4]);
 	}
 	
-	if(checksum!=0xFF)
-	{
-		printk(" (invalid checksum)\n");
-		return -ENODEV;
-	}		
-	printk("\n");
+	if (checksum != 0xFF) return -ENODEV;
 
 	memset(&mp->stats, 0, sizeof(mp->stats));
-	init_timer(&mp->tx_timeout);
-	mp->timeout_active = 0;
 
-	dev->open = mace68k_open;
-	dev->stop = mace68k_close;
-	dev->hard_start_xmit = mace68k_xmit_start;
-	dev->get_stats = mace68k_stats;
-	dev->set_multicast_list = mace68k_set_multicast;
-	dev->set_mac_address = mace68k_set_address;
+	dev->open		= mace_open;
+	dev->stop		= mace_close;
+	dev->hard_start_xmit	= mace_xmit_start;
+	dev->tx_timeout		= mace_tx_timeout;
+	dev->watchdog_timeo	= TX_TIMEOUT;
+	dev->get_stats		= mace_stats;
+	dev->set_multicast_list	= mace_set_multicast;
+	dev->set_mac_address	= mace_set_address;
 
 	ether_setup(dev);
 
-	mp = (struct mace68k_data *) dev->priv;
-	mp->maccc = ENXMT | ENRCV;
-	mp->dma_intr = IRQ_MAC_MACE_DMA;
+	printk(KERN_INFO "%s: 68K MACE, hardware address %.2X", dev->name, dev->dev_addr[0]);
+	for (j = 1 ; j < 6 ; j++) printk(":%.2X", dev->dev_addr[j]);
+	printk("\n");
 
-	psc_write_word(PSC_ENETWR_CTL, 0x9000);
-	psc_write_word(PSC_ENETRD_CTL, 0x9000);
-	psc_write_word(PSC_ENETWR_CTL, 0x0400);
-	psc_write_word(PSC_ENETRD_CTL, 0x0400);
-                                        	
-	/* apple's driver doesn't seem to do this */
-	/* except at driver shutdown time...      */
-#if 0
-	mace68k_dma_off(dev);
-#endif
+	return 0;
+}
+
+/*
+ * Load the address on a mace controller.
+ */
+
+static int mace_set_address(struct net_device *dev, void *addr)
+{
+	unsigned char *p = addr;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
+	volatile struct mace *mb = mp->mace;
+	int i;
+	unsigned long flags;
+	u8 maccc;
+
+	save_flags(flags);
+	cli();
+
+	maccc = mb->maccc;
+
+	/* load up the hardware address */
+	mb->iac = ADDRCHG | PHYADDR;
+	while ((mb->iac & ADDRCHG) != 0);
+	
+	for (i = 0; i < 6; ++i) {
+		mb->padr = dev->dev_addr[i] = p[i];
+	}
+
+	mb->maccc = maccc;
+	restore_flags(flags);
 
 	return 0;
 }
 
 /*
- *	Reset a MACE controller
+ * Open the Macintosh MACE. Most of this is playing with the DMA
+ * engine. The ethernet chip is quite friendly.
  */
  
-static void mace68k_reset(struct net_device *dev)
+static int mace_open(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
+#if 0
 	int i;
 
-	/* soft-reset the chip */
 	i = 200;
 	while (--i) {
 		mb->biucc = SWRST;
@@ -344,18 +297,59 @@
 		break;
 	}
 	if (!i) {
-		printk(KERN_ERR "mace: cannot reset chip!\n");
-		return;
+		printk(KERN_ERR "%s: software reset failed!!\n", dev->name);
+		return -EAGAIN;
 	}
+#endif
 
 	mb->biucc = XMTSP_64;
-	mb->imr = 0xff;		/* disable all intrs for now */
-	i = mb->ir;
-	mb->maccc = 0;		/* turn off tx, rx */
-	mb->utr = RTRD;
-	mb->fifocc = RCVFW_64;
-	mb->xmtfc = AUTO_PAD_XMIT;	/* auto-pad short frames */
+	mb->fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST;
+	mb->xmtfc = AUTO_PAD_XMIT;
+	mb->plscc = PORTSEL_AUI;
+	/* mb->utr = RTRD; */
+
+	if (request_irq(dev->irq, mace_interrupt, 0, dev->name, dev)) {
+		printk(KERN_ERR "%s: can't get irq %d\n", dev->name, dev->irq);
+		return -EAGAIN;
+	}
+	if (request_irq(mp->dma_intr, mace_dma_intr, 0, dev->name, dev)) {
+		printk(KERN_ERR "%s: can't get irq %d\n", dev->name, mp->dma_intr);
+		free_irq(dev->irq, dev);
+		return -EAGAIN;
+	}
+
+	/* Allocate the DMA ring buffers */
+
+	mp->rx_ring = (void *) __get_free_pages(GFP_DMA, N_RX_PAGES);
+	mp->tx_ring = (void *) __get_free_pages(GFP_DMA, 0);
+	
+	if (mp->tx_ring==NULL || mp->rx_ring==NULL) {
+		if (mp->rx_ring) free_pages((u32) mp->rx_ring, N_RX_PAGES);
+		if (mp->tx_ring) free_pages((u32) mp->tx_ring, 0);
+		free_irq(dev->irq, dev);
+		free_irq(mp->dma_intr, dev);
+		printk(KERN_ERR "%s: unable to allocate DMA buffers\n", dev->name);
+		return -ENOMEM;
+	}
+
+	mp->rx_ring_phys = (unsigned char *) virt_to_bus(mp->rx_ring);
+	mp->tx_ring_phys = (unsigned char *) virt_to_bus(mp->tx_ring);
+
+	/* We want the Rx buffer to be uncached and the Tx buffer to be writethrough */
+
+	kernel_set_cachemode((void *)mp->rx_ring, N_RX_PAGES * PAGE_SIZE, IOMAP_NOCACHE_NONSER);	
+	kernel_set_cachemode((void *)mp->tx_ring, PAGE_SIZE, IOMAP_WRITETHROUGH);
+
+	mace_dma_off(dev);
+
+	/* Not sure what these do */
 
+	psc_write_word(PSC_ENETWR_CTL, 0x9000);
+	psc_write_word(PSC_ENETRD_CTL, 0x9000);
+	psc_write_word(PSC_ENETWR_CTL, 0x0400);
+	psc_write_word(PSC_ENETRD_CTL, 0x0400);
+
+#if 0
 	/* load up the hardware address */
 	
 	mb->iac = ADDRCHG | PHYADDR;
@@ -374,245 +368,157 @@
 		mb->ladrf = 0;
 
 	mb->plscc = PORTSEL_GPSI + ENPLSIO;
-}
-
-/*
- *	Load the address on a mace controller.
- */
- 
-static int mace68k_set_address(struct net_device *dev, void *addr)
-{
-	unsigned char *p = addr;
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	volatile struct mace *mb = mp->mace;
-	int i;
-	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	mb->maccc = ENXMT | ENRCV;
+	mb->imr = RCVINT;
+#endif
 
-	/* load up the hardware address */
-	mb->iac = ADDRCHG | PHYADDR;
-	while ((mb->iac & ADDRCHG) != 0);
+	mace_rxdma_reset(dev);
+	mace_txdma_reset(dev);
 	
-	for (i = 0; i < 6; ++i)
-		mb->padr = dev->dev_addr[i] = p[i];
-	/* note: setting ADDRCHG clears ENRCV */
-	mb->maccc = mp->maccc;
-	restore_flags(flags);
 	return 0;
 }
 
 /*
- *	Open the Macintosh MACE. Most of this is playing with the DMA
- *	engine. The ethernet chip is quite friendly.
+ * Shut down the mace and its interrupt channel
  */
  
-static int mace68k_open(struct net_device *dev)
+static int mace_close(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 
-	/* reset the chip */
-	mace68k_reset(dev);
-
-	mp->rx_done = 0;
-	mace68k_rxdma_reset(dev);
-
-	/*
-	 *	The interrupt is fixed and comes off the PSC.
-	 */
-	 
-	if (request_irq(dev->irq, mace68k_interrupt, 0, "68K MACE", dev))
-	{
-		printk(KERN_ERR "MACE: can't get irq %d\n", dev->irq);
-		return -EAGAIN;
-	}
+	mb->maccc = 0;		/* disable rx and tx	 */
+	mb->imr = 0xFF;		/* disable all irqs	 */
+	mace_dma_off(dev);	/* disable rx and tx dma */
 
-	/*
-	 *	Ditto the DMA interrupt.
-	 */
-	 
-	if (request_irq(IRQ_MAC_MACE_DMA, mace68k_dma_intr, 0, "68K MACE DMA",
-			dev))
-	{
-		printk(KERN_ERR "MACE: can't get irq %d\n", IRQ_MAC_MACE_DMA);
-		return -EAGAIN;
-	}
+	free_irq(dev->irq, dev);
+	free_irq(IRQ_MAC_MACE_DMA, dev);
 
-	/* Activate the Mac DMA engine */
+	free_pages((u32) mp->rx_ring, N_RX_PAGES);
+	free_pages((u32) mp->tx_ring, 0);
 
-	mp->tx_slot = 0;		/* Using register set 0 */
-	mp->tx_count = 1;		/* 1 Buffer ready for use */
-	mace68k_txdma_reset(dev);
-	
-	/* turn it on! */
-	mb->maccc = mp->maccc;
-	/* enable all interrupts except receive interrupts */
-	mb->imr = RCVINT;
 	return 0;
 }
 
 /*
- *	Shut down the mace and its interrupt channel
+ * Transmit a frame
  */
  
-static int mace68k_close(struct net_device *dev)
+static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	volatile struct mace *mb = mp->mace;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 
-	/* disable rx and tx */
-	mb->maccc = 0;
-	mb->imr = 0xff;		/* disable all intrs */
+	/* Stop the queue if the buffer is full */
 
-	/* disable rx and tx dma */
+	if (!mp->tx_count) {
+		netif_stop_queue(dev);
+		return 1;
+	}
+	mp->tx_count--;
+	
+	mp->stats.tx_packets++;
+	mp->stats.tx_bytes += skb->len;
 
-	mace68k_dma_off(dev);
+	/* We need to copy into our xmit buffer to take care of alignment and caching issues */
 
-	free_irq(dev->irq, dev);
-	free_irq(IRQ_MAC_MACE_DMA, dev);
-	return 0;
-}
+	memcpy((void *) mp->tx_ring, skb->data, skb->len);
 
-static inline void mace68k_set_timeout(struct net_device *dev)
-{
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	unsigned long flags;
+	/* load the Tx DMA and fire it off */
 
-	save_flags(flags);
-	cli();
-	if (mp->timeout_active)
-		del_timer(&mp->tx_timeout);
-	mp->tx_timeout.expires = jiffies + TX_TIMEOUT;
-	mp->tx_timeout.function = mace68k_tx_timeout;
-	mp->tx_timeout.data = (unsigned long) dev;
-	add_timer(&mp->tx_timeout);
-	mp->timeout_active = 1;
-	restore_flags(flags);
-}
+	psc_write_long(PSC_ENETWR_ADDR + mp->tx_slot, (u32)  mp->tx_ring_phys);
+	psc_write_long(PSC_ENETWR_LEN + mp->tx_slot, skb->len);
+	psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x9800);
 
-/*
- *	Transmit a frame
- */
- 
-static int mace68k_xmit_start(struct sk_buff *skb, struct net_device *dev)
-{
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	/*
-	 *	This may need atomic types ???
-	 */
+	mp->tx_slot ^= 0x10;
+
+	dev_kfree_skb(skb);
 
-	printk("mace68k_xmit_start: mp->tx_count = %d, dev->tbusy = %d, mp->tx_ring = %p (%p)\n",
-		mp->tx_count, dev->tbusy,
-		mp->tx_ring, virt_to_bus(mp->tx_ring));
-	psc_debug_dump();
-
-	if(mp->tx_count == 0)
-	{
-		dev->tbusy=1;
-		mace68k_dma_intr(IRQ_MAC_MACE_DMA, dev, NULL);
-		return 1;
-	}
-	mp->tx_count--;
-	
-	/*
-	 *	FIXME:
-	 *	This is hackish. The memcpy probably isnt needed but
-	 *	the rules for alignment are not known. Ideally we'd like
-	 *	to just blast the skb directly to ethernet. We also don't
-	 *	use the ring properly - just a one frame buffer. That
-	 *	also requires cache pushes ;).
-	 */
-	memcpy((void *)mp->tx_ring, skb, skb->len);
-	psc_write_long(PSC_ENETWR_ADDR + mp->tx_slot, virt_to_bus(mp->tx_ring));
-        psc_write_long(PSC_ENETWR_LEN + mp->tx_slot, skb->len);
-        psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x9800);                       
-	mp->stats.tx_packets++;
-	mp->stats.tx_bytes+=skb->len;
-        dev_kfree_skb(skb);
 	return 0;
 }
 
-static struct net_device_stats *mace68k_stats(struct net_device *dev)
+static struct net_device_stats *mace_stats(struct net_device *dev)
 {
-	struct mace68k_data *p = (struct mace68k_data *) dev->priv;
+	struct mace_data *p = (struct mace_data *) dev->priv;
 	return &p->stats;
 }
 
-static void mace68k_set_multicast(struct net_device *dev)
+static void mace_set_multicast(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
-	int i, j, k, b;
+	int i, j;
 	u32 crc;
+	u8 maccc;
+
+	maccc = mb->maccc;
+	mb->maccc &= ~PROM;
 
-	mp->maccc &= ~PROM;
-	if (dev->flags & IFF_PROMISC)
-	{
-		mp->maccc |= PROM;
-	} else
-	{
+	if (dev->flags & IFF_PROMISC) {
+		mb->maccc |= PROM;
+	} else {
 		unsigned char multicast_filter[8];
 		struct dev_mc_list *dmi = dev->mc_list;
 
-		if (dev->flags & IFF_ALLMULTI)
-		{
-			for (i = 0; i < 8; i++)
-				multicast_filter[i] = 0xff;
-		} else
-		{
+		if (dev->flags & IFF_ALLMULTI) {
+			for (i = 0; i < 8; i++) {
+				multicast_filter[i] = 0xFF;
+			}
+		} else {
 			for (i = 0; i < 8; i++)
 				multicast_filter[i] = 0;
-			for (i = 0; i < dev->mc_count; i++)
-			{
+			for (i = 0; i < dev->mc_count; i++) {
 				crc = ether_crc_le(6, dmi->dmi_addr);
 				j = crc >> 26;	/* bit number in multicast_filter */
 				multicast_filter[j >> 3] |= 1 << (j & 7);
 				dmi = dmi->next;
 			}
 		}
-#if 0
-		printk("Multicast filter :");
-		for (i = 0; i < 8; i++)
-			printk("%02x ", multicast_filter[i]);
-		printk("\n");
-#endif
 
 		mb->iac = ADDRCHG | LOGADDR;
-		while ((mb->iac & ADDRCHG) != 0);
+		while (mb->iac & ADDRCHG);
 		
-		for (i = 0; i < 8; ++i)
+		for (i = 0; i < 8; ++i) {
 			mb->ladrf = multicast_filter[i];
+		}
 	}
-	/* reset maccc */
-	mb->maccc = mp->maccc;
+
+	mb->maccc = maccc;
 }
 
 /*
- *	Miscellaneous interrupts are handled here. We may end up 
- *	having to bash the chip on the head for bad errors
+ * Miscellaneous interrupts are handled here. We may end up 
+ * having to bash the chip on the head for bad errors
  */
  
-static void mace68k_handle_misc_intrs(struct mace68k_data *mp, int intr)
+static void mace_handle_misc_intrs(struct mace_data *mp, int intr)
 {
 	volatile struct mace *mb = mp->mace;
-	static int mace68k_babbles, mace68k_jabbers;
+	static int mace_babbles, mace_jabbers;
 
-	if (intr & MPCO)
+	if (intr & MPCO) {
 		mp->stats.rx_missed_errors += 256;
+	}
 	mp->stats.rx_missed_errors += mb->mpc;	/* reading clears it */
-	if (intr & RNTPCO)
+
+	if (intr & RNTPCO) {
 		mp->stats.rx_length_errors += 256;
+	}
 	mp->stats.rx_length_errors += mb->rntpc;	/* reading clears it */
-	if (intr & CERR)
+
+	if (intr & CERR) {
 		++mp->stats.tx_heartbeat_errors;
-	if (intr & BABBLE)
-		if (mace68k_babbles++ < 4)
+	}
+	if (intr & BABBLE) {
+		if (mace_babbles++ < 4) {
 			printk(KERN_DEBUG "mace: babbling transmitter\n");
-	if (intr & JABBER)
-		if (mace68k_jabbers++ < 4)
+		}
+	}
+	if (intr & JABBER) {
+		if (mace_jabbers++ < 4) {
 			printk(KERN_DEBUG "mace: jabbering transceiver\n");
+		}
+	}
 }
 
 /*
@@ -620,191 +526,172 @@
  *	the DMA completion)
  */
  
-static void mace68k_xmit_error(struct net_device *dev)
+static void mace_xmit_error(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 	u8 xmtfs, xmtrc;
 	
 	xmtfs = mb->xmtfs;
 	xmtrc = mb->xmtrc;
 	
-	if(xmtfs & XMTSV)
-	{
-		if(xmtfs & UFLO)
-		{
+	if (xmtfs & XMTSV) {
+		if (xmtfs & UFLO) {
 			printk("%s: DMA underrun.\n", dev->name);
 			mp->stats.tx_errors++;
 			mp->stats.tx_fifo_errors++;
-			mace68k_reset(dev);
+			mace_txdma_reset(dev);
 		}
-		if(xmtfs & RTRY)
+		if (xmtfs & RTRY) {
 			mp->stats.collisions++;
+		}
 	}			
-	mark_bh(NET_BH);
 }
 
 /*
  *	A receive interrupt occurred.
  */
  
-static void mace68k_recv_interrupt(struct net_device *dev)
+static void mace_recv_interrupt(struct net_device *dev)
 {
-//	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+/*	struct mace_data *mp = (struct mace_data *) dev->priv; */
 //	volatile struct mace *mb = mp->mace;
 }
 
 /*
- *	Process the chip interrupt
+ * Process the chip interrupt
  */
  
-static void mace68k_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 	u8 ir;
 	
 	ir = mb->ir;
-	mace68k_handle_misc_intrs(mp, ir);
+	mace_handle_misc_intrs(mp, ir);
 	
-	if(ir&XMTINT)
-		mace68k_xmit_error(dev);
-	if(ir&RCVINT)
-		mace68k_recv_interrupt(dev);
+	if (ir & XMTINT) {
+		mace_xmit_error(dev);
+	}
+	if (ir & RCVINT) {
+		mace_recv_interrupt(dev);
+	}
 }
 
-static void mace68k_tx_timeout(unsigned long data)
+static void mace_tx_timeout(struct net_device *dev)
 {
-//	struct net_device *dev = (struct net_device *) data;
-//	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+/*	struct mace_data *mp = (struct mace_data *) dev->priv; */
 //	volatile struct mace *mb = mp->mace;
 }
 
 /*
- *	Handle a newly arrived frame
+ * Handle a newly arrived frame
  */
  
 static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	struct sk_buff *skb;
 
-	if(mf->status&RS_OFLO)
-	{
+	if (mf->status & RS_OFLO) {
 		printk("%s: fifo overflow.\n", dev->name);
 		mp->stats.rx_errors++;
 		mp->stats.rx_fifo_errors++;
 	}
-	if(mf->status&(RS_CLSN|RS_FRAMERR|RS_FCSERR))
+	if (mf->status&(RS_CLSN|RS_FRAMERR|RS_FCSERR))
 		mp->stats.rx_errors++;
 		
-	if(mf->status&RS_CLSN)
+	if (mf->status&RS_CLSN) {
 		mp->stats.collisions++;
-	if(mf->status&RS_FRAMERR)
+	}
+	if (mf->status&RS_FRAMERR) {
 		mp->stats.rx_frame_errors++;
-	if(mf->status&RS_FCSERR)
+	}
+	if (mf->status&RS_FCSERR) {
 		mp->stats.rx_crc_errors++;
+	}
 		
 	skb = dev_alloc_skb(mf->len+2);
-	if(skb==NULL)
-	{
+	if (!skb) {
 		mp->stats.rx_dropped++;
 		return;
 	}
 	skb_reserve(skb,2);
 	memcpy(skb_put(skb, mf->len), mf->data, mf->len);
 	
+	skb->dev = dev;
 	skb->protocol = eth_type_trans(skb, dev);
 	netif_rx(skb);
 	dev->last_rx = jiffies;
 	mp->stats.rx_packets++;
-	mp->stats.rx_bytes+=mf->len;
+	mp->stats.rx_bytes += mf->len;
 }
 
 /*
- *	The PSC has passed us a DMA interrupt event.
+ * The PSC has passed us a DMA interrupt event.
  */
  
-static void mace68k_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
+static void mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
+	int left, head;
+	u16 status;
+	u32 baka;
 
-#if 0
-	u32 psc_status;
-	
-	/* It seems this must be allowed to stabilise ?? */
-	
-	while((psc_status=psc_read_long(0x0804))!=psc_read_long(0x0804));
+	/* Not sure what this does */
+
+	while ((baka = psc_read_long(PSC_MYSTERY)) != psc_read_long(PSC_MYSTERY));
+	if (!(baka & 0x60000000)) return;
 
 	/*
-	 *	Was this an ethernet event ?
+	 * Process the read queue
 	 */
-	 	
-	if(psc_status&0x60000000)
-	{
-#endif
-		/*
-		 *	Process the read queue
-		 */
 		 
-		u16 psc_status = psc_read_word(PSC_ENETRD_CTL);
+	status = psc_read_word(PSC_ENETRD_CTL);
 		
-		printk("mace68k_dma_intr: PSC_ENETRD_CTL = %04X\n", (uint) psc_status);
-
-		if (psc_status & 0x2000) {
-			mace68k_rxdma_reset(dev);
-			mp->rx_done = 0;
-		} else if (psc_status & 0x100) {
-			int left;
-			
-			psc_write_word(PSC_ENETRD_CMD + mp->rx_slot, 0x1100);
-			left=psc_read_long(PSC_ENETRD_LEN + mp->rx_slot);
-			/* read packets */	
-			
-			while(mp->rx_done < left)
-			{
-				struct mace_frame *mf=((struct mace_frame *)
-					mp->rx_ring)+mp->rx_done++;
-				mace_dma_rx_frame(dev, mf);
-			}
+	if (status & 0x2000) {
+		mace_rxdma_reset(dev);
+	} else if (status & 0x0100) {
+		psc_write_word(PSC_ENETRD_CMD + mp->rx_slot, 0x1100);
+
+		left = psc_read_long(PSC_ENETRD_LEN + mp->rx_slot);
+		head = N_RX_RING - left;
+
+		/* Loop through the ring buffer and process new packages */
+
+		while (mp->rx_tail < head) {
+			mace_dma_rx_frame(dev, (struct mace_frame *) (mp->rx_ring + (mp->rx_tail * 0x0800)));
+			mp->rx_tail++;
+		}
 			
-			if(left == 0)	/* Out of DMA room */
-			{
-				psc_load_rxdma_base(mp->rx_slot, 
-					(void *)virt_to_phys(mp->rx_ring));
-				mp->rx_slot^=16;
-				mp->rx_done = 0;
-			}
-			else
-			{
-				psc_write_word(PSC_ENETRD_CMD+mp->rx_slot,
-					0x9800);
-			}
-					
+		/* If we're out of buffers in this ring then switch to */
+		/* the other set, otherwise just reactivate this one.  */
+
+		if (!left) {
+			mace_load_rxdma_base(dev, mp->rx_slot);
+			mp->rx_slot ^= 0x10;
+		} else {
+			psc_write_word(PSC_ENETRD_CMD + mp->rx_slot, 0x9800);
 		}
+	}
 		
-		/*
-		 *	Process the write queue
-		 */
-		 
-		psc_status = psc_read_word(PSC_ENETWR_CTL);
-		printk("mace68k_dma_intr: PSC_ENETWR_CTL = %04X\n", (uint) psc_status);
+	/*
+	 * Process the write queue
+	 */
 
-		/* apple's driver seems to loop over this until neither */
-		/* condition is true.    - jmt                          */
+	status = psc_read_word(PSC_ENETWR_CTL);
 
-		if (psc_status & 0x2000) {
-			mace68k_txdma_reset(dev);
-		} else if (psc_status & 0x0100) {
-			psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x0100);
-			mp->tx_slot ^=16;
-			mp->tx_count++;
-			dev->tbusy = 0;
-			mark_bh(NET_BH);
-		}
-#if 0
+	if (status & 0x2000) {
+		mace_txdma_reset(dev);
+	} else if (status & 0x0100) {
+		psc_write_word(PSC_ENETWR_CMD + mp->tx_sloti, 0x0100);
+		mp->tx_sloti ^= 0x10;
+		mp->tx_count++;
+		netif_wake_queue(dev);
 	}
-#endif
 }
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/net/macsonic.c b/drivers/net/macsonic.c
--- a/drivers/net/macsonic.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/net/macsonic.c	Wed Jul 24 14:03:36 2002
@@ -20,6 +20,9 @@
  *		  and duplicating packets. Needs more testing.
  *
  * 99/01/03 MSch: upgraded to version 0.92 of the core driver, fixed.
+ * 
+ * 00/10/31 sammy@oh.verio.com: Updated driver for 2.4 kernels, fixed problems
+ *          on centris.
  */
 
 #include <linux/kernel.h>
@@ -46,6 +49,7 @@
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_via.h>
+#include <asm/pgalloc.h>
 
 #include <linux/errno.h>
 
@@ -58,9 +62,21 @@
 
 #include "sonic.h"
 
+#define SONIC_READ(reg) \
+	nubus_readl(base_addr+(reg))
+#define SONIC_WRITE(reg,val) \
+	nubus_writel((val), base_addr+(reg))
+#define sonic_read(dev, reg) \
+	nubus_readl((dev)->base_addr+(reg))
+#define sonic_write(dev, reg, val) \
+	nubus_writel((val), (dev)->base_addr+(reg))
+
+
 static int sonic_debug;
 static int sonic_version_printed;
 
+static int reg_offset;
+
 extern int macsonic_probe(struct net_device* dev);
 extern int mac_onboard_sonic_probe(struct net_device* dev);
 extern int mac_nubus_sonic_probe(struct net_device* dev);
@@ -95,7 +111,7 @@
    resource directories */
 #define DAYNA_SONIC_MAC_ADDR	0xffe004
 
-#define SONIC_READ_PROM(addr) readb(prom_addr+addr)
+#define SONIC_READ_PROM(addr) nubus_readb(prom_addr+addr)
 
 int __init macsonic_probe(struct net_device* dev)
 {
@@ -125,36 +141,42 @@
 
 int __init macsonic_init(struct net_device* dev)
 {
-	struct sonic_local* lp = (struct sonic_local *)dev->priv;
+	struct sonic_local* lp;
 	int i;
 
 	/* Allocate the entire chunk of memory for the descriptors.
            Note that this cannot cross a 64K boundary. */
 	for (i = 0; i < 20; i++) {
 		unsigned long desc_base, desc_top;
-		if ((lp->sonic_desc = 
-		     kmalloc(SIZEOF_SONIC_DESC
-			     * SONIC_BUS_SCALE(lp->dma_bitmode), GFP_KERNEL | GFP_DMA)) == NULL) {
+		if((lp = kmalloc(sizeof(struct sonic_local), GFP_KERNEL | GFP_DMA)) == NULL) {
 			printk(KERN_ERR "%s: couldn't allocate descriptor buffers\n", dev->name);
 			return -ENOMEM;
 		}
-		desc_base = (unsigned long) lp->sonic_desc;
-		desc_top = desc_base + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode);
+
+		desc_base = (unsigned long) lp;
+		desc_top = desc_base + sizeof(struct sonic_local);
 		if ((desc_top & 0xffff) >= (desc_base & 0xffff))
 			break;
 		/* Hmm. try again (FIXME: does this actually work?) */
-		kfree(lp->sonic_desc);
+		kfree(lp);
 		printk(KERN_DEBUG
 		       "%s: didn't get continguous chunk [%08lx - %08lx], trying again\n",
 		       dev->name, desc_base, desc_top);
 	}
 
-	if (lp->sonic_desc == NULL) {
+	if (lp == NULL) {
 		printk(KERN_ERR "%s: tried 20 times to allocate descriptor buffers, giving up.\n",
 		       dev->name);
 		return -ENOMEM;
 	}		       
 
+	dev->priv = lp;
+
+#if 0
+	/* this code is only here as a curiousity...   mainly, where the 
+	   fuck did SONIC_BUS_SCALE come from, and what was it supposed
+	   to do?  the normal allocation works great for 32 bit stuffs..  */
+
 	/* Now set up the pointers to point to the appropriate places */
 	lp->cda = lp->sonic_desc;
 	lp->tda = lp->cda + (SIZEOF_SONIC_CDA * SONIC_BUS_SCALE(lp->dma_bitmode));
@@ -163,24 +185,33 @@
 	lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
 			     * SONIC_BUS_SCALE(lp->dma_bitmode));
 
+#endif
+	
+	memset(lp, 0, sizeof(struct sonic_local));
+
+	lp->cda_laddr = (unsigned int)&(lp->cda);
+	lp->tda_laddr = (unsigned int)lp->tda;
+	lp->rra_laddr = (unsigned int)lp->rra;
+	lp->rda_laddr = (unsigned int)lp->rda;
+
 	/* FIXME, maybe we should use skbs */
 	if ((lp->rba = (char *)
 	     kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
 		printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
-		kfree(lp->sonic_desc);
-		lp->sonic_desc = NULL;
 		return -ENOMEM;
 	}
 
+	lp->rba_laddr = (unsigned int)lp->rba;
+
 	{
 		int rs, ds;
 
 		/* almost always 12*4096, but let's not take chances */
 		rs = ((SONIC_NUM_RRS * SONIC_RBSIZE + 4095) / 4096) * 4096;
 		/* almost always under a page, but let's not take chances */
-		ds = ((SIZEOF_SONIC_DESC + 4095) / 4096) * 4096;
+		ds = ((sizeof(struct sonic_local) + 4095) / 4096) * 4096;
 		kernel_set_cachemode(lp->rba, rs, IOMAP_NOCACHE_SER);
-		kernel_set_cachemode(lp->sonic_desc, ds, IOMAP_NOCACHE_SER);
+		kernel_set_cachemode(lp, ds, IOMAP_NOCACHE_SER);
 	}
 	
 #if 0
@@ -275,8 +306,8 @@
 {
 	/* Bwahahaha */
 	static int once_is_more_than_enough;
-	struct sonic_local* lp;
 	int i;
+	int dma_bitmode;
 	
 	if (once_is_more_than_enough)
 		return -ENODEV;
@@ -333,8 +364,13 @@
 	if (dev == NULL)
 		return -ENOMEM;
 
-	lp = (struct sonic_local*) dev->priv;
-	memset(lp, 0, sizeof(struct sonic_local));
+	if(dev->priv) {
+		printk("%s: warning! sonic entering with priv already allocated!\n",
+		       dev->name);
+		printk("%s: discarding, will attempt to reallocate\n", dev->name);
+		dev->priv = NULL;
+	}
+
 	/* Danger!  My arms are flailing wildly!  You *must* set this
            before using sonic_read() */
 
@@ -356,8 +392,11 @@
 
 	/* The PowerBook's SONIC is 16 bit always. */
 	if (macintosh_config->ident == MAC_MODEL_PB520) {
-		lp->reg_offset = 0;
-		lp->dma_bitmode = 0;
+		reg_offset = 0;
+		dma_bitmode = 0;
+	} else if (macintosh_config->ident == MAC_MODEL_C610) {
+		reg_offset = 0;
+		dma_bitmode = 1;
 	} else {
 		/* Some of the comm-slot cards are 16 bit.  But some
                    of them are not.  The 32-bit cards use offset 2 and
@@ -368,27 +407,41 @@
 
 		/* Technically this is not necessary since we zeroed
                    it above */
-		lp->reg_offset = 0;
-		lp->dma_bitmode = 0;
+		reg_offset = 0;
+		dma_bitmode = 0;
 		sr = sonic_read(dev, SONIC_SR);
 		if (sr == 0 || sr == 0xffff) {
-			lp->reg_offset = 2;
+			reg_offset = 2;
 			/* 83932 is 0x0004, 83934 is 0x0100 or 0x0101 */
 			sr = sonic_read(dev, SONIC_SR);
-			lp->dma_bitmode = 1;
+			dma_bitmode = 1;
 			
 		}
 		printk(KERN_INFO
 		       "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
-		       dev->name, sr, lp->dma_bitmode?32:16, lp->reg_offset);
+		       dev->name, sr, dma_bitmode?32:16, reg_offset);
 	}
+	
 
-
+	/* this carries my sincere apologies -- by the time I got to updating
+	   the driver, support for "reg_offsets" appeares nowhere in the sonic
+	   code, going back for over a year.  Fortunately, my Mac does't seem
+	   to use whatever this was.
+
+	   If you know how this is supposed to be implemented, either fix it,
+	   or contact me (sammy@oh.verio.com) to explain what it is. --Sam */
+	   
+	if(reg_offset) {
+		printk("%s: register offset unsupported.  please fix this if you know what it is.\n", dev->name);
+		return -ENODEV;
+	}
+	
 	/* Software reset, then initialize control registers. */
 	sonic_write(dev, SONIC_CMD, SONIC_CR_RST);
 	sonic_write(dev, SONIC_DCR, SONIC_DCR_BMS |
 		    SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_EXBUS |
-		    (lp->dma_bitmode ? SONIC_DCR_DW : 0));
+		    (dma_bitmode ? SONIC_DCR_DW : 0));
+
 	/* This *must* be written back to in order to restore the
            extended programmable output bits */
 	sonic_write(dev, SONIC_DCR2, 0);
@@ -452,7 +505,7 @@
 	u16 sonic_dcr;
 	int id;
 	int i;
-	int reg_offset, dma_bitmode;
+	int dma_bitmode;
 
 	/* Find the first SONIC that hasn't been initialized already */
 	while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK,
@@ -538,8 +591,6 @@
 	memset(lp, 0, sizeof(struct sonic_local));
 	/* Danger!  My arms are flailing wildly!  You *must* set this
            before using sonic_read() */
-	lp->reg_offset = reg_offset;
-	lp->dma_bitmode = dma_bitmode;
 	dev->base_addr = base_addr;
 	dev->irq = SLOT2IRQ(ndev->board->slot);
 
@@ -552,6 +603,11 @@
 	printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
 	       dev->name, sonic_read(dev, SONIC_SR), dma_bitmode?32:16, reg_offset);
 
+	if(reg_offset) {
+		printk("%s: register offset unsupported.  please fix this if you know what it is.\n", dev->name);
+		return -ENODEV;
+	}
+
 	/* Software reset, then initialize control registers. */
 	sonic_write(dev, SONIC_CMD, SONIC_CR_RST);
 	sonic_write(dev, SONIC_DCR, sonic_dcr
@@ -614,6 +670,9 @@
 #define vdma_free(baz)
 #define sonic_chiptomem(bat) (bat)
 #define PHYSADDR(quux) (quux)
+
+#define sonic_request_irq       request_irq
+#define sonic_free_irq          free_irq
 
 #include "sonic.c"
 
diff -Nru a/drivers/net/plip.c b/drivers/net/plip.c
--- a/drivers/net/plip.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/net/plip.c	Wed Jul 24 14:03:39 2002
@@ -518,7 +518,7 @@
 	spin_unlock_irq(&nl->lock);
 	if (error == HS_TIMEOUT) {
 		DISABLE(dev->irq);
-		synchronize_irq();
+		synchronize_irq(dev->irq);
 	}
 	disable_parport_interrupts (dev);
 	netif_stop_queue (dev);
@@ -840,7 +840,7 @@
 			if (c0 & 0x08) {
 				spin_unlock_irq(&nl->lock);
 				DISABLE(dev->irq);
-				synchronize_irq();
+				synchronize_irq(dev->irq);
 				if (nl->connection == PLIP_CN_RECEIVE) {
 					/* Interrupted.
 					   We don't need to enable irq,
@@ -1178,7 +1178,7 @@
 
 	netif_stop_queue (dev);
 	DISABLE(dev->irq);
-	synchronize_irq();
+	synchronize_irq(dev->irq);
 
 	if (dev->irq == -1)
 	{
diff -Nru a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
--- a/drivers/net/sgiseeq.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/net/sgiseeq.c	Wed Jul 24 14:03:39 2002
@@ -450,7 +450,7 @@
 	unsigned long flags;
 	int err;
 
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	err = -EAGAIN;
 	if (request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) {
@@ -464,7 +464,7 @@
 	netif_start_queue(dev);
 
 out:
-	__restore_flags(flags);
+	local_irq_restore(flags);
 	return err;
 }
 
diff -Nru a/drivers/net/sonic.h b/drivers/net/sonic.h
--- a/drivers/net/sonic.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/net/sonic.h	Wed Jul 24 14:03:35 2002
@@ -87,6 +87,7 @@
 #define SONIC_FAET              0x2d
 #define SONIC_MPT               0x2e
 
+#define SONIC_DCR2              0x3f
 
 /*
  * SONIC command bits
diff -Nru a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
--- a/drivers/net/tulip/de2104x.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/net/tulip/de2104x.c	Wed Jul 24 14:03:37 2002
@@ -1455,7 +1455,7 @@
 	/* Update the error counts. */
 	__de_get_stats(de);
 
-	synchronize_irq();
+	synchronize_irq(dev->irq);
 	de_clean_rings(de);
 
 	de_init_hw(de);
diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
--- a/drivers/net/wireless/orinoco.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/net/wireless/orinoco.c	Wed Jul 24 14:03:38 2002
@@ -534,10 +534,10 @@
 
 	TRACE_ENTER(priv->ndev->name);
 
-	__cli(); /* FIXME: is this necessary? */
+	local_irq_disable(); /* FIXME: is this necessary? */
 	set_bit(ORINOCO_STATE_DOIRQ, &priv->state);
 	hermes_set_irqmask(hw, irqmask);
-	__sti();
+	local_irq_enable();
 
 	TRACE_EXIT(priv->ndev->name);
 }
diff -Nru a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
--- a/drivers/nubus/nubus.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/nubus/nubus.c	Wed Jul 24 14:03:36 2002
@@ -961,18 +961,18 @@
 	return strlen(ptr);
 }
 
-static int nubus_read_proc(char *buf, char **start, off_t off,
+static int nubus_read_proc(char *page, char **start, off_t off,
 				int count, int *eof, void *data)
 {
 	int nprinted, len, begin = 0;
-	int slot,size;
+	int size = PAGE_SIZE;
 	struct nubus_board* board;
 	
-	len   = sprintf(buf, "Nubus devices found:\n");
+	len   = sprintf(page, "Nubus devices found:\n");
 	/* Walk the list of NuBus boards */
 	for (board = nubus_boards; board != NULL; board = board->next)
 	{
-		nprinted = sprint_nubus_board(board, buf + len, size - len);
+		nprinted = sprint_nubus_board(board, page + len, size - len);
 		if (nprinted < 0)
 			break;
 		len += nprinted;
@@ -983,10 +983,10 @@
 		if (len+begin >= off+count)
 			break;
 	}
-	if (slot==16 || len+begin < off)
+	if (len+begin < off)
 		*eof = 1;
 	off -= begin;
-	*start = buf + off;
+	*start = page + off;
 	len -= off;
 	if (len>count)
 		len = count;
@@ -1009,10 +1009,10 @@
 	}
 }
 
-void __init nubus_init(void)
+static int __init nubus_init(void)
 {
 	if (!MACH_IS_MAC) 
-		return;
+		return 0;
 
 	/* Initialize the NuBus interrupts */
 	if (oss_present) {
@@ -1038,6 +1038,7 @@
 	create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL);
 	nubus_proc_init();
 #endif
+	return 0;
 }
 
 subsys_initcall(nubus_init);
diff -Nru a/drivers/parport/init.c b/drivers/parport/init.c
--- a/drivers/parport/init.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/parport/init.c	Wed Jul 24 14:03:38 2002
@@ -31,6 +31,7 @@
 extern int parport_sunbpp_init(void);
 extern int parport_amiga_init(void);
 extern int parport_mfc3_init(void);
+extern int parport_atari_init(void);
 
 static int parport_setup_ptr __initdata = 0;
 
diff -Nru a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c
--- a/drivers/parport/parport_mfc3.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/parport/parport_mfc3.c	Wed Jul 24 14:03:37 2002
@@ -332,7 +332,7 @@
 int __init parport_mfc3_init(void)
 {
 	struct parport *p;
-	int pias;
+	int pias = 0;
 	struct pia *pp;
 	struct zorro_dev *z = NULL;
 
diff -Nru a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
--- a/drivers/parport/parport_pc.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/parport/parport_pc.c	Wed Jul 24 14:03:38 2002
@@ -2406,7 +2406,9 @@
 
 void parport_pc_unregister_port (struct parport *p)
 {
+#ifdef CONFIG_PARPORT_PC_FIFO
 	struct parport_pc_private *priv = p->private_data;
+#endif /* CONFIG_PARPORT_PC_FIFO */
 	struct parport_operations *ops = p->ops;
 	if (p->dma != PARPORT_DMA_NONE)
 		free_dma(p->dma);
@@ -2418,10 +2420,12 @@
 	if (p->modes & PARPORT_MODE_ECP)
 		release_region(p->base_hi, 3);
 	parport_proc_unregister(p);
+#ifdef CONFIG_PARPORT_PC_FIFO
 	if (priv->dma_buf)
 		pci_free_consistent(priv->dev, PAGE_SIZE,
 				    priv->dma_buf,
 				    priv->dma_handle);
+#endif /* CONFIG_PARPORT_PC_FIFO */
 	kfree (p->private_data);
 	parport_unregister_port(p);
 	kfree (ops); /* hope no-one cached it */
diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
--- a/drivers/pci/pci-driver.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/pci/pci-driver.c	Wed Jul 24 14:03:39 2002
@@ -41,8 +41,8 @@
 	struct pci_driver *drv;
 	struct pci_dev *pci_dev;
 
-	drv = list_entry(dev->driver, struct pci_driver, driver);
-	pci_dev = list_entry(dev, struct pci_dev, dev);
+	drv = to_pci_driver(dev->driver);
+	pci_dev = to_pci_dev(dev);
 
 	if (drv->probe) {
 		const struct pci_device_id *id;
@@ -60,7 +60,7 @@
 
 static int pci_device_remove(struct device * dev)
 {
-	struct pci_dev * pci_dev = list_entry(dev,struct pci_dev,dev);
+	struct pci_dev * pci_dev = to_pci_dev(dev);
 	struct pci_driver * drv = pci_dev->driver;
 
 	if (drv) {
@@ -73,7 +73,7 @@
 
 static int pci_device_suspend(struct device * dev, u32 state, u32 level)
 {
-	struct pci_dev * pci_dev = (struct pci_dev *)list_entry(dev,struct pci_dev,dev);
+	struct pci_dev * pci_dev = to_pci_dev(dev);
 	int error = 0;
 
 	if (pci_dev->driver) {
@@ -87,7 +87,7 @@
 
 static int pci_device_resume(struct device * dev, u32 level)
 {
-	struct pci_dev * pci_dev = (struct pci_dev *)list_entry(dev,struct pci_dev,dev);
+	struct pci_dev * pci_dev = to_pci_dev(dev);
 
 	if (pci_dev->driver) {
 		if (level == RESUME_POWER_ON && pci_dev->driver->resume)
@@ -175,8 +175,8 @@
  */
 static int pci_bus_match(struct device * dev, struct device_driver * drv) 
 {
-	struct pci_dev * pci_dev = list_entry(dev, struct pci_dev, dev);
-	struct pci_driver * pci_drv = list_entry(drv,struct pci_driver,driver);
+	struct pci_dev * pci_dev = to_pci_dev(dev);
+	struct pci_driver * pci_drv = to_pci_driver(drv);
 	const struct pci_device_id * ids = pci_drv->id_table;
 
 	if (!ids) 
diff -Nru a/drivers/pci/proc.c b/drivers/pci/proc.c
--- a/drivers/pci/proc.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/pci/proc.c	Wed Jul 24 14:03:35 2002
@@ -374,7 +374,7 @@
 /* driverfs files */
 static ssize_t pci_show_irq(struct device * dev, char * buf, size_t count, loff_t off)
 {
-	struct pci_dev * pci_dev = list_entry(dev,struct pci_dev,dev);
+	struct pci_dev * pci_dev = to_pci_dev(dev);
 	return off ? 0 : sprintf(buf,"%u\n",pci_dev->irq);
 }
 
@@ -386,7 +386,7 @@
 
 static ssize_t pci_show_resources(struct device * dev, char * buf, size_t count, loff_t off)
 {
-	struct pci_dev * pci_dev = list_entry(dev,struct pci_dev,dev);
+	struct pci_dev * pci_dev = to_pci_dev(dev);
 	char * str = buf;
 	int i;
 
diff -Nru a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
--- a/drivers/s390/block/dasd_ioctl.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/s390/block/dasd_ioctl.c	Wed Jul 24 14:03:35 2002
@@ -447,11 +447,6 @@
 	return 0;
 }
 
-static int dasd_ioctl_blkioctl(void *inp, int no, long args)
-{
-	return blk_ioctl(((struct inode *) inp)->i_bdev, no, args);
-}
-
 /*
  * Return device size in number of sectors.
  */
@@ -517,12 +512,12 @@
 static int dasd_ioctl_getgeo(void *inp, int no, long args)
 {
 	struct hd_geometry geo = { 0, };
+	struct inode *inode = inp;
 	dasd_devmap_t *devmap;
 	dasd_device_t *device;
-	kdev_t kdev;
+	kdev_t kdev = inode->i_rdev;
 	int rc;
 
-	kdev = ((struct inode *) inp)->i_rdev;
 	devmap = dasd_devmap_from_kdev(kdev);
 	device = (devmap != NULL) ?
 		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
@@ -532,7 +527,7 @@
 	if (device != NULL && device->discipline != NULL &&
 	    device->discipline->fill_geometry != NULL) {
 		device->discipline->fill_geometry(device, &geo);
-		geo.start = get_start_sect(kdev);
+		geo.start = get_start_sect(inode->i_bdev);
 		if (copy_to_user((struct hd_geometry *) args, &geo,
 				 sizeof (struct hd_geometry)))
 			rc = -EFAULT;
@@ -554,16 +549,10 @@
 	{ BIODASDINFO2, dasd_ioctl_information },
 	{ BIODASDPRRD, dasd_ioctl_read_profile },
 	{ BIODASDPRRST, dasd_ioctl_reset_profile },
-	{ BLKELVGET, dasd_ioctl_blkioctl },
-	{ BLKELVSET, dasd_ioctl_blkioctl },
-	{ BLKFLSBUF, dasd_ioctl_blkioctl },
 	{ BLKGETSIZE, dasd_ioctl_blkgetsize },
 	{ BLKGETSIZE64, dasd_ioctl_blkgetsize64 },
-	{ BLKPG, dasd_ioctl_blkioctl },
-	{ BLKROGET, dasd_ioctl_blkioctl },
 	{ BLKROSET, dasd_ioctl_set_ro },
 	{ BLKRRPART, dasd_ioctl_rr_partition },
-	{ BLKSSZGET, dasd_ioctl_blkioctl },
 	{ DASDAPIVER, dasd_ioctl_api_version },
 	{ HDIO_GETGEO, dasd_ioctl_getgeo },
 	{ -1, NULL }
diff -Nru a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
--- a/drivers/s390/block/xpram.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/s390/block/xpram.c	Wed Jul 24 14:03:39 2002
@@ -342,14 +342,6 @@
 	if (idx >= xpram_devs)
 		return -ENODEV;
 	switch (cmd) {
-	case BLKGETSIZE:
-		/* Return the device size, expressed in sectors */
-		return put_user(xpram_sizes[idx] << 1, (unsigned long *) arg);
-	case BLKGETSIZE64:
-		/* Return the device size, expressed in bytes */
-		return put_user((u64) xpram_sizes[idx] << 10, (u64 *) arg);
-	case BLKFLSBUF:
-		return blk_ioctl(((struct inode *) inode)->i_bdev, cmd, arg);
 	case BLKRRPART:
 		/* re-read partition table: can't do it */
 		return -EINVAL;
diff -Nru a/drivers/s390/char/tubio.h b/drivers/s390/char/tubio.h
--- a/drivers/s390/char/tubio.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/s390/char/tubio.h	Wed Jul 24 14:03:35 2002
@@ -338,11 +338,10 @@
 #define spin_trylock_irqsave(lock, flags) \
 ({ \
 	int success; \
-	__save_flags(flags); \
-	__cli(); \
+	local_irq_save(flags); \
 	success = spin_trylock(lock); \
 	if (success == 0) \
-		__restore_flags(flags); \
+		local_irq_restore(flags); \
 	success; \
 })
 #endif /* if not spin_trylock_irqsave */
diff -Nru a/drivers/s390/cio/s390io.c b/drivers/s390/cio/s390io.c
--- a/drivers/s390/cio/s390io.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/s390/cio/s390io.c	Wed Jul 24 14:03:39 2002
@@ -163,11 +163,10 @@
 	 *  function we resestablish the old environment.
 	 *
 	 * Note : as we don't need a system wide lock, therefore
-	 *        we shouldn't use cli(), but __cli() as this
+	 *        we shouldn't use cli(), but local_irq_save() as this
 	 *        affects the current CPU only.
 	 */
-	__save_flags (flags);
-	__cli ();
+	local_irq_save(flags);
 
 	/*
 	 * disable all interrupts
@@ -204,7 +203,7 @@
 
 	init_IRQ_complete = 1;
 
-	__restore_flags (flags);
+	local_irq_restore (flags);
 
 	return;
 }
@@ -578,10 +577,9 @@
 	 *   also require to run disabled.
 	 *
 	 * Note : as no global lock is required, we must not use
-	 *        cli(), but __cli() instead.   
+	 *        cli(), but local_irq_save() instead.   
 	 */
-	__save_flags (flags);
-	__cli ();
+	local_irq_save(flags);
 
 	rdc_ccw = &ioinfo[irq]->senseccw;
 
@@ -643,7 +641,7 @@
 
 		}
 
-		__restore_flags (flags);
+		local_irq_restore (flags);
 
 		/*
 		 * on success we update the user input parms
@@ -720,8 +718,7 @@
 		int emulated = 0;	/* no i/O handler installed */
 		int retry = 5;	/* retry count */
 
-		__save_flags (flags);
-		__cli ();
+		local_irq_save(flags);
 
 		if (!ioinfo[irq]->ui.flags.ready) {
 			pdevstat = &devstat;
@@ -816,7 +813,7 @@
 
 			}
 
-			__restore_flags (flags);
+			local_irq_restore (flags);
 
 		}
 
diff -Nru a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
--- a/drivers/s390/net/lcs.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/s390/net/lcs.c	Wed Jul 24 14:03:36 2002
@@ -968,7 +968,7 @@
 #if LINUX_VERSION_CODE<=KERNEL_VERSION(2,2,16)
 	/* tq_scheduler sometimes leaves interrupts disabled from do
 	 * bottom half */
-	__sti();
+	local_irq_enable();
 #endif
 	if (kernel_thread((int (*)(void *)) drvr_globals->kernel_thread_routine,
 			  (void *) drvr_globals, SIGCHLD) < 0) {
diff -Nru a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
--- a/drivers/s390/s390mach.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/s390/s390mach.c	Wed Jul 24 14:03:39 2002
@@ -254,8 +254,7 @@
 
 		found = 0;	/* init ... */
 
-		__save_flags(flags);
-		__cli();
+		local_irq_save(flags);
 
 		do {
 
@@ -311,7 +310,7 @@
 
 		} while (pmache);
 
-		__restore_flags(flags);
+		local_irq_restore(flags);
 
 	} while (1);
 
diff -Nru a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
--- a/drivers/sbus/char/jsflash.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/sbus/char/jsflash.c	Wed Jul 24 14:03:38 2002
@@ -464,14 +464,6 @@
 	case BLKGETSIZE64:
 		return put_user(jsfd_bytesizes[dev], (u64 *) arg);
 
-#if 0
-	case BLKROSET:
-	case BLKROGET:
-	case BLKSSZGET:
-		return blk_ioctl(inode->i_bdev, cmd, arg);
-#endif
-
-	/* case BLKFLSBUF: */	/* Program, then read, what happens? Stale? */
 	default: ;
 	}
 	return -ENOTTY;
diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
--- a/drivers/scsi/3w-xxxx.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/3w-xxxx.c	Wed Jul 24 14:03:39 2002
@@ -2084,7 +2084,7 @@
 } /* End tw_reset_sequence() */
 
 /* This funciton returns unit geometry in cylinders/heads/sectors */
-int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[]) 
+int tw_scsi_biosparam(Disk *disk, struct block_device *dev, int geom[]) 
 {
 	int heads, sectors, cylinders;
 	TW_Device_Extension *tw_dev;
diff -Nru a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
--- a/drivers/scsi/3w-xxxx.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/3w-xxxx.h	Wed Jul 24 14:03:36 2002
@@ -56,7 +56,6 @@
 
 #include <linux/version.h>
 #include <linux/types.h>
-#include <linux/kdev_t.h>
 
 /* AEN strings */
 static char *tw_aen_string[] = {
@@ -445,7 +444,7 @@
 int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id);
 int tw_reset_device_extension(TW_Device_Extension *tw_dev);
 int tw_reset_sequence(TW_Device_Extension *tw_dev);
-int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[]);
+int tw_scsi_biosparam(Disk *disk, struct block_device *dev, int geom[]);
 int tw_scsi_detect(Scsi_Host_Template *tw_host);
 int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt);
 int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt);
diff -Nru a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
--- a/drivers/scsi/53c7xx.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/53c7xx.c	Wed Jul 24 14:03:39 2002
@@ -1144,8 +1144,8 @@
     	return -1;
     }
 
-    printk("scsi-ncr53c7xx : %s at memory 0x%x, io 0x%x, irq %d",
-    	chip_str, (unsigned) base, io_port, irq);
+    printk("scsi-ncr53c7xx : %s at memory 0x%lx, io 0x%x, irq %d",
+    	chip_str, base, io_port, irq);
     if (dma == DMA_NONE)
     	printk("\n");
     else 
@@ -3459,9 +3459,10 @@
 
     for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, 
 	cmd_dataout += 4, ++i) {
-	u32 vbuf = cmd->use_sg ? 
-	    (u32)(((struct scatterlist *)cmd->buffer)[i].address) :
-	    (u32)(cmd->request_buffer);
+	u32 vbuf = cmd->use_sg
+	    ? (u32)page_address(((struct scatterlist *)cmd->buffer)[i].page)+
+	      ((struct scatterlist *)cmd->buffer)[i].offset
+	    : (u32)(cmd->request_buffer);
 	u32 bbuf = virt_to_bus((void *)vbuf);
 	u32 count = cmd->use_sg ?
 	    ((struct scatterlist *)cmd->buffer)[i].length :
@@ -5428,16 +5429,16 @@
 	    if ((buffers = cmd->use_sg)) {
     	    	for (offset = 0, 
 		     	segment = (struct scatterlist *) cmd->buffer;
-    	    	     buffers && !((found = ((ptr >= segment->address) && 
-    	    	    	    (ptr < (segment->address + segment->length)))));
+    	    	     buffers && !((found = ((ptr >= (char *)page_address(segment->page)+segment->offset) && 
+    	    	    	    (ptr < ((char *)page_address(segment->page)+segment->offset+segment->length)))));
     	    	     --buffers, offset += segment->length, ++segment)
 #if 0
 		    printk("scsi%d: comparing 0x%p to 0x%p\n", 
-			cmd->host->host_no, saved, segment->address);
+			cmd->host->host_no, saved, page_address(segment->page+segment->offset);
 #else
 		    ;
 #endif
-    	    	    offset += ptr - segment->address;
+    	    	    offset += ptr - ((char *)page_address(segment->page)+segment->offset);
     	    } else {
 		found = 1;
     	    	offset = ptr - (char *) (cmd->request_buffer);
diff -Nru a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
--- a/drivers/scsi/BusLogic.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/BusLogic.c	Wed Jul 24 14:03:39 2002
@@ -4110,7 +4110,7 @@
   the BIOS, and a warning may be displayed.
 */
 
-int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
+int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, struct block_device *bdev,
 				int *Parameters)
 {
   BusLogic_HostAdapter_T *HostAdapter =
@@ -4138,7 +4138,7 @@
     }
   DiskParameters->Cylinders =
     Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
-  buf = scsi_bios_ptable(Device);
+  buf = scsi_bios_ptable(bdev);
   if (buf == NULL) return 0;
   /*
     If the boot sector partition table flag is valid, search for a partition
diff -Nru a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
--- a/drivers/scsi/BusLogic.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/BusLogic.h	Wed Jul 24 14:03:38 2002
@@ -34,7 +34,6 @@
   of the Linux Kernel and SCSI Subsystem.
 */
 
-typedef kdev_t KernelDevice_T;
 typedef unsigned long ProcessorFlags_T;
 typedef struct pt_regs Registers_T;
 typedef struct partition PartitionTable_T;
@@ -58,7 +57,7 @@
 				 void (*CompletionRoutine)(SCSI_Command_T *));
 extern int BusLogic_AbortCommand(SCSI_Command_T *);
 extern int BusLogic_ResetCommand(SCSI_Command_T *, unsigned int);
-extern int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, KernelDevice_T, int *);
+extern int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, struct block_device *, int *);
 extern int BusLogic_ProcDirectoryInfo(char *, char **, off_t, int, int, int);
 
 
diff -Nru a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
--- a/drivers/scsi/NCR5380.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/NCR5380.c	Wed Jul 24 14:03:36 2002
@@ -337,7 +337,8 @@
 	if (cmd->use_sg) {
 		cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
-		cmd->SCp.ptr = (char *) cmd->SCp.buffer->address;
+		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+			       cmd->SCp.buffer->offset;
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
 		cmd->SCp.buffer = NULL;
@@ -2308,7 +2309,8 @@
 					++cmd->SCp.buffer;
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
-					cmd->SCp.ptr = cmd->SCp.buffer->address;
+					cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+						       cmd->SCp.buffer->offset;
 					dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
 				}
 				/*
diff -Nru a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
--- a/drivers/scsi/NCR53c406a.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/NCR53c406a.c	Wed Jul 24 14:03:38 2002
@@ -760,7 +760,7 @@
 }
 
 int 
-NCR53c406a_biosparm(Scsi_Disk *disk, kdev_t dev, int* info_array){
+NCR53c406a_biosparm(Scsi_Disk *disk, struct block_device *dev, int* info_array){
     int size;
     
     DEB(printk("NCR53c406a_biosparm called\n"));
diff -Nru a/drivers/scsi/NCR53c406a.h b/drivers/scsi/NCR53c406a.h
--- a/drivers/scsi/NCR53c406a.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/NCR53c406a.h	Wed Jul 24 14:03:37 2002
@@ -50,7 +50,7 @@
 int NCR53c406a_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int NCR53c406a_abort(Scsi_Cmnd *);
 int NCR53c406a_reset(Scsi_Cmnd *, unsigned int);
-int NCR53c406a_biosparm(Disk *, kdev_t, int []);
+int NCR53c406a_biosparm(Disk *, struct block_device *, int []);
 
 #endif /* _NCR53C406A_H */
 
diff -Nru a/drivers/scsi/README.st b/drivers/scsi/README.st
--- a/drivers/scsi/README.st	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/README.st	Wed Jul 24 14:03:36 2002
@@ -2,7 +2,7 @@
 The driver is currently maintained by Kai M{kisara (email
 Kai.Makisara@metla.fi)
 
-Last modified: Tue Jun 18 18:13:50 2002 by makisara
+Last modified: Mon Jul 15 16:30:40 2002 by makisara
 
 
 BASICS
@@ -118,7 +118,6 @@
 memory having sizes 2^n * (page size). Because of this the actual
 buffer size may be larger than the minimum allowable buffer size.
 
-
 Asynchronous writing. Writing the buffer contents to the tape is
 started and the write call returns immediately. The status is checked
 at the next tape operation.
@@ -163,12 +162,24 @@
 extending the buffer will always fail.
 
 
+EOM BEHAVIOUR WHEN WRITING
+
+When the end of medium early warning is encountered, the current write
+is finished and the number of bytes is returned. The next write
+returns -1 and errno is set to ENOSPC. To enable writing a trailer,
+the next write is allowed to proceed and, if successful, the number of
+bytes is returned. After this, -1 and the number of bytes are
+alternately returned until the physical end of medium (or some other
+error) is encountered.
+
+
 MODULE PARAMETERS
 
 The buffer size, write threshold, and the maximum number of allocated buffers
 are configurable when the driver is loaded as a module. The keywords are:
 
-buffer_kbs=xxx             the buffer size in kilobytes is set to xxx
+buffer_kbs=xxx             the buffer size for fixed block mode is set
+			   to xxx kilobytes
 write_threshold_kbs=xxx    the write threshold in kilobytes set to xxx
 max_buffers=xxx            the maximum number of tape buffer set to xxx
 max_sg_segs=xxx		   the maximum number of scatter/gather
@@ -188,17 +199,15 @@
 mark. The definition is prepended by the string st=. Here is an
 example:
 
-	st=buffer_kbs:64,max_buffers:2
+	st=buffer_kbs:64,write_threhold_kbs:60
 
 The following syntax used by the old kernel versions is also supported:
 
-           st=aa[,bb[,cc[,dd]]]
+           st=aa[,bb[,dd]]
 
 where
-  aa is the buffer size in 1024 byte units
+  aa is the buffer size for fixed block mode in 1024 byte units
   bb is the write threshold in 1024 byte units
-  cc is the maximum number of tape buffers to allocate (the number of
-        buffers is bounded also by the number of drives detected)
   dd is the maximum number of scatter/gather segments
 
 
@@ -231,7 +240,9 @@
 MTNOP   Do nothing except flush the buffers.
 MTRETEN Re-tension tape.
 MTEOM   Space to end of recorded data.
-MTERASE Erase tape.
+MTERASE Erase tape. If the argument is zero, the short erase command
+	is used. The long erase command is used with all other values
+	of the argument.
 MTSEEK	Seek to tape block count. Uses Tandberg-compatible seek (QFA)
         for SCSI-1 drives and SCSI-2 seek for SCSI-2 drives. The file and
 	block numbers in the status are not valid after a seek.
diff -Nru a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
--- a/drivers/scsi/advansys.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/advansys.c	Wed Jul 24 14:03:37 2002
@@ -6114,7 +6114,7 @@
  * ip[2]: cylinders
  */
 int
-advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
+advansys_biosparam(Disk *dp, struct block_device *dep, int ip[])
 {
     asc_board_t     *boardp;
 
diff -Nru a/drivers/scsi/advansys.h b/drivers/scsi/advansys.h
--- a/drivers/scsi/advansys.h	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/advansys.h	Wed Jul 24 14:03:39 2002
@@ -52,7 +52,7 @@
 const char *advansys_info(struct Scsi_Host *);
 int advansys_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
 int advansys_reset(Scsi_Cmnd *);
-int advansys_biosparam(Disk *, kdev_t, int[]);
+int advansys_biosparam(Disk *, struct block_device *, int[]);
 #ifdef CONFIG_PROC_FS
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,28)
 extern struct proc_dir_entry proc_scsi_advansys;
diff -Nru a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
--- a/drivers/scsi/aha152x.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/aha152x.c	Wed Jul 24 14:03:35 2002
@@ -1830,7 +1830,7 @@
  * Return the "logical geometry"
  *
  */
-int aha152x_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array)
+int aha152x_biosparam(Scsi_Disk * disk, struct block_device *bdev, int *info_array)
 {
 	struct Scsi_Host *shpnt = disk->device->host;
 
@@ -1844,7 +1844,7 @@
 		int info[3];
 
 		/* try to figure out the geometry from the partition table */
-		if (scsicam_bios_param(disk, dev, info) < 0 ||
+		if (scsicam_bios_param(disk, bdev, info) < 0 ||
 		    !((info[0] == 64 && info[1] == 32) || (info[0] == 255 && info[1] == 63))) {
 			if (EXT_TRANS) {
 				printk(KERN_NOTICE
diff -Nru a/drivers/scsi/aha152x.h b/drivers/scsi/aha152x.h
--- a/drivers/scsi/aha152x.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/aha152x.h	Wed Jul 24 14:03:38 2002
@@ -20,7 +20,7 @@
 int aha152x_device_reset(Scsi_Cmnd *);
 int aha152x_bus_reset(Scsi_Cmnd *);
 int aha152x_host_reset(Scsi_Cmnd *);
-int aha152x_biosparam(Disk *, kdev_t, int*);
+int aha152x_biosparam(Disk *, struct block_device *, int*);
 int aha152x_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout);
 
 /* number of queueable commands
diff -Nru a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
--- a/drivers/scsi/aha1542.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/aha1542.c	Wed Jul 24 14:03:35 2002
@@ -1783,7 +1783,7 @@
 
 #include "sd.h"
 
-static int aha1542_biosparam(Scsi_Disk * disk, kdev_t dev, int *ip)
+static int aha1542_biosparam(Scsi_Disk * disk, struct block_device *dev, int *ip)
 {
 	int translation_algorithm;
 	int size = disk->capacity;
diff -Nru a/drivers/scsi/aha1542.h b/drivers/scsi/aha1542.h
--- a/drivers/scsi/aha1542.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/aha1542.h	Wed Jul 24 14:03:36 2002
@@ -32,7 +32,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/kdev_t.h>
 
 /* I/O Port interface 4.2 */
 /* READ */
@@ -141,7 +140,7 @@
 static int aha1542_old_abort(Scsi_Cmnd * SCpnt);
 static int aha1542_old_reset(Scsi_Cmnd *, unsigned int);
 #endif
-static int aha1542_biosparam(Disk *, kdev_t, int*);
+static int aha1542_biosparam(Disk *, struct block_device *, int*);
 
 #define AHA1542_MAILBOXES 8
 #define AHA1542_SCATTER 16
diff -Nru a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
--- a/drivers/scsi/aha1740.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/aha1740.c	Wed Jul 24 14:03:36 2002
@@ -590,7 +590,7 @@
     return SCSI_RESET_PUNT;
 }
 
-int aha1740_biosparam(Disk * disk, kdev_t dev, int* ip)
+int aha1740_biosparam(Disk * disk, struct block_device *dev, int* ip)
 {
     int size = disk->capacity;
     int extended = HOSTDATA(disk->device->host)->translation;
diff -Nru a/drivers/scsi/aha1740.h b/drivers/scsi/aha1740.h
--- a/drivers/scsi/aha1740.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/aha1740.h	Wed Jul 24 14:03:38 2002
@@ -11,7 +11,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/kdev_t.h>
 
 /* Eisa Enhanced mode operation - slot locating and addressing */
 #define MINEISA 1   /* I don't have an EISA Spec to know these ranges, so I */
@@ -158,7 +157,7 @@
 int aha1740_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int aha1740_abort(Scsi_Cmnd *);
 int aha1740_reset(Scsi_Cmnd *, unsigned int);
-int aha1740_biosparam(Disk *, kdev_t, int*);
+int aha1740_biosparam(Disk *, struct block_device *, int*);
 int aha1740_proc_info(char *buffer, char **start, off_t offset,
                                int length, int hostno, int inout);
 
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_linux.c b/drivers/scsi/aic7xxx/aic7xxx_linux.c
--- a/drivers/scsi/aic7xxx/aic7xxx_linux.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/aic7xxx/aic7xxx_linux.c	Wed Jul 24 14:03:38 2002
@@ -2722,7 +2722,7 @@
  * Return the disk geometry for the given SCSI device.
  */
 int
-ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[])
+ahc_linux_biosparam(Disk *disk, struct block_device *bdev, int geom[])
 {
 	int	heads;
 	int	sectors;
@@ -2733,7 +2733,7 @@
 	unsigned char *buf;
 
 	ahc = *((struct ahc_softc **)disk->device->host->hostdata);
-	buf = scsi_bios_ptable(dev);
+	buf = scsi_bios_ptable(bdev);
 
 	if (buf) {
 		ret = scsi_partsize(buf, disk->capacity,
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_linux_host.h b/drivers/scsi/aic7xxx/aic7xxx_linux_host.h
--- a/drivers/scsi/aic7xxx/aic7xxx_linux_host.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/aic7xxx/aic7xxx_linux_host.h	Wed Jul 24 14:03:37 2002
@@ -47,7 +47,7 @@
 int		 ahc_linux_detect(Scsi_Host_Template *);
 int		 ahc_linux_release(struct Scsi_Host *);
 const char	*ahc_linux_info(struct Scsi_Host *);
-int		 ahc_linux_biosparam(Disk *, kdev_t, int[]);
+int		 ahc_linux_biosparam(Disk *, struct block_device *, int[]);
 int		 ahc_linux_bus_reset(Scsi_Cmnd *);
 int		 ahc_linux_dev_reset(Scsi_Cmnd *);
 int		 ahc_linux_abort(Scsi_Cmnd *);
diff -Nru a/drivers/scsi/aic7xxx_old/aic7xxx.h b/drivers/scsi/aic7xxx_old/aic7xxx.h
--- a/drivers/scsi/aic7xxx_old/aic7xxx.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/aic7xxx_old/aic7xxx.h	Wed Jul 24 14:03:35 2002
@@ -58,7 +58,7 @@
 }
 
 extern int aic7xxx_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
-extern int aic7xxx_biosparam(Disk *, kdev_t, int[]);
+extern int aic7xxx_biosparam(Disk *, struct block_device *, int[]);
 extern int aic7xxx_detect(Scsi_Host_Template *);
 extern int aic7xxx_command(Scsi_Cmnd *);
 extern int aic7xxx_reset(Scsi_Cmnd *, unsigned int);
diff -Nru a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
--- a/drivers/scsi/aic7xxx_old.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/aic7xxx_old.c	Wed Jul 24 14:03:37 2002
@@ -11719,14 +11719,14 @@
  *   Return the disk geometry for the given SCSI device.
  *-F*************************************************************************/
 int
-aic7xxx_biosparam(Disk *disk, kdev_t dev, int geom[])
+aic7xxx_biosparam(Disk *disk, struct block_device *bdev, int geom[])
 {
   int heads, sectors, cylinders, ret;
   struct aic7xxx_host *p;
   unsigned char *buf;
 
   p = (struct aic7xxx_host *) disk->device->host->hostdata;
-  buf = scsi_bios_ptable(dev);
+  buf = scsi_bios_ptable(bdev);
 
   if ( buf )
   {
diff -Nru a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
--- a/drivers/scsi/atari_NCR5380.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/atari_NCR5380.c	Wed Jul 24 14:03:38 2002
@@ -474,8 +474,8 @@
 
     for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
 	 cmd->SCp.buffers_residual &&
-	 virt_to_phys(cmd->SCp.buffer[1].address) == endaddr; ) {
-	
+	 virt_to_phys(page_address(cmd->SCp.buffer[1].page)+
+		      cmd->SCp.buffer[1].offset) == endaddr; ) {
 	MER_PRINTK("VTOP(%p) == %08lx -> merging\n",
 		   cmd->SCp.buffer[1].address, endaddr);
 #if (NDEBUG & NDEBUG_MERGING)
@@ -512,7 +512,8 @@
     if (cmd->use_sg) {
 	cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
 	cmd->SCp.buffers_residual = cmd->use_sg - 1;
-	cmd->SCp.ptr = (char *) cmd->SCp.buffer->address;
+	cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+
+		       cmd->SCp.buffer->offset;
 	cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	/* ++roman: Try to merge some scatter-buffers if they are at
 	 * contiguous physical addresses.
@@ -2060,7 +2061,8 @@
 		    ++cmd->SCp.buffer;
 		    --cmd->SCp.buffers_residual;
 		    cmd->SCp.this_residual = cmd->SCp.buffer->length;
-		    cmd->SCp.ptr = cmd->SCp.buffer->address;
+		    cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+				   cmd->SCp.buffer->offset;
 		    /* ++roman: Try to merge some scatter-buffers if
 		     * they are at contiguous physical addresses.
 		     */
diff -Nru a/drivers/scsi/atari_scsi.h b/drivers/scsi/atari_scsi.h
--- a/drivers/scsi/atari_scsi.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/atari_scsi.h	Wed Jul 24 14:03:38 2002
@@ -258,8 +258,6 @@
 #define NCR_PRINT_STATUS(mask) \
 	((NDEBUG & (mask)) ? NCR5380_print_status(instance) : (void)0)
 
-#define NDEBUG_ANY	0xffffffff
-
 
 #endif /* ndef ASM */
 #endif /* ATARI_SCSI_H */
diff -Nru a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
--- a/drivers/scsi/atp870u.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/atp870u.c	Wed Jul 24 14:03:37 2002
@@ -2835,7 +2835,7 @@
 
 #include "sd.h"
 
-int atp870u_biosparam(Scsi_Disk * disk, kdev_t dev, int *ip)
+int atp870u_biosparam(Scsi_Disk * disk, struct block_device *dev, int *ip)
 {
 	int heads, sectors, cylinders;
 
diff -Nru a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h
--- a/drivers/scsi/atp870u.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/atp870u.h	Wed Jul 24 14:03:35 2002
@@ -11,7 +11,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/kdev_t.h>
 
 /* I/O Port */
 
@@ -23,7 +22,7 @@
 int atp870u_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 int atp870u_abort(Scsi_Cmnd *);
 int atp870u_reset(Scsi_Cmnd *, unsigned int);
-int atp870u_biosparam(Disk *, kdev_t, int *);
+int atp870u_biosparam(Disk *, struct block_device *, int *);
 int atp870u_release(struct Scsi_Host *);
 void send_s870(unsigned char);
 
diff -Nru a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c
--- a/drivers/scsi/bvme6000.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/bvme6000.c	Wed Jul 24 14:03:36 2002
@@ -23,9 +23,9 @@
 
 #include<linux/stat.h>
 
-extern ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip,
-			unsigned long base, int io_port, int irq, int dma,
-			long long options, int clock);
+extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip,
+			  unsigned long base, int io_port, int irq, int dma,
+			  long long options, int clock);
 
 int bvme6000_scsi_detect(Scsi_Host_Template *tpnt)
 {
diff -Nru a/drivers/scsi/cpqfcTS.h b/drivers/scsi/cpqfcTS.h
--- a/drivers/scsi/cpqfcTS.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/cpqfcTS.h	Wed Jul 24 14:03:37 2002
@@ -12,7 +12,7 @@
 extern int cpqfcTS_reset(Scsi_Cmnd *, unsigned int);
 extern int cpqfcTS_eh_abort(Scsi_Cmnd *Cmnd);
 extern int cpqfcTS_eh_device_reset(Scsi_Cmnd *);
-extern int cpqfcTS_biosparam(Disk *, kdev_t, int[]);
+extern int cpqfcTS_biosparam(Disk *, struct block_device *, int[]);
 extern int cpqfcTS_ioctl( Scsi_Device *ScsiDev, int Cmnd, void *arg);
 
 // note: since Tachyon TS supports an extended scatter/gather
diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
--- a/drivers/scsi/cpqfcTSinit.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/cpqfcTSinit.c	Wed Jul 24 14:03:35 2002
@@ -1625,7 +1625,7 @@
    (from hosts.h)
 */
 
-int cpqfcTS_biosparam(Disk *disk, kdev_t n, int ip[])
+int cpqfcTS_biosparam(Disk *disk, struct block_device *n, int ip[])
 {
   int size = disk->capacity;
   
diff -Nru a/drivers/scsi/dc390.h b/drivers/scsi/dc390.h
--- a/drivers/scsi/dc390.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/dc390.h	Wed Jul 24 14:03:36 2002
@@ -39,7 +39,7 @@
 extern int DC390_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
 extern int DC390_abort(Scsi_Cmnd *cmd);
 extern int DC390_reset(Scsi_Cmnd *cmd, unsigned int resetFlags);
-extern int DC390_bios_param(Disk *disk, kdev_t devno, int geom[]);
+extern int DC390_bios_param(Disk *disk, struct block_device *dev, int geom[]);
 
 #ifdef MODULE
 static int DC390_release(struct Scsi_Host *);
diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/dpt_i2o.c	Wed Jul 24 14:03:37 2002
@@ -453,7 +453,7 @@
 	return adpt_scsi_to_i2o(pHba, cmd, pDev);
 }
 
-static int adpt_bios_param(Disk* disk, kdev_t dev, int geom[])
+static int adpt_bios_param(Disk* disk, struct block_device *dev, int geom[])
 {
 	int heads=-1;
 	int sectors=-1;
diff -Nru a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
--- a/drivers/scsi/dpti.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/dpti.h	Wed Jul 24 14:03:35 2002
@@ -45,7 +45,7 @@
 static int adpt_release(struct Scsi_Host *host);
 
 static const char *adpt_info(struct Scsi_Host *pSHost);
-static int adpt_bios_param(Disk * disk, kdev_t dev, int geom[]);
+static int adpt_bios_param(Disk * disk, struct block_device *dev, int geom[]);
 
 static int adpt_bus_reset(Scsi_Cmnd* cmd);
 static int adpt_device_reset(Scsi_Cmnd* cmd);
diff -Nru a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
--- a/drivers/scsi/dtc.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/dtc.c	Wed Jul 24 14:03:39 2002
@@ -295,7 +295,7 @@
 }
 
 /*
- * Function : int dtc_biosparam(Disk * disk, kdev_t dev, int *ip)
+ * Function : int dtc_biosparam(Disk * disk, struct block_device *dev, int *ip)
  *
  * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 
  *	the specified device / size.
@@ -314,7 +314,7 @@
  * and matching the H_C_S coordinates to what DOS uses.
 */
 
-int dtc_biosparam(Disk * disk, kdev_t dev, int * ip)
+int dtc_biosparam(Disk * disk, struct block_device *dev, int * ip)
 {
    int size = disk->capacity;
 
diff -Nru a/drivers/scsi/dtc.h b/drivers/scsi/dtc.h
--- a/drivers/scsi/dtc.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/dtc.h	Wed Jul 24 14:03:36 2002
@@ -30,7 +30,7 @@
 
 #ifndef ASM
 int dtc_abort(Scsi_Cmnd *);
-int dtc_biosparam(Disk *, kdev_t, int*);
+int dtc_biosparam(Disk *, struct block_device *, int*);
 int dtc_detect(Scsi_Host_Template *);
 int dtc_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int dtc_reset(Scsi_Cmnd *, unsigned int reset_flags);
diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/eata.c	Wed Jul 24 14:03:39 2002
@@ -1803,10 +1803,10 @@
    return do_reset(SCarg);
 }
 
-int eata2x_biosparam(Disk *disk, kdev_t dev, int *dkinfo) {
+int eata2x_biosparam(Disk *disk, struct block_device *bdev, int *dkinfo) {
    int size = disk->capacity;
 
-   if (ext_tran || (scsicam_bios_param(disk, dev, dkinfo) < 0)) {
+   if (ext_tran || (scsicam_bios_param(disk, bdev, dkinfo) < 0)) {
       dkinfo[0] = 255;
       dkinfo[1] = 63;
       dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
diff -Nru a/drivers/scsi/eata.h b/drivers/scsi/eata.h
--- a/drivers/scsi/eata.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/eata.h	Wed Jul 24 14:03:36 2002
@@ -11,7 +11,7 @@
 int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int eata2x_abort(Scsi_Cmnd *);
 int eata2x_reset(Scsi_Cmnd *);
-int eata2x_biosparam(Disk *, kdev_t, int *);
+int eata2x_biosparam(Disk *, struct block_device *, int *);
 
 #define EATA_VERSION "7.22.00"
 
diff -Nru a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
--- a/drivers/scsi/fd_mcs.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/fd_mcs.c	Wed Jul 24 14:03:37 2002
@@ -1383,9 +1383,8 @@
 #include "sd.h"
 #include <scsi/scsi_ioctl.h>
 
-int fd_mcs_biosparam( Scsi_Disk *disk, kdev_t dev, int *info_array )
+int fd_mcs_biosparam( Scsi_Disk *disk, struct block_device *bdev, int *info_array )
 {
-  int              drive;
   unsigned char    buf[512 + sizeof( int ) * 2];
   int		    size      = disk->capacity;
   int              *sizes    = (int *)buf;
@@ -1394,8 +1393,6 @@
   int              retcode;
 
   /* BIOS >= 3.4 for MCA cards */
-  drive = MINOR(dev) / 16;
-
   /* This algorithm was provided by Future Domain (much thanks!). */
 
   sizes[0] = 0;		/* zero bytes out */
diff -Nru a/drivers/scsi/fd_mcs.h b/drivers/scsi/fd_mcs.h
--- a/drivers/scsi/fd_mcs.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/fd_mcs.h	Wed Jul 24 14:03:36 2002
@@ -28,7 +28,7 @@
 extern int fd_mcs_abort( Scsi_Cmnd * );
 extern int fd_mcs_reset( Scsi_Cmnd *, unsigned int );
 extern int fd_mcs_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
-extern int fd_mcs_biosparam( Disk *, kdev_t, int * );
+extern int fd_mcs_biosparam( Disk *, struct block_device *, int * );
 extern int fd_mcs_proc_info( char *, char **, off_t, int, int, int );
 extern const char *fd_mcs_info(struct Scsi_Host *);
 
diff -Nru a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
--- a/drivers/scsi/fdomain.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/fdomain.c	Wed Jul 24 14:03:36 2002
@@ -1874,7 +1874,7 @@
 #include "sd.h"
 #include <scsi/scsi_ioctl.h>
 
-int fdomain_16x0_biosparam( Scsi_Disk *disk, kdev_t dev, int *info_array )
+int fdomain_16x0_biosparam( Scsi_Disk *disk, struct block_device *bdev, int *info_array )
 {
    int              drive;
    unsigned char    buf[512 + sizeof (Scsi_Ioctl_Command)];
@@ -1933,11 +1933,11 @@
       0x0a bytes long.  Heads are one less than we need to report.
     */
 
-   if (major(dev) != SCSI_DISK0_MAJOR) {
+   if (MAJOR(bdev->bd_dev) != SCSI_DISK0_MAJOR) {
       printk("scsi: <fdomain> fdomain_16x0_biosparam: too many disks");
       return 0;
    }
-   drive = minor(dev) >> 4;
+   drive = MINOR(bdev->bd_dev) >> 4;
 
    if (bios_major == 2) {
       switch (Quantum) {
diff -Nru a/drivers/scsi/fdomain.h b/drivers/scsi/fdomain.h
--- a/drivers/scsi/fdomain.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/fdomain.h	Wed Jul 24 14:03:37 2002
@@ -31,7 +31,7 @@
 const char *fdomain_16x0_info( struct Scsi_Host * );
 int        fdomain_16x0_reset( Scsi_Cmnd *, unsigned int ); 
 int        fdomain_16x0_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
-int        fdomain_16x0_biosparam( Disk *, kdev_t, int * );
+int        fdomain_16x0_biosparam( Disk *, struct block_device *, int * );
 int        fdomain_16x0_proc_info( char *buffer, char **start, off_t offset,
 				   int length, int hostno, int inout );
 int        fdomain_16x0_release( struct Scsi_Host *shpnt );
diff -Nru a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
--- a/drivers/scsi/g_NCR5380.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/g_NCR5380.c	Wed Jul 24 14:03:36 2002
@@ -512,7 +512,7 @@
  *	Locks: none
  */
 
-int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
+int generic_NCR5380_biosparam(Disk * disk, struct block_device *dev, int *ip)
 {
 	int size = disk->capacity;
 	ip[0] = 64;
diff -Nru a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
--- a/drivers/scsi/g_NCR5380.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/g_NCR5380.h	Wed Jul 24 14:03:35 2002
@@ -53,7 +53,7 @@
                      int length, int hostno, int inout);
 const char* generic_NCR5380_info(struct Scsi_Host *);
 #ifdef BIOSPARAM
-int generic_NCR5380_biosparam(Disk *, kdev_t, int *);
+int generic_NCR5380_biosparam(Disk *, struct block_device *, int *);
 #endif
 
 int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout);
diff -Nru a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
--- a/drivers/scsi/gdth.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/gdth.c	Wed Jul 24 14:03:35 2002
@@ -4512,11 +4512,7 @@
 }
 #endif
 
-#if LINUX_VERSION_CODE >= 0x010300
-int gdth_bios_param(Disk *disk,kdev_t dev,int *ip)
-#else
-int gdth_bios_param(Disk *disk,int dev,int *ip)
-#endif
+int gdth_bios_param(Disk *disk,struct block_device *bdev,int *ip)
 {
     unchar b, t;
     int hanum;
diff -Nru a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
--- a/drivers/scsi/gdth.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/gdth.h	Wed Jul 24 14:03:37 2002
@@ -1031,8 +1031,7 @@
 #endif
 const char *gdth_info(struct Scsi_Host *);
 
-#if LINUX_VERSION_CODE >= 0x020322
-int gdth_bios_param(Disk *,kdev_t,int *);
+int gdth_bios_param(Disk *,struct block_device *,int *);
 int gdth_proc_info(char *,char **,off_t,int,int,int);
 int gdth_eh_abort(Scsi_Cmnd *scp);
 int gdth_eh_device_reset(Scsi_Cmnd *scp);
@@ -1060,84 +1059,6 @@
                present:         0,                               \
                unchecked_isa_dma: 1,                             \
                use_clustering:  ENABLE_CLUSTERING }
-
-#elif LINUX_VERSION_CODE >= 0x02015F
-int gdth_bios_param(Disk *,kdev_t,int *);
-extern struct proc_dir_entry proc_scsi_gdth;
-int gdth_proc_info(char *,char **,off_t,int,int,int);
-int gdth_eh_abort(Scsi_Cmnd *scp);
-int gdth_eh_device_reset(Scsi_Cmnd *scp);
-int gdth_eh_bus_reset(Scsi_Cmnd *scp);
-int gdth_eh_host_reset(Scsi_Cmnd *scp);
-#define GDTH { proc_dir:        &proc_scsi_gdth,                 \
-               proc_info:       gdth_proc_info,                  \
-               name:            "GDT SCSI Disk Array Controller",\
-               detect:          gdth_detect,                     \
-               release:         gdth_release,                    \
-               info:            gdth_info,                       \
-               command:         NULL,                            \
-               queuecommand:    gdth_queuecommand,               \
-               eh_abort_handler: gdth_eh_abort,                  \
-               eh_device_reset_handler: gdth_eh_device_reset,    \
-               eh_bus_reset_handler: gdth_eh_bus_reset,          \
-               eh_host_reset_handler: gdth_eh_host_reset,        \
-               abort:           gdth_abort,                      \
-               reset:           gdth_reset,                      \
-               bios_param:      gdth_bios_param,                 \
-               can_queue:       GDTH_MAXCMDS,                    \
-               this_id:         -1,                              \
-               sg_tablesize:    GDTH_MAXSG,                      \
-               cmd_per_lun:     GDTH_MAXC_P_L,                   \
-               present:         0,                               \
-               unchecked_isa_dma: 1,                             \
-               use_clustering:  ENABLE_CLUSTERING }
-
-#elif LINUX_VERSION_CODE >= 0x010300
-int gdth_bios_param(Disk *,kdev_t,int *);
-extern struct proc_dir_entry proc_scsi_gdth;
-int gdth_proc_info(char *,char **,off_t,int,int,int);
-#define GDTH { NULL, NULL,                              \
-                   &proc_scsi_gdth,                     \
-                   gdth_proc_info,                      \
-                   "GDT SCSI Disk Array Controller",    \
-                   gdth_detect,                         \
-                   gdth_release,                        \
-                   gdth_info,                           \
-                   NULL,                                \
-                   gdth_queuecommand,                   \
-                   gdth_abort,                          \
-                   gdth_reset,                          \
-                   NULL,                                \
-                   gdth_bios_param,                     \
-                   GDTH_MAXCMDS,                        \
-                   -1,                                  \
-                   GDTH_MAXSG,                          \
-                   GDTH_MAXC_P_L,                       \
-                   0,                                   \
-                   1,                                   \
-                   ENABLE_CLUSTERING}
-
-#else
-int gdth_bios_param(Disk *,int,int *);
-#define GDTH { NULL, NULL,                              \
-                   "GDT SCSI Disk Array Controller",    \
-                   gdth_detect,                         \
-                   gdth_release,                        \
-                   gdth_info,                           \
-                   NULL,                                \
-                   gdth_queuecommand,                   \
-                   gdth_abort,                          \
-                   gdth_reset,                          \
-                   NULL,                                \
-                   gdth_bios_param,                     \
-                   GDTH_MAXCMDS,                        \
-                   -1,                                  \
-                   GDTH_MAXSG,                          \
-                   GDTH_MAXC_P_L,                       \
-                   0,                                   \
-                   1,                                   \
-                   ENABLE_CLUSTERING}
-#endif
 
 #endif
 
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
--- a/drivers/scsi/hosts.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/hosts.h	Wed Jul 24 14:03:37 2002
@@ -210,9 +210,9 @@
      * This function determines the bios parameters for a given
      * harddisk.  These tend to be numbers that are made up by
      * the host adapter.  Parameters:
-     * size, device number, list (heads, sectors, cylinders)
+     * size, device, list (heads, sectors, cylinders)
      */
-    int (* bios_param)(Disk *, kdev_t, int []);
+    int (* bios_param)(Disk *, struct block_device *, int []);
 
 
     /*
diff -Nru a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
--- a/drivers/scsi/ibmmca.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/ibmmca.c	Wed Jul 24 14:03:36 2002
@@ -2382,7 +2382,7 @@
      return SCSI_RESET_SUCCESS;
 }
 
-int ibmmca_biosparam (Disk * disk, kdev_t dev, int *info)
+int ibmmca_biosparam (Disk * disk, struct block_device *dev, int *info)
 {
    info[0] = 64;
    info[1] = 32;
diff -Nru a/drivers/scsi/ibmmca.h b/drivers/scsi/ibmmca.h
--- a/drivers/scsi/ibmmca.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/ibmmca.h	Wed Jul 24 14:03:36 2002
@@ -17,7 +17,7 @@
 extern int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 extern int ibmmca_abort (Scsi_Cmnd *);
 extern int ibmmca_reset (Scsi_Cmnd *, unsigned int);
-extern int ibmmca_biosparam (Disk *, kdev_t, int *);
+extern int ibmmca_biosparam (Disk *, struct block_device *, int *);
 
 /*structure for /proc filesystem */
 extern struct proc_dir_entry proc_scsi_ibmmca;
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/ide-scsi.c	Wed Jul 24 14:03:35 2002
@@ -711,7 +711,7 @@
 	return SUCCESS;
 }
 
-static int idescsi_bios(Disk *disk, kdev_t dev, int *parm)
+static int idescsi_bios(Disk *disk, struct block_device *dev, int *parm)
 {
 	idescsi_scsi_t *scsi = idescsi_private(disk->device->host);
 	struct ata_device *drive = scsi->drive;
diff -Nru a/drivers/scsi/imm.c b/drivers/scsi/imm.c
--- a/drivers/scsi/imm.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/imm.c	Wed Jul 24 14:03:39 2002
@@ -1117,7 +1117,7 @@
  * be done in sd.c.  Even if it gets fixed there, this will still
  * work.
  */
-int imm_biosparam(Disk * disk, kdev_t dev, int ip[])
+int imm_biosparam(Disk * disk, struct block_device *dev, int ip[])
 {
     ip[0] = 0x40;
     ip[1] = 0x20;
diff -Nru a/drivers/scsi/imm.h b/drivers/scsi/imm.h
--- a/drivers/scsi/imm.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/imm.h	Wed Jul 24 14:03:35 2002
@@ -162,7 +162,7 @@
 int imm_abort(Scsi_Cmnd *);
 int imm_reset(Scsi_Cmnd *);
 int imm_proc_info(char *, char **, off_t, int, int, int);
-int imm_biosparam(Disk *, kdev_t, int *);
+int imm_biosparam(Disk *, struct block_device *, int *);
 
 #define IMM {	proc_name:			"imm",			\
 		proc_info:			imm_proc_info,		\
diff -Nru a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
--- a/drivers/scsi/in2000.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/in2000.c	Wed Jul 24 14:03:39 2002
@@ -2158,7 +2158,7 @@
  *       supposed to do...
  */
 
-int in2000_biosparam(Disk *disk, kdev_t dev, int *iinfo)
+int in2000_biosparam(Disk *disk, struct block_device *dev, int *iinfo)
 {
 int size;
 
diff -Nru a/drivers/scsi/in2000.h b/drivers/scsi/in2000.h
--- a/drivers/scsi/in2000.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/in2000.h	Wed Jul 24 14:03:35 2002
@@ -402,7 +402,7 @@
 int in2000_abort(Scsi_Cmnd *);
 void in2000_setup(char *, int *) in2000__INIT;
 int in2000_proc_info(char *, char **, off_t, int, int, int);
-int in2000_biosparam(struct scsi_disk *, kdev_t, int *);
+int in2000_biosparam(struct scsi_disk *, struct block_device *, int *);
 int in2000_reset(Scsi_Cmnd *, unsigned int);
 
 
diff -Nru a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c
--- a/drivers/scsi/ini9100u.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/ini9100u.c	Wed Jul 24 14:03:37 2002
@@ -583,7 +583,7 @@
 /*
  * Return the "logical geometry"
  */
-int i91u_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array)
+int i91u_biosparam(Scsi_Disk * disk, struct block_device *dev, int *info_array)
 {
 	HCS *pHcb;		/* Point to Host adapter control block */
 	TCS *pTcb;
diff -Nru a/drivers/scsi/ini9100u.h b/drivers/scsi/ini9100u.h
--- a/drivers/scsi/ini9100u.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/ini9100u.h	Wed Jul 24 14:03:38 2002
@@ -84,7 +84,7 @@
 extern int i91u_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 extern int i91u_abort(Scsi_Cmnd *);
 extern int i91u_reset(Scsi_Cmnd *, unsigned int);
-extern int i91u_biosparam(Scsi_Disk *, kdev_t, int *);	/*for linux v2.0 */
+extern int i91u_biosparam(Scsi_Disk *, struct block_device *, int *);
 
 #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.03g"
 
diff -Nru a/drivers/scsi/inia100.c b/drivers/scsi/inia100.c
--- a/drivers/scsi/inia100.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/inia100.c	Wed Jul 24 14:03:37 2002
@@ -653,7 +653,7 @@
  Output         : None.
  Return         : pSRB  -       Pointer to SCSI request block.
 *****************************************************************************/
-int inia100_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array)
+int inia100_biosparam(Scsi_Disk * disk, struct block_device *dev, int *info_array)
 {
 	ORC_HCS *pHcb;		/* Point to Host adapter control block */
 	ORC_TCS *pTcb;
diff -Nru a/drivers/scsi/inia100.h b/drivers/scsi/inia100.h
--- a/drivers/scsi/inia100.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/inia100.h	Wed Jul 24 14:03:35 2002
@@ -83,7 +83,7 @@
 extern int inia100_abort(Scsi_Cmnd *);
 extern int inia100_reset(Scsi_Cmnd *, unsigned int);
 
-extern int inia100_biosparam(Scsi_Disk *, kdev_t, int *);	/*for linux v2.0 */
+extern int inia100_biosparam(Scsi_Disk *, struct block_device *, int *);
 
 #define inia100_REVID "Initio INI-A100U2W SCSI device driver; Revision: 1.02c"
 
diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c
--- a/drivers/scsi/ips.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/ips.c	Wed Jul 24 14:03:35 2002
@@ -437,7 +437,7 @@
 int ips_eh_abort(Scsi_Cmnd *);
 int ips_eh_reset(Scsi_Cmnd *);
 int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));
-int ips_biosparam(Disk *, kdev_t, int *);
+int ips_biosparam(Disk *, struct block_device *, int *);
 const char * ips_info(struct Scsi_Host *);
 void do_ipsintr(int, void *, struct pt_regs *);
 static int ips_hainit(ips_ha_t *);
@@ -1853,7 +1853,7 @@
 /*                                                                          */
 /****************************************************************************/
 int
-ips_biosparam(Disk *disk, kdev_t dev, int geom[]) {
+ips_biosparam(Disk *disk, struct block_device *dev, int geom[]) {
    ips_ha_t         *ha;
    int               heads;
    int               sectors;
diff -Nru a/drivers/scsi/ips.h b/drivers/scsi/ips.h
--- a/drivers/scsi/ips.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/ips.h	Wed Jul 24 14:03:36 2002
@@ -56,7 +56,7 @@
    extern int ips_eh_abort(Scsi_Cmnd *);
    extern int ips_eh_reset(Scsi_Cmnd *);
    extern int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));
-   extern int ips_biosparam(Disk *, kdev_t, int *);
+   extern int ips_biosparam(Disk *, struct block_device *, int *);
    extern const char * ips_info(struct Scsi_Host *);
    extern void do_ips(int, void *, struct pt_regs *);
 
diff -Nru a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
--- a/drivers/scsi/mac_esp.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/mac_esp.c	Wed Jul 24 14:03:38 2002
@@ -360,14 +360,14 @@
 			} else {
 				/* q950, 900, 700 */
 				quick = 1;
-				writel(0x1d1, 0xf9800024);
+				out_be32(0xf9800024, 0x1d1);
 				esp->dregs = (void *) 0xf9800024;
 			}
 
 		} else { /* chipnum */
 
 			quick = 1;
-			writel(0x1d1, 0xf9800028);
+			out_be32(0xf9800028, 0x1d1);
 			esp->dregs = (void *) 0xf9800028;
 
 		} /* chipnum == 0 */
@@ -377,7 +377,7 @@
 
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = (volatile unsigned char*) cmd_buffer;
+		esp->esp_command_dvma = (__u32) cmd_buffer;
 
 		/* various functions */
 		esp->dma_bytes_sent = &dma_bytes_sent;
diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
--- a/drivers/scsi/megaraid.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/megaraid.c	Wed Jul 24 14:03:35 2002
@@ -4218,13 +4218,13 @@
  * Return the disk geometry for a particular disk
  * Input:
  *   Disk *disk - Disk geometry
- *   kdev_t dev - Device node
+ *   struct block_device *dev - Device node
  *   int *geom  - Returns geometry fields
  *     geom[0] = heads
  *     geom[1] = sectors
  *     geom[2] = cylinders
  *-------------------------------------------------------------*/
-int megaraid_biosparam (Disk * disk, kdev_t dev, int *geom)
+int megaraid_biosparam (Disk * disk, struct block_device *bdev, int *geom)
 {
 	int heads, sectors, cylinders;
 	mega_host_config *megaCfg;
@@ -4251,7 +4251,7 @@
 			geom[2] = cylinders;
 	}
 	else {
-		if( mega_partsize(disk, dev, geom) == 0 ) return 0;
+		if( mega_partsize(disk, bdev, geom) == 0 ) return 0;
 
 		printk(KERN_WARNING
 				"megaraid: invalid partition on this disk on channel %d\n",
@@ -4279,7 +4279,7 @@
 }
 
 /*
- * Function : static int mega_partsize(Disk * disk, kdev_t dev, int *geom)
+ * Function : static int mega_partsize(Disk * disk, struct block_device *bdev, int *geom)
  *
  * Purpose : to determine the BIOS mapping used to create the partition
  *			table, storing the results (cyls, hds, and secs) in geom
@@ -4289,7 +4289,7 @@
  * Returns : -1 on failure, 0 on success.
  */
 static int
-mega_partsize(Disk * disk, kdev_t dev, int *geom)
+mega_partsize(Disk * disk, struct block_device *bdev, int *geom)
 {
 	struct partition *p, *largest = NULL;
 	int i, largest_cyl;
@@ -4297,7 +4297,7 @@
 	int capacity = disk->capacity;
 	unsigned char *buf;
 
-	if (!(buf = scsi_bios_ptable(dev)))
+	if (!(buf = scsi_bios_ptable(bdev)))
 		return -1;
 
 	if( *(unsigned short *)(buf + 64) == 0xAA55 ) {
@@ -4534,7 +4534,6 @@
 	       unsigned int cmd, unsigned long arg)
 {
 	int adapno;
-	kdev_t dev;
 	u32 inlen;
 	struct uioctl_t ioc;
 	char *kvaddr = NULL;
@@ -4560,8 +4559,6 @@
 
 	if (!inode)
 		return -EINVAL;
-
-	dev = inode->i_rdev;
 
 	if (_IOC_TYPE (cmd) != MEGAIOC_MAGIC)
 		return (-EINVAL);
diff -Nru a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
--- a/drivers/scsi/megaraid.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/megaraid.h	Wed Jul 24 14:03:38 2002
@@ -950,7 +950,7 @@
 int megaraid_abort (Scsi_Cmnd *);
 int megaraid_reset (Scsi_Cmnd *, unsigned int);
 int megaraid_queue (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
-int megaraid_biosparam (Disk *, kdev_t, int *);
+int megaraid_biosparam (Disk *, struct block_device *, int *);
 int megaraid_proc_info (char *buffer, char **start, off_t offset,
 			int length, int hostno, int inout);
 
@@ -998,7 +998,7 @@
 static mega_ext_passthru* mega_prepare_extpassthru(mega_host_config *,
 		mega_scb *, Scsi_Cmnd *);
 static void mega_enum_raid_scsi(mega_host_config *);
-static int mega_partsize(Disk *, kdev_t, int *);
+static int mega_partsize(Disk *, struct block_device *, int *);
 static void mega_get_boot_ldrv(mega_host_config *);
 static int mega_get_lun(mega_host_config *, Scsi_Cmnd *);
 static int mega_support_random_del(mega_host_config *);
diff -Nru a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c
--- a/drivers/scsi/mvme16x.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/mvme16x.c	Wed Jul 24 14:03:37 2002
@@ -21,9 +21,9 @@
 
 #include<linux/stat.h>
 
-extern ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip,
-			unsigned long base, int io_port, int irq, int dma,
-			long long options, int clock);
+extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip,
+			  unsigned long base, int io_port, int irq, int dma,
+			  long long options, int clock);
 
 int mvme16x_scsi_detect(Scsi_Host_Template *tpnt)
 {
diff -Nru a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c
--- a/drivers/scsi/oktagon_esp.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/oktagon_esp.c	Wed Jul 24 14:03:35 2002
@@ -554,8 +554,8 @@
 
 void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp)
 {
-        sp->SCp.ptr = 
-                sp->SCp.buffer->address;
+        sp->SCp.ptr = page_address(sp->SCp.buffer->page)+
+		      sp->SCp.buffer->offset;
 }
 
 void dma_mmu_release_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp)
@@ -568,7 +568,8 @@
 
 void dma_advance_sg(Scsi_Cmnd *sp)
 {
-  sp->SCp.ptr = sp->SCp.buffer->address;
+	sp->SCp.ptr = page_address(sp->SCp.buffer->page)+
+		      sp->SCp.buffer->offset;
 }
 
 
diff -Nru a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
--- a/drivers/scsi/pas16.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/pas16.c	Wed Jul 24 14:03:35 2002
@@ -486,7 +486,7 @@
 }
 
 /*
- * Function : int pas16_biosparam(Disk *disk, kdev_t dev, int *ip)
+ * Function : int pas16_biosparam(Disk *disk, struct block_device *dev, int *ip)
  *
  * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 
  *	the specified device / size.
@@ -505,7 +505,7 @@
  * and matching the H_C_S coordinates to what DOS uses.
  */
 
-int pas16_biosparam(Disk * disk, kdev_t dev, int * ip)
+int pas16_biosparam(Disk * disk, struct block_device *dev, int * ip)
 {
   int size = disk->capacity;
   ip[0] = 64;
diff -Nru a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h
--- a/drivers/scsi/pas16.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/pas16.h	Wed Jul 24 14:03:38 2002
@@ -115,7 +115,7 @@
 
 #ifndef ASM
 int pas16_abort(Scsi_Cmnd *);
-int pas16_biosparam(Disk *, kdev_t, int*);
+int pas16_biosparam(Disk *, struct block_device *, int*);
 int pas16_detect(Scsi_Host_Template *);
 int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int pas16_reset(Scsi_Cmnd *, unsigned int);
diff -Nru a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c
--- a/drivers/scsi/pci2000.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/pci2000.c	Wed Jul 24 14:03:38 2002
@@ -830,7 +830,7 @@
  *	Returns:		zero.
  *
  ****************************************************************/
-int Pci2000_BiosParam (Scsi_Disk *disk, kdev_t dev, int geom[])
+int Pci2000_BiosParam (Scsi_Disk *disk, struct block_device *dev, int geom[])
 	{
 	PADAPTER2000	    padapter;
 
diff -Nru a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h
--- a/drivers/scsi/pci2000.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/pci2000.h	Wed Jul 24 14:03:37 2002
@@ -22,7 +22,6 @@
 #define _PCI2000_H
 
 #include <linux/types.h>
-#include <linux/kdev_t.h>
 
 #ifndef	PSI_EIDE_SCSIOP
 #define	PSI_EIDE_SCSIOP	1
@@ -194,7 +193,7 @@
 int Pci2000_Abort			(Scsi_Cmnd *SCpnt);
 int Pci2000_Reset			(Scsi_Cmnd *SCpnt, unsigned int flags);
 int Pci2000_Release			(struct Scsi_Host *pshost);
-int Pci2000_BiosParam		(Disk *disk, kdev_t dev, int geom[]);
+int Pci2000_BiosParam		(Disk *disk, struct block_device *dev, int geom[]);
 
 #ifndef NULL
 	#define NULL 0
diff -Nru a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c
--- a/drivers/scsi/pci2220i.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/pci2220i.c	Wed Jul 24 14:03:35 2002
@@ -49,7 +49,6 @@
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
-#include <linux/kdev_t.h>
 #include <linux/blk.h>
 #include <linux/timer.h>
 #include <linux/spinlock.h>
@@ -2903,7 +2902,7 @@
  *	Returns:		zero.
  *
  ****************************************************************/
-int Pci2220i_BiosParam (Scsi_Disk *disk, kdev_t dev, int geom[])
+int Pci2220i_BiosParam (Scsi_Disk *disk, struct block_device *dev, int geom[])
 	{
 	POUR_DEVICE	pdev;
 
diff -Nru a/drivers/scsi/pci2220i.h b/drivers/scsi/pci2220i.h
--- a/drivers/scsi/pci2220i.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/pci2220i.h	Wed Jul 24 14:03:38 2002
@@ -33,7 +33,7 @@
 int Pci2220i_Abort			(Scsi_Cmnd *SCpnt);
 int Pci2220i_Reset			(Scsi_Cmnd *SCpnt, unsigned int flags);
 int Pci2220i_Release		(struct Scsi_Host *pshost);
-int Pci2220i_BiosParam		(Disk *disk, kdev_t dev, int geom[]);
+int Pci2220i_BiosParam		(Disk *disk, struct block_device *dev, int geom[]);
 
 #ifndef NULL
 	#define NULL 0
diff -Nru a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
--- a/drivers/scsi/ppa.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/ppa.c	Wed Jul 24 14:03:35 2002
@@ -998,7 +998,7 @@
  * be done in sd.c.  Even if it gets fixed there, this will still
  * work.
  */
-int ppa_biosparam(Disk * disk, kdev_t dev, int ip[])
+int ppa_biosparam(Disk * disk, struct block_device *dev, int ip[])
 {
     ip[0] = 0x40;
     ip[1] = 0x20;
diff -Nru a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h
--- a/drivers/scsi/ppa.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/ppa.h	Wed Jul 24 14:03:37 2002
@@ -170,7 +170,7 @@
 int ppa_abort(Scsi_Cmnd *);
 int ppa_reset(Scsi_Cmnd *);
 int ppa_proc_info(char *, char **, off_t, int, int, int);
-int ppa_biosparam(Disk *, kdev_t, int *);
+int ppa_biosparam(Disk *, struct block_device *, int *);
 
 #define PPA {	proc_name:			"ppa",		\
 		proc_info:			ppa_proc_info,		\
diff -Nru a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c
--- a/drivers/scsi/psi240i.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/psi240i.c	Wed Jul 24 14:03:38 2002
@@ -703,7 +703,7 @@
  *	Returns:		zero.
  *
  ****************************************************************/
-int Psi240i_BiosParam (Scsi_Disk *disk, kdev_t dev, int geom[])
+int Psi240i_BiosParam (Scsi_Disk *disk, struct block_device *dev, int geom[])
 	{
 	POUR_DEVICE	pdev;
 
diff -Nru a/drivers/scsi/psi240i.h b/drivers/scsi/psi240i.h
--- a/drivers/scsi/psi240i.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/psi240i.h	Wed Jul 24 14:03:37 2002
@@ -28,7 +28,6 @@
 #define _PSI240I_H
 
 #include <linux/types.h>
-#include <linux/kdev_t.h>
 
 #ifndef	PSI_EIDE_SCSIOP
 #define	PSI_EIDE_SCSIOP	1
@@ -315,7 +314,7 @@
 int Psi240i_QueueCommand	(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
 int Psi240i_Abort			(Scsi_Cmnd *SCpnt);
 int Psi240i_Reset			(Scsi_Cmnd *SCpnt, unsigned int flags);
-int Psi240i_BiosParam		(Disk *disk, kdev_t dev, int geom[]);
+int Psi240i_BiosParam		(Disk *disk, struct block_device * dev, int geom[]);
 
 #ifndef NULL
 	#define NULL 0
diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
--- a/drivers/scsi/qla1280.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/qla1280.c	Wed Jul 24 14:03:39 2002
@@ -1699,7 +1699,7 @@
  *   Return the disk geometry for the given SCSI device.
  **************************************************************************/
 int
-qla1280_biosparam(Disk * disk, kdev_t dev, int geom[])
+qla1280_biosparam(Disk * disk, struct block_device *dev, int geom[])
 {
 	int heads, sectors, cylinders;
 
diff -Nru a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h
--- a/drivers/scsi/qla1280.h	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/qla1280.h	Wed Jul 24 14:03:39 2002
@@ -1313,7 +1313,7 @@
 int qla1280_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 int qla1280_abort(Scsi_Cmnd *);
 int qla1280_reset(Scsi_Cmnd *, unsigned int);
-int qla1280_biosparam(Disk *, kdev_t, int[]);
+int qla1280_biosparam(Disk *, struct block_device *, int[]);
 void qla1280_intr_handler(int, void *, struct pt_regs *);
 void qla1280_setup(char *s, int *dummy);
 
diff -Nru a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
--- a/drivers/scsi/qlogicfas.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/qlogicfas.c	Wed Jul 24 14:03:39 2002
@@ -651,7 +651,7 @@
 
 /*----------------------------------------------------------------*/
 /* return bios parameters */
-int	qlogicfas_biosparam(Disk * disk, kdev_t dev, int ip[])
+int	qlogicfas_biosparam(Disk * disk, struct block_device *dev, int ip[])
 {
 /* This should mimic the DOS Qlogic driver's behavior exactly */
 	ip[0] = 0x40;
diff -Nru a/drivers/scsi/qlogicfas.h b/drivers/scsi/qlogicfas.h
--- a/drivers/scsi/qlogicfas.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/qlogicfas.h	Wed Jul 24 14:03:37 2002
@@ -7,7 +7,7 @@
 int qlogicfas_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
 int qlogicfas_abort(Scsi_Cmnd *);
 int qlogicfas_reset(Scsi_Cmnd *, unsigned int);
-int qlogicfas_biosparam(Disk *, kdev_t, int[]);
+int qlogicfas_biosparam(Disk *, struct block_device *, int[]);
 
 #ifndef NULL
 #define NULL (0)
diff -Nru a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
--- a/drivers/scsi/qlogicfc.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/qlogicfc.c	Wed Jul 24 14:03:39 2002
@@ -1800,7 +1800,7 @@
 }
 
 
-int isp2x00_biosparam(Disk * disk, kdev_t n, int ip[])
+int isp2x00_biosparam(Disk * disk, struct block_device *n, int ip[])
 {
 	int size = disk->capacity;
 
diff -Nru a/drivers/scsi/qlogicfc.h b/drivers/scsi/qlogicfc.h
--- a/drivers/scsi/qlogicfc.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/qlogicfc.h	Wed Jul 24 14:03:37 2002
@@ -75,7 +75,7 @@
 int isp2x00_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
 int isp2x00_abort(Scsi_Cmnd *);
 int isp2x00_reset(Scsi_Cmnd *, unsigned int);
-int isp2x00_biosparam(Disk *, kdev_t, int[]);
+int isp2x00_biosparam(Disk *, struct block_device *, int[]);
 
 #ifndef NULL
 #define NULL (0)
diff -Nru a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c
--- a/drivers/scsi/qlogicisp.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/qlogicisp.c	Wed Jul 24 14:03:38 2002
@@ -84,14 +84,11 @@
 {								\
 	unsigned long flags;					\
 								\
-	save_flags(flags);					\
-	cli();							\
 	trace.buf[trace.next].name  = (w);			\
 	trace.buf[trace.next].time  = jiffies;			\
 	trace.buf[trace.next].index = (i);			\
 	trace.buf[trace.next].addr  = (long) (a);		\
 	trace.next = (trace.next + 1) & (TRACE_BUF_LEN - 1);	\
-	restore_flags(flags);					\
 }
 
 #else
@@ -1240,7 +1237,7 @@
 }
 
 
-int isp1020_biosparam(Disk *disk, kdev_t n, int ip[])
+int isp1020_biosparam(Disk *disk, struct block_device *n, int ip[])
 {
 	int size = disk->capacity;
 
@@ -1704,9 +1701,6 @@
 
 	ENTER("isp1020_load_parameters");
 
-	save_flags(flags);
-	cli();
-
 	hwrev = isp_inw(host, ISP_CFG0) & ISP_CFG0_HWMSK;
 	isp_cfg1 = ISP_CFG1_F64 | ISP_CFG1_BENAB;
 	if (hwrev == ISP_CFG0_1040A) {
@@ -1724,7 +1718,6 @@
 	isp1020_mbox_command(host, param);
 
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		restore_flags(flags);
 		printk("qlogicisp : set initiator id failure\n");
 		return 1;
 	}
@@ -1736,7 +1729,6 @@
 	isp1020_mbox_command(host, param);
 
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		restore_flags(flags);
 		printk("qlogicisp : set retry count failure\n");
 		return 1;
 	}
@@ -1747,7 +1739,6 @@
 	isp1020_mbox_command(host, param);
 
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		restore_flags(flags);
 		printk("qlogicisp : async data setup time failure\n");
 		return 1;
 	}
@@ -1759,7 +1750,6 @@
 	isp1020_mbox_command(host, param);
 
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		restore_flags(flags);
 		printk("qlogicisp : set active negation state failure\n");
 		return 1;
 	}
@@ -1771,7 +1761,6 @@
 	isp1020_mbox_command(host, param);
 
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		restore_flags(flags);
 		printk("qlogicisp : set pci control parameter failure\n");
 		return 1;
 	}
@@ -1782,7 +1771,6 @@
 	isp1020_mbox_command(host, param);
 
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		restore_flags(flags);
 		printk("qlogicisp : set tag age limit failure\n");
 		return 1;
 	}
@@ -1793,7 +1781,6 @@
 	isp1020_mbox_command(host, param);
 
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		restore_flags(flags);
 		printk("qlogicisp : set selection timeout failure\n");
 		return 1;
 	}
@@ -1812,7 +1799,6 @@
 		isp1020_mbox_command(host, param);
 
 		if (param[0] != MBOX_COMMAND_COMPLETE) {
-			restore_flags(flags);
 			printk("qlogicisp : set target parameter failure\n");
 			return 1;
 		}
@@ -1827,7 +1813,6 @@
 			isp1020_mbox_command(host, param);
 
 			if (param[0] != MBOX_COMMAND_COMPLETE) {
-				restore_flags(flags);
 				printk("qlogicisp : set device queue "
 				       "parameter failure\n");
 				return 1;
@@ -1854,7 +1839,6 @@
 	isp1020_mbox_command(host, param);
 
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		restore_flags(flags);
 		printk("qlogicisp : set response queue failure\n");
 		return 1;
 	}
@@ -1879,12 +1863,9 @@
 	isp1020_mbox_command(host, param);
 
 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		restore_flags(flags);
 		printk("qlogicisp : set request queue failure\n");
 		return 1;
 	}
-
-	restore_flags(flags);
 
 	LEAVE("isp1020_load_parameters");
 
diff -Nru a/drivers/scsi/qlogicisp.h b/drivers/scsi/qlogicisp.h
--- a/drivers/scsi/qlogicisp.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/qlogicisp.h	Wed Jul 24 14:03:35 2002
@@ -64,7 +64,7 @@
 int isp1020_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
 int isp1020_abort(Scsi_Cmnd *);
 int isp1020_reset(Scsi_Cmnd *, unsigned int);
-int isp1020_biosparam(Disk *, kdev_t, int[]);
+int isp1020_biosparam(Disk *, struct block_device *, int[]);
 
 #ifndef NULL
 #define NULL (0)
diff -Nru a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
--- a/drivers/scsi/qlogicpti.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/qlogicpti.c	Wed Jul 24 14:03:36 2002
@@ -1456,7 +1456,7 @@
 		} while (dq != NULL);
 		spin_unlock(qpti->qhost->host_lock);
 	}
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 int qlogicpti_abort(Scsi_Cmnd *Cmnd)
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/scsi.h	Wed Jul 24 14:03:36 2002
@@ -627,6 +627,8 @@
 	int allow_revalidate;
 	struct device sdev_driverfs_dev;
 };
+#define	to_scsi_device(d)	\
+	container_of(d, struct scsi_device, sdev_driverfs_dev)
 
 
 /*
diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/scsi_debug.c	Wed Jul 24 14:03:38 2002
@@ -1008,7 +1008,7 @@
 #endif
 }
 
-static int scsi_debug_biosparam(Disk * disk, kdev_t dev, int *info)
+static int scsi_debug_biosparam(Disk * disk, struct block_device *dev, int *info)
 {
 	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
 		printk(KERN_INFO "scsi_debug: biosparam\n");
diff -Nru a/drivers/scsi/scsi_debug.h b/drivers/scsi/scsi_debug.h
--- a/drivers/scsi/scsi_debug.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/scsi_debug.h	Wed Jul 24 14:03:38 2002
@@ -1,13 +1,12 @@
 #ifndef _SCSI_DEBUG_H
 
 #include <linux/types.h>
-#include <linux/kdev_t.h>
 
 static int scsi_debug_detect(Scsi_Host_Template *);
 /* static int scsi_debug_command(Scsi_Cmnd *); */
 static int scsi_debug_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 static int scsi_debug_abort(Scsi_Cmnd *);
-static int scsi_debug_biosparam(Disk *, kdev_t, int[]);
+static int scsi_debug_biosparam(Disk *, struct block_device *, int[]);
 static int scsi_debug_bus_reset(Scsi_Cmnd *);
 static int scsi_debug_device_reset(Scsi_Cmnd *);
 static int scsi_debug_host_reset(Scsi_Cmnd *);
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/scsi_lib.c	Wed Jul 24 14:03:38 2002
@@ -360,7 +360,7 @@
 {
 	request_queue_t *q = &SCpnt->device->request_queue;
 	struct request *req = SCpnt->request;
-	int flags;
+	unsigned long flags;
 
 	ASSERT_LOCK(q->queue_lock, 0);
 
diff -Nru a/drivers/scsi/scsi_mid_low_api.txt b/drivers/scsi/scsi_mid_low_api.txt
--- a/drivers/scsi/scsi_mid_low_api.txt	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/scsi_mid_low_api.txt	Wed Jul 24 14:03:39 2002
@@ -85,7 +85,7 @@
  *      pre-initialized with made up values just in case this function 
  *      doesn't output anything.
  **/
-    int bios_param(Scsi_Disk * sdkp, kdev_t dev, int params[3]);
+    int bios_param(Scsi_Disk * sdkp, struct block_device *bdev, int params[3]);
 
 
 /**
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/scsi_scan.c	Wed Jul 24 14:03:39 2002
@@ -293,8 +293,7 @@
 static ssize_t scsi_device_type_read(struct device *driverfs_dev, char *page, 
 	size_t count, loff_t off)
 {
-	struct scsi_device *SDpnt = list_entry(driverfs_dev,
-		struct scsi_device, sdev_driverfs_dev);
+	struct scsi_device *SDpnt = to_scsi_device(driverfs_dev);
 
 	if ((SDpnt->type <= MAX_SCSI_DEVICE_CODE) && 
 		(scsi_device_types[(int)SDpnt->type] != NULL))
diff -Nru a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c
--- a/drivers/scsi/scsicam.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/scsi/scsicam.c	Wed Jul 24 14:03:35 2002
@@ -26,39 +26,25 @@
 static int setsize(unsigned long capacity, unsigned int *cyls, unsigned int *hds,
 		   unsigned int *secs);
 
-unsigned char *scsi_bios_ptable(kdev_t dev)
+unsigned char *scsi_bios_ptable(struct block_device *dev)
 {
-	struct block_device *bdev;
 	unsigned char *res = kmalloc(66, GFP_KERNEL);
-	kdev_t rdev = mk_kdev(major(dev), minor(dev) & ~0x0f);
-
 	if (res) {
-		struct buffer_head *bh;
-		int err;
-
-		bdev = bdget(kdev_t_to_nr(rdev));
-		if (!bdev)
-			goto fail;
-		err = blkdev_get(bdev, FMODE_READ, 0, BDEV_FILE);
-		if (err)
-			goto fail;
-		bh = __bread(bdev, 0, block_size(bdev));
-		if (!bh)
-			goto fail2;
-		memcpy(res, bh->b_data + 0x1be, 66);
-		brelse(bh);
-		blkdev_put(bdev, BDEV_FILE);
+		struct block_device *bdev = dev->bd_contains;
+		struct buffer_head *bh = __bread(bdev, 0, block_size(bdev));
+		if (bh) {
+			memcpy(res, bh->b_data + 0x1be, 66);
+			brelse(bh);
+		} else {
+			kfree(res);
+			res = NULL;
+		}
 	}
 	return res;
-fail2:
-	blkdev_put(bdev, BDEV_FILE);
-fail:
-	kfree(res);
-	return NULL;
 }
 
 /*
- * Function : int scsicam_bios_param (Disk *disk, int dev, int *ip)
+ * Function : int scsicam_bios_param (Disk *disk, struct block_device *bdev, int *ip)
  *
  * Purpose : to determine the BIOS mapping used for a drive in a 
  *      SCSI-CAM system, storing the results in ip as required
@@ -69,13 +55,13 @@
  */
 
 int scsicam_bios_param(Disk * disk,	/* SCSI disk */
-		       kdev_t dev,	/* Device major, minor */
+		       struct block_device *bdev,
 		  int *ip /* Heads, sectors, cylinders in that order */ )
 {
 	int ret_code;
 	int size = disk->capacity;
 	unsigned long temp_cyl;
-	unsigned char *p = scsi_bios_ptable(dev);
+	unsigned char *p = scsi_bios_ptable(bdev);
 
 	if (!p)
 		return -1;
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/sd.c	Wed Jul 24 14:03:36 2002
@@ -233,33 +233,20 @@
 			   or driver values */
 	
 			if(host->hostt->bios_param != NULL)
-				host->hostt->bios_param(sdkp, dev,
+				host->hostt->bios_param(sdkp, inode->i_bdev,
 							&diskinfo[0]);
 			else
-				scsicam_bios_param(sdkp, dev, &diskinfo[0]);
+				scsicam_bios_param(sdkp, inode->i_bdev, &diskinfo[0]);
 			if (put_user(diskinfo[0], &loc->heads) ||
 				put_user(diskinfo[1], &loc->sectors) ||
 				put_user(diskinfo[2], &loc->cylinders) ||
 				put_user((unsigned) 
-					     get_start_sect(inode->i_rdev),
+					     get_start_sect(inode->i_bdev),
 					 (unsigned long *) &loc->start))
 				return -EFAULT;
 			return 0;
 		}
 
-		case BLKGETSIZE:
-		case BLKGETSIZE64:
-		case BLKROSET:
-		case BLKROGET:
-		case BLKFLSBUF:
-		case BLKSSZGET:
-		case BLKPG:
-                case BLKELVGET:
-                case BLKELVSET:
-		case BLKBSZGET:
-		case BLKBSZSET:
-			return blk_ioctl(inode->i_bdev, cmd, arg);
-
 		case BLKRRPART: /* Re-read partition tables */
 		        if (!capable(CAP_SYS_ADMIN))
 		                return -EACCES;
@@ -507,16 +494,6 @@
 	if (!scsi_block_when_processing_errors(sdp))
 		return -ENXIO;
 	/*
-	 * Make sure that only one process can do a check_change_disk at 
-	 * one time.  This is also used to lock out further access when 
-	 * the partition table is being re-read.
-	 */
-
-	while (sdp->busy) {
-		barrier();
-		cpu_relax();
-	}
-	/*
 	 * The following code can sleep.
 	 * Module unloading must be prevented
 	 */
@@ -527,9 +504,7 @@
 	sdp->access_count++;
 
 	if (sdp->removable) {
-		sdp->allow_revalidate = 1;
 		check_disk_change(inode->i_rdev);
-		sdp->allow_revalidate = 0;
 
 		/*
 		 * If the drive is empty, just let the open fail.
@@ -1464,9 +1439,10 @@
 int revalidate_scsidisk(kdev_t dev, int maxusage)
 {
 	int dsk_nr = DEVICE_NR(dev);
-	int res;
 	Scsi_Disk * sdkp;
 	Scsi_Device * sdp;
+	kdev_t device = mk_kdev(major(dev), minor(dev) & ~15);
+	int res;
 
 	SCSI_LOG_HLQUEUE(3, printk("revalidate_scsidisk: dsk_nr=%d\n", 
 				   DEVICE_NR(dev)));
@@ -1474,24 +1450,20 @@
 	if ((NULL == sdkp) || (NULL == (sdp = sdkp->device)))
 		return -ENODEV;
 
-	if (sdp->busy || ((sdp->allow_revalidate == 0) && 
-			  (sdp->access_count > maxusage))) {
-		printk(KERN_WARNING "Device busy for revalidation "
-		       "(access_count=%d)\n", sdp->access_count);
-		return -EBUSY;
-	}
-	sdp->busy = 1;
+	res = dev_lock_part(device);
+	if (res < 0)
+		return res;
 
-	res = wipe_partitions(dev);
+	res = wipe_partitions(device);
 	if (res)
 		goto leave;
 
 	sd_init_onedisk(sdkp, dsk_nr);
 
-	grok_partitions(dev, sdkp->capacity);
+	grok_partitions(device, sdkp->capacity);
 
 leave:
-	sdp->busy = 0;
+	dev_unlock_part(device);
 	return res;
 }
 
diff -Nru a/drivers/scsi/sim710.h b/drivers/scsi/sim710.h
--- a/drivers/scsi/sim710.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/sim710.h	Wed Jul 24 14:03:38 2002
@@ -14,7 +14,7 @@
 int sim710_bus_reset(Scsi_Cmnd * SCpnt);
 int sim710_dev_reset(Scsi_Cmnd * SCpnt);
 int sim710_host_reset(Scsi_Cmnd * SCpnt);
-int sim710_biosparam(Disk *, kdev_t, int*);
+int sim710_biosparam(Disk *, struct block_device *, int*);
 #ifdef MODULE
 int sim710_release(struct Scsi_Host *);
 #else
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/st.c	Wed Jul 24 14:03:38 2002
@@ -12,13 +12,13 @@
    Copyright 1992 - 2002 Kai Makisara
    email Kai.Makisara@metla.fi
 
-   Last modified: Sat Jun 15 13:01:56 2002 by makisara
+   Last modified: Mon Jul 22 13:27:21 2002 by makisara
    Some small formal changes - aeb, 950809
 
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
  */
 
-static char *verstr = "20020615";
+static char *verstr = "20020722";
 
 #include <linux/module.h>
 
@@ -76,11 +76,11 @@
 MODULE_LICENSE("GPL");
 
 MODULE_PARM(buffer_kbs, "i");
-MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size (KB; 32)");
+MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size for fixed block mode (KB; 32)");
 MODULE_PARM(write_threshold_kbs, "i");
 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 30)");
 MODULE_PARM(max_sg_segs, "i");
-MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (32)");
+MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (64)");
 
 #ifndef MODULE
 static struct st_dev_parm {
@@ -139,25 +139,26 @@
 
 static int modes_defined;
 
-static ST_buffer *new_tape_buffer(int, int);
+static ST_buffer *new_tape_buffer(int, int, int);
 static int enlarge_buffer(ST_buffer *, int, int);
 static void normalize_buffer(ST_buffer *);
 static int append_to_buffer(const char *, ST_buffer *, int);
 static int from_buffer(ST_buffer *, char *, int);
+static void buf_to_sg(ST_buffer *, unsigned int);
 
 static int st_attach(Scsi_Device *);
 static int st_detect(Scsi_Device *);
 static void st_detach(Scsi_Device *);
 
 static struct Scsi_Device_Template st_template = {
-	module:		THIS_MODULE,
-	name:		"tape", 
-	tag:		"st", 
-	scsi_type:	TYPE_TAPE,
-	major:		SCSI_TAPE_MAJOR, 
-	detect:		st_detect, 
-	attach:		st_attach, 
-	detach:		st_detach
+	.module =	THIS_MODULE,
+	.name =		"tape", 
+	.tag =		"st", 
+	.scsi_type =	TYPE_TAPE,
+	.major =	SCSI_TAPE_MAJOR, 
+	.detect =	st_detect, 
+	.attach =	st_attach, 
+	.detach =	st_detach
 };
 
 static int st_compression(Scsi_Tape *, int);
@@ -361,12 +362,11 @@
 	if (SRpnt->sr_device->scsi_level <= SCSI_2)
 		cmd[1] |= (SRpnt->sr_device->lun << 5) & 0xe0;
 	init_completion(&STp->wait);
-	SRpnt->sr_use_sg = (bytes > (STp->buffer)->sg[0].length) ?
-	    (STp->buffer)->use_sg : 0;
+	SRpnt->sr_use_sg = (bytes > (STp->buffer)->frp[0].length);
 	if (SRpnt->sr_use_sg) {
+		buf_to_sg(STp->buffer, bytes);
+		SRpnt->sr_use_sg = (STp->buffer)->sg_segs;
 		bp = (char *) &((STp->buffer)->sg[0]);
-		if ((STp->buffer)->sg_segs < SRpnt->sr_use_sg)
-			SRpnt->sr_use_sg = (STp->buffer)->sg_segs;
 	} else
 		bp = (STp->buffer)->b_data;
 	SRpnt->sr_data_direction = direction;
@@ -550,7 +550,6 @@
 
 	if (STp->ready != ST_READY)
 		return 0;
-
 	STps = &(STp->ps[STp->partition]);
 	if (STps->rw == ST_WRITING)	/* Writing */
 		return flush_write_buffer(STp);
@@ -1226,14 +1225,15 @@
 	ssize_t total;
 	ssize_t i, do_count, blks, transfer;
 	ssize_t retval;
-	int write_threshold;
-	int doing_write = 0;
+	int undone;
+	int async_write;
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	const char *b_point;
 	Scsi_Request *SRpnt = NULL;
 	Scsi_Tape *STp;
 	ST_mode *STm;
 	ST_partstat *STps;
+	ST_buffer *STbp;
 	int dev = TAPE_NR(inode->i_rdev);
 
 	read_lock(&st_dev_arr_lock);
@@ -1286,12 +1286,13 @@
 		}
 	}
 
-	if ((STp->buffer)->writing) {
+	STbp = STp->buffer;
+	if (STbp->writing) {
 		write_behind_check(STp);
-		if ((STp->buffer)->syscall_result) {
+		if (STbp->syscall_result) {
                         DEBC(printk(ST_DEB_MSG "st%d: Async write error (write) %x.\n",
-                                    dev, (STp->buffer)->midlevel_result));
-			if ((STp->buffer)->midlevel_result == INT_MAX)
+                                    dev, STbp->midlevel_result));
+			if (STbp->midlevel_result == INT_MAX)
 				STps->eof = ST_EOM_OK;
 			else
 				STps->eof = ST_EOM_ERROR;
@@ -1299,6 +1300,7 @@
 	}
 
 	if (STps->eof == ST_EOM_OK) {
+		STps->eof = ST_EOD_1;  /* allow next write */
 		retval = (-ENOSPC);
 		goto out;
 	}
@@ -1316,19 +1318,6 @@
 		goto out;
 	}
 
-	if (!STm->do_buffer_writes) {
-#if 0
-		if (STp->block_size != 0 && (count % STp->block_size) != 0) {
-			retval = (-EINVAL);	/* Write must be integral number of blocks */
-			goto out;
-		}
-#endif
-		write_threshold = 1;
-	} else
-		write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
-	if (!STm->do_async_writes)
-		write_threshold--;
-
 	total = count;
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -1338,29 +1327,44 @@
 	STps->rw = ST_WRITING;
 
 	b_point = buf;
-	while ((STp->block_size == 0 && !STm->do_async_writes && count > 0) ||
-	       (STp->block_size != 0 &&
-		(STp->buffer)->buffer_bytes + count > write_threshold)) {
-		doing_write = 1;
+	while (count > 0) {
+
 		if (STp->block_size == 0)
 			do_count = count;
 		else {
-			do_count = (STp->buffer)->buffer_blocks * STp->block_size -
-			    (STp->buffer)->buffer_bytes;
+			do_count = STbp->buffer_blocks * STp->block_size -
+			    STbp->buffer_bytes;
 			if (do_count > count)
 				do_count = count;
 		}
 
-		i = append_to_buffer(b_point, STp->buffer, do_count);
+		i = append_to_buffer(b_point, STbp, do_count);
 		if (i) {
 			retval = i;
 			goto out;
 		}
+		count -= do_count;
+		filp->f_pos += do_count;
+		b_point += do_count;
+
+		async_write = STm->do_async_writes && STps->eof < ST_EOM_OK;
+		if (STp->block_size != 0)
+			async_write &= count == 0 &&
+				(!STm->do_buffer_writes ||
+				 STbp->buffer_bytes >= STp->write_threshold);
+
+		if (STp->block_size != 0 && STm->do_buffer_writes && STps->eof < ST_EOM_OK &&
+		    STbp->buffer_bytes < STbp->buffer_size) {
+			STp->dirty = TRUE;
+			/* Don't write a buffer that is not full enough. */
+			if (!async_write && count == 0)
+				break;
+		}
 
 		if (STp->block_size == 0)
 			blks = transfer = do_count;
 		else {
-			blks = (STp->buffer)->buffer_bytes /
+			blks = STbp->buffer_bytes /
 			    STp->block_size;
 			transfer = blks * STp->block_size;
 		}
@@ -1369,47 +1373,59 @@
 		cmd[4] = blks;
 
 		SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, SCSI_DATA_WRITE,
-				   STp->timeout, MAX_WRITE_RETRIES, TRUE);
+				   STp->timeout, MAX_WRITE_RETRIES, !async_write);
 		if (!SRpnt) {
-			retval = (STp->buffer)->syscall_result;
+			retval = STbp->syscall_result;
 			goto out;
 		}
+		if (async_write) {
+			STbp->writing = transfer;
+			STp->dirty = !(STbp->writing ==
+				       STbp->buffer_bytes);
+			SRpnt = NULL;  /* Prevent releasing this request! */
+			DEB( STp->write_pending = 1; )
+			break;
+		}
 
-		if ((STp->buffer)->syscall_result != 0) {
+		if (STbp->syscall_result != 0) {
                         DEBC(printk(ST_DEB_MSG "st%d: Error on write:\n", dev));
 			if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
 			    (SRpnt->sr_sense_buffer[2] & 0x40)) {
 				if ((SRpnt->sr_sense_buffer[0] & 0x80) != 0)
-					transfer = (SRpnt->sr_sense_buffer[3] << 24) |
+					undone = (SRpnt->sr_sense_buffer[3] << 24) |
 					    (SRpnt->sr_sense_buffer[4] << 16) |
 					    (SRpnt->sr_sense_buffer[5] << 8) |
                                                 SRpnt->sr_sense_buffer[6];
 				else if (STp->block_size == 0 &&
 					 (SRpnt->sr_sense_buffer[2] & 0x0f) ==
                                          VOLUME_OVERFLOW)
-					transfer = do_count;
+					undone = do_count;
 				else
-					transfer = 0;
+					undone = 0;
 				if (STp->block_size != 0)
-					transfer *= STp->block_size;
-				if (transfer <= do_count) {
-					filp->f_pos += do_count - transfer;
-					count -= do_count - transfer;
-					if (STps->drv_block >= 0) {
-						if (STp->block_size == 0 &&
-                                                    transfer < do_count)
-							STps->drv_block++;
-						else if (STp->block_size != 0)
-							STps->drv_block +=
-                                                                (do_count - transfer) /
-                                                                STp->block_size;
-					}
+					undone *= STp->block_size;
+				filp->f_pos -= undone;
+				if (undone <= do_count) {
+					/* Only data from this write is not written */
+					count -= undone;
+					do_count -= undone;
+					if (STp->block_size)
+						blks = (transfer - undone) / STp->block_size;
 					STps->eof = ST_EOM_OK;
-					retval = (-ENOSPC); /* EOM within current request */
+					/* Continue in fixed block mode if all written
+					   in this request but still something left to write
+					   (retval left to zero)
+					*/
+					if (STp->block_size == 0 ||
+					   undone > 0 || count == 0)
+						retval = (-ENOSPC); /* EOM within current request */
                                         DEBC(printk(ST_DEB_MSG
                                                        "st%d: EOM with %d bytes unwritten.\n",
 						       dev, transfer));
 				} else {
+					/* Previously buffered data not written */
+					count -= do_count;
+					blks = do_count = 0;
 					STps->eof = ST_EOM_ERROR;
 					STps->drv_block = (-1); /* Too cautious? */
 					retval = (-EIO);	/* EOM for old data */
@@ -1418,80 +1434,33 @@
                                                        dev));
 				}
 			} else {
+				filp->f_pos -= do_count;
 				STps->drv_block = (-1);		/* Too cautious? */
 				retval = (-EIO);
 			}
 
-			scsi_release_request(SRpnt);
-			SRpnt = NULL;
-			(STp->buffer)->buffer_bytes = 0;
-			STp->dirty = 0;
-			if (count < total)
-				retval = total - count;
-			goto out;
 		}
-		filp->f_pos += do_count;
-		b_point += do_count;
-		count -= do_count;
+
 		if (STps->drv_block >= 0) {
 			if (STp->block_size == 0)
-				STps->drv_block++;
+				STps->drv_block += (do_count > 0);
 			else
 				STps->drv_block += blks;
 		}
-		(STp->buffer)->buffer_bytes = 0;
-		STp->dirty = 0;
-	}
-	if (count != 0) {
-		STp->dirty = 1;
-		i = append_to_buffer(b_point, STp->buffer, count);
-		if (i) {
-			retval = i;
-			goto out;
-		}
-		filp->f_pos += count;
-		count = 0;
-	}
 
-	if (doing_write && (STp->buffer)->syscall_result != 0) {
-		retval = (STp->buffer)->syscall_result;
-		goto out;
-	}
-
-	if (STm->do_async_writes &&
-	    (((STp->buffer)->buffer_bytes >= STp->write_threshold &&
-	      (STp->buffer)->buffer_bytes >= STp->block_size) ||
-	     STp->block_size == 0)) {
-		/* Schedule an asynchronous write */
-		if (STp->block_size == 0)
-			(STp->buffer)->writing = (STp->buffer)->buffer_bytes;
-		else
-			(STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
-				      STp->block_size) * STp->block_size;
-		STp->dirty = !((STp->buffer)->writing ==
-			       (STp->buffer)->buffer_bytes);
-
-		if (STp->block_size == 0)
-			blks = (STp->buffer)->writing;
-		else
-			blks = (STp->buffer)->writing / STp->block_size;
-		cmd[2] = blks >> 16;
-		cmd[3] = blks >> 8;
-		cmd[4] = blks;
-		DEB( STp->write_pending = 1; )
+		STbp->buffer_bytes = 0;
+		STp->dirty = 0;
 
-		SRpnt = st_do_scsi(SRpnt, STp, cmd, (STp->buffer)->writing,
-				   SCSI_DATA_WRITE, STp->timeout,
-				   MAX_WRITE_RETRIES, FALSE);
-		if (SRpnt == NULL) {
-			retval = (STp->buffer)->syscall_result;
+		if (retval) {
+			if (count < total)
+				retval = total - count;
 			goto out;
 		}
-		SRpnt = NULL;  /* Prevent releasing this request! */
-
 	}
-	STps->at_sm &= (total == 0);
-	if (total > 0)
+
+	if (STps->eof == ST_EOD_1)
+		STps->eof = ST_EOM_OK;
+	else
 		STps->eof = ST_NOEOF;
 	retval = total;
 
@@ -2425,7 +2394,7 @@
 		if (STp->write_prot)
 			return (-EACCES);
 		cmd[0] = ERASE;
-		cmd[1] = 1;	/* To the end of tape */
+		cmd[1] = (arg ? 1 : 0);	/* Long erase with non-zero argument */
 		if (STp->immediate) {
 			cmd[1] |= 2;	/* Don't wait for completion */
 			timeout = STp->timeout;
@@ -3296,7 +3265,7 @@
 /* Try to allocate a new tape buffer. Calling function must not hold
    dev_arr_lock. */
 static ST_buffer *
- new_tape_buffer(int from_initialization, int need_dma)
+ new_tape_buffer(int from_initialization, int need_dma, int max_sg)
 {
 	int i, priority, got = 0, segs = 0;
 	ST_buffer *tb;
@@ -3306,26 +3275,29 @@
 	else
 		priority = GFP_KERNEL;
 
-	i = sizeof(ST_buffer) + (st_max_sg_segs - 1) * sizeof(struct scatterlist);
+	i = sizeof(ST_buffer) + (max_sg - 1) * sizeof(struct scatterlist) +
+		max_sg * sizeof(struct st_buf_fragment);
 	tb = kmalloc(i, priority);
 	if (!tb) {
 		printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
 		return NULL;
 	}
-	tb->sg_segs = tb->orig_sg_segs = segs;
+	memset(tb, 0, i);
+	tb->frp_segs = tb->orig_frp_segs = segs;
+	tb->use_sg = max_sg;
 	if (segs > 0)
 		tb->b_data = page_address(tb->sg[0].page);
+	tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
 
 	tb->in_use = TRUE;
 	tb->dma = need_dma;
 	tb->buffer_size = got;
-	tb->writing = 0;
 
 	return tb;
 }
 
 
-/* Try to allocate a temporary enlarged tape buffer */
+/* Try to allocate enough space in the tape buffer */
 static int enlarge_buffer(ST_buffer * STbuffer, int new_size, int need_dma)
 {
 	int segs, nbr, max_segs, b_size, priority, order, got;
@@ -3333,12 +3305,11 @@
 	if (new_size <= STbuffer->buffer_size)
 		return TRUE;
 
-	normalize_buffer(STbuffer);
+	if (STbuffer->buffer_size <= PAGE_SIZE)
+		normalize_buffer(STbuffer);  /* Avoid extra segment */
 
 	max_segs = STbuffer->use_sg;
-	if (max_segs > st_max_sg_segs)
-		max_segs = st_max_sg_segs;
-	nbr = max_segs - STbuffer->sg_segs;
+	nbr = max_segs - STbuffer->frp_segs;
 	if (nbr <= 0)
 		return FALSE;
 
@@ -3350,12 +3321,10 @@
 	     order++, b_size *= 2)
 		;  /* empty */
 
-	for (segs = STbuffer->sg_segs, got = STbuffer->buffer_size;
+	for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
 	     segs < max_segs && got < new_size;) {
-		STbuffer->sg[segs].page = alloc_pages(priority, order);
-		/* printk("st: allocated %x, order %d\n", STbuffer->sg[segs].page, order); */
-		STbuffer->sg[segs].offset = 0;
-		if (STbuffer->sg[segs].page == NULL) {
+		STbuffer->frp[segs].page = alloc_pages(priority, order);
+		if (STbuffer->frp[segs].page == NULL) {
 			if (new_size - got <= (max_segs - segs) * b_size / 2) {
 				b_size /= 2; /* Large enough for the rest of the buffers */
 				order--;
@@ -3367,16 +3336,16 @@
 			normalize_buffer(STbuffer);
 			return FALSE;
 		}
-		STbuffer->sg[segs].length = b_size;
-		STbuffer->sg_segs += 1;
+		STbuffer->frp[segs].length = b_size;
+		STbuffer->frp_segs += 1;
 		got += b_size;
 		STbuffer->buffer_size = got;
 		segs++;
 	}
-	STbuffer->b_data = page_address(STbuffer->sg[0].page);
+	STbuffer->b_data = page_address(STbuffer->frp[0].page);
         DEBC(printk(ST_DEB_MSG
                     "st: Succeeded to enlarge buffer at %p to %d bytes (segs %d->%d, %d).\n",
-                    STbuffer, got, STbuffer->orig_sg_segs, STbuffer->sg_segs, b_size));
+                    STbuffer, got, STbuffer->orig_frp_segs, STbuffer->frp_segs, b_size));
 
 	return TRUE;
 }
@@ -3385,22 +3354,20 @@
 /* Release the extra buffer */
 static void normalize_buffer(ST_buffer * STbuffer)
 {
-	int i, order, b_size;
+	int i, order;
 
-	for (i = STbuffer->orig_sg_segs; i < STbuffer->sg_segs; i++) {
-		for (b_size=PAGE_SIZE, order=0; b_size < STbuffer->sg[i].length;
-		     order++, b_size *= 2)
-			; /* empty */
-		/* printk("st: freeing %x, order %d\n", STbuffer->sg[i].page, order); */
-		__free_pages(STbuffer->sg[i].page, order);
-		STbuffer->buffer_size -= STbuffer->sg[i].length;
+	for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
+		order = get_order(STbuffer->frp[i].length);
+		__free_pages(STbuffer->frp[i].page, order);
+		STbuffer->buffer_size -= STbuffer->frp[i].length;
 	}
         DEB(
-	if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
-		printk(ST_DEB_MSG "st: Buffer at %p normalized to %d bytes (segs %d).\n",
-		       STbuffer, STbuffer->buffer_size, STbuffer->sg_segs);
+	if (debugging && STbuffer->orig_frp_segs < STbuffer->frp_segs)
+		printk(ST_DEB_MSG "st: Buffer at %p normalized to %d bytes (segs %d->%d).\n",
+		       STbuffer, STbuffer->buffer_size, STbuffer->frp_segs, STbuffer->orig_frp_segs);
         ) /* end DEB */
-	STbuffer->sg_segs = STbuffer->orig_sg_segs;
+	STbuffer->frp_segs = STbuffer->orig_frp_segs;
+	STbuffer->frp_sg_current = 0;
 }
 
 
@@ -3411,16 +3378,16 @@
 	int i, cnt, res, offset;
 
 	for (i = 0, offset = st_bp->buffer_bytes;
-	     i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
-		offset -= st_bp->sg[i].length;
-	if (i == st_bp->sg_segs) {	/* Should never happen */
+	     i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
+		offset -= st_bp->frp[i].length;
+	if (i == st_bp->frp_segs) {	/* Should never happen */
 		printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
 		return (-EIO);
 	}
-	for (; i < st_bp->sg_segs && do_count > 0; i++) {
-		cnt = st_bp->sg[i].length - offset < do_count ?
-		    st_bp->sg[i].length - offset : do_count;
-		res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
+	for (; i < st_bp->frp_segs && do_count > 0; i++) {
+		cnt = st_bp->frp[i].length - offset < do_count ?
+		    st_bp->frp[i].length - offset : do_count;
+		res = copy_from_user(page_address(st_bp->frp[i].page) + offset, ubp, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -3444,16 +3411,16 @@
 	int i, cnt, res, offset;
 
 	for (i = 0, offset = st_bp->read_pointer;
-	     i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
-		offset -= st_bp->sg[i].length;
-	if (i == st_bp->sg_segs) {	/* Should never happen */
+	     i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
+		offset -= st_bp->frp[i].length;
+	if (i == st_bp->frp_segs) {	/* Should never happen */
 		printk(KERN_WARNING "st: from_buffer offset overflow.\n");
 		return (-EIO);
 	}
-	for (; i < st_bp->sg_segs && do_count > 0; i++) {
-		cnt = st_bp->sg[i].length - offset < do_count ?
-		    st_bp->sg[i].length - offset : do_count;
-		res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
+	for (; i < st_bp->frp_segs && do_count > 0; i++) {
+		cnt = st_bp->frp[i].length - offset < do_count ?
+		    st_bp->frp[i].length - offset : do_count;
+		res = copy_to_user(ubp, page_address(st_bp->frp[i].page) + offset, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -3471,6 +3438,33 @@
 }
 
 
+/* Fill the s/g list up to the length required for this transfer */
+static void buf_to_sg(ST_buffer *STbp, unsigned int length)
+{
+	int i;
+	unsigned int count;
+	struct scatterlist *sg;
+	struct st_buf_fragment *frp;
+
+	if (length == STbp->frp_sg_current)
+		return;   /* work already done */
+
+	sg = &(STbp->sg[0]);
+	frp = STbp->frp;
+	for (i=count=0; count < length; i++) {
+		sg[i].page = frp[i].page;
+		if (length - count > frp[i].length)
+			sg[i].length = frp[i].length;
+		else
+			sg[i].length = length - count;
+		count += sg[i].length;
+		sg[i].offset = 0;
+	}
+	STbp->sg_segs = i;
+	STbp->frp_sg_current = length;
+}
+
+
 /* Validate the options from command line or module parameters */
 static void validate_options(void)
 {
@@ -3587,7 +3581,10 @@
 		return 1;
 	}
 
-	buffer = new_tape_buffer(TRUE, (SDp->host)->unchecked_isa_dma);
+	i = SDp->host->sg_tablesize;
+	if (st_max_sg_segs < i)
+		i = st_max_sg_segs;
+	buffer = new_tape_buffer(TRUE, (SDp->host)->unchecked_isa_dma, i);
 	if (buffer == NULL) {
 		printk(KERN_ERR "st: Can't allocate new tape buffer. Device not attached.\n");
 		return 1;
@@ -3702,7 +3699,6 @@
 	else
 		tpnt->tape_type = MT_ISSCSI2;
 
-	buffer->use_sg = tpnt->device->host->sg_tablesize;
 	tpnt->buffer = buffer;
 
         tpnt->inited = 0;
@@ -3714,7 +3710,7 @@
 	tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
 	tpnt->density = 0;
 	tpnt->do_auto_lock = ST_AUTO_LOCK;
-	tpnt->can_bsr = ST_IN_FILE_POS;
+	tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
 	tpnt->can_partitions = 0;
 	tpnt->two_fm = ST_TWO_FM;
 	tpnt->fast_mteom = ST_FAST_MTEOM;
@@ -3802,7 +3798,7 @@
 				put_device(&tpnt->driverfs_dev_n[mode]);
 			}
 			if (tpnt->buffer) {
-				tpnt->buffer->orig_sg_segs = 0;
+				tpnt->buffer->orig_frp_segs = 0;
 				normalize_buffer(tpnt->buffer);
 				kfree(tpnt->buffer);
 			}
diff -Nru a/drivers/scsi/st.h b/drivers/scsi/st.h
--- a/drivers/scsi/st.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/st.h	Wed Jul 24 14:03:37 2002
@@ -21,12 +21,20 @@
 	int syscall_result;
 	Scsi_Request *last_SRpnt;
 	unsigned char *b_data;
-	unsigned short use_sg;	/* zero or number of segments for this adapter */
-	unsigned short sg_segs;	/* total number of allocated segments */
-	unsigned short orig_sg_segs;	/* number of segments allocated at first try */
+	unsigned short use_sg;	/* zero or maximum number of s/g segments for this adapter */
+	unsigned short sg_segs;		/* number of segments in s/g list */
+	unsigned short orig_frp_segs;	/* number of segments allocated at first try */
+	unsigned short frp_segs;	/* number of buffer segments */
+	unsigned int frp_sg_current;	/* driver buffer length currently in s/g list */
+	struct st_buf_fragment *frp;	/* the allocated buffer fragment list */
 	struct scatterlist sg[1];	/* MUST BE last item */
 } ST_buffer;
 
+/* The tape buffer fragment descriptor */
+struct st_buf_fragment {
+	struct page *page;
+	unsigned int length;
+};
 
 /* The tape mode definition */
 typedef struct {
@@ -147,6 +155,9 @@
 #define ST_EOD		7
 /* EOD hit while reading => ST_EOD_1 => return zero => ST_EOD_2 =>
    return zero => ST_EOD, return ENOSPC */
+/* When writing: ST_EOM_OK == early warning found, write OK
+		 ST_EOD_1  == allow trying new write after early warning
+		 ST_EOM_ERROR == early warning found, not able to write all */
 
 /* Values of rw */
 #define	ST_IDLE		0
diff -Nru a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
--- a/drivers/scsi/sym53c416.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/sym53c416.c	Wed Jul 24 14:03:36 2002
@@ -828,7 +828,7 @@
 	return SCSI_RESET_PENDING;
 }
 
-static int sym53c416_bios_param(Disk *disk, kdev_t dev, int *ip)
+static int sym53c416_bios_param(Disk *disk, struct block_device *dev, int *ip)
 {
 	int size;
 
diff -Nru a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h
--- a/drivers/scsi/sym53c416.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/scsi/sym53c416.h	Wed Jul 24 14:03:36 2002
@@ -27,7 +27,6 @@
 #endif
 
 #include <linux/types.h>
-#include <linux/kdev_t.h>
 
 #define SYM53C416_SCSI_ID 7
 
@@ -37,7 +36,7 @@
 static int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 static int sym53c416_abort(Scsi_Cmnd *);
 static int sym53c416_reset(Scsi_Cmnd *, unsigned int);
-static int sym53c416_bios_param(Disk *, kdev_t, int *);
+static int sym53c416_bios_param(Disk *, struct block_device *, int *);
 static void sym53c416_setup(char *str, int *ints);
 
 #define SYM53C416 {                                          \
diff -Nru a/drivers/scsi/t128.c b/drivers/scsi/t128.c
--- a/drivers/scsi/t128.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/t128.c	Wed Jul 24 14:03:39 2002
@@ -279,7 +279,7 @@
 }
 
 /*
- * Function : int t128_biosparam(Disk * disk, kdev_t dev, int *ip)
+ * Function : int t128_biosparam(Disk * disk, struct block_device *dev, int *ip)
  *
  * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 
  *	the specified device / size.
@@ -298,7 +298,7 @@
  * and matching the H_C_S coordinates to what DOS uses.
  */
 
-int t128_biosparam(Disk * disk, kdev_t dev, int * ip)
+int t128_biosparam(Disk * disk, struct block_device *dev, int * ip)
 {
   int size = disk->capacity;
   ip[0] = 64;
diff -Nru a/drivers/scsi/t128.h b/drivers/scsi/t128.h
--- a/drivers/scsi/t128.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/t128.h	Wed Jul 24 14:03:37 2002
@@ -92,7 +92,7 @@
 
 #ifndef ASM
 int t128_abort(Scsi_Cmnd *);
-int t128_biosparam(Disk *, kdev_t, int*);
+int t128_biosparam(Disk *, struct block_device *, int*);
 int t128_detect(Scsi_Host_Template *);
 int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int t128_reset(Scsi_Cmnd *, unsigned int reset_flags);
diff -Nru a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
--- a/drivers/scsi/tmscsim.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/tmscsim.c	Wed Jul 24 14:03:38 2002
@@ -1439,7 +1439,7 @@
  * Note:
  *   In contrary to other externally callable funcs (DC390_), we don't lock
  ***********************************************************************/
-int DC390_bios_param (Disk *disk, kdev_t devno, int geom[])
+int DC390_bios_param (Disk *disk, struct block_device *bdev, int geom[])
 {
     int heads, sectors, cylinders;
     PACB pACB = (PACB) disk->device->host->hostdata;
@@ -1447,7 +1447,7 @@
     int size = disk->capacity;
     unsigned char *buf;
 
-    if ((buf = scsi_bios_ptable(devno)))
+    if ((buf = scsi_bios_ptable(bdev)))
     {
 	/* try to infer mapping from partition table */
 	ret_code = partsize (buf, (unsigned long) size, (unsigned int *) geom + 2,
@@ -1475,9 +1475,9 @@
     return (0);
 }
 #else
-int DC390_bios_param (Disk *disk, kdev_t devno, int geom[])
+int DC390_bios_param (Disk *disk, struct block_device *bdev, int geom[])
 {
-    return scsicam_bios_param (disk, devno, geom);
+    return scsicam_bios_param (disk, bdev, geom);
 };
 #endif
 
@@ -2525,8 +2525,8 @@
 if (dc390_search (&buffer, &pos, &p0, &var, txt, max, scale, "")) goto einv2; 		\
 else if (!p1) goto ok2
 
-#define SEARCH3(buffer, pos, &p0, var, txt, max, scale, ign)				\
-if (dc390_search (&buffer, &pos, p0, &var, txt, max, scale, ign)) goto einv2;		\
+#define SEARCH3(buffer, pos, p0, var, txt, max, scale, ign)				\
+if (dc390_search (&buffer, &pos, &p0, &var, txt, max, scale, ign)) goto einv2;		\
 else if (!p1) goto ok2
 
 
diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
--- a/drivers/scsi/u14-34f.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/u14-34f.c	Wed Jul 24 14:03:37 2002
@@ -1452,7 +1452,7 @@
    return do_reset(SCarg);
 }
 
-int u14_34f_biosparam(Disk *disk, kdev_t dev, int *dkinfo) {
+int u14_34f_biosparam(Disk *disk, struct block_device *bdev, int *dkinfo) {
    unsigned int j = 0;
    int size = disk->capacity;
 
@@ -1460,7 +1460,7 @@
    dkinfo[1] = HD(j)->sectors;
    dkinfo[2] = size / (HD(j)->heads * HD(j)->sectors);
 
-   if (ext_tran && (scsicam_bios_param(disk, dev, dkinfo) < 0)) {
+   if (ext_tran && (scsicam_bios_param(disk, bdev, dkinfo) < 0)) {
       dkinfo[0] = 255;
       dkinfo[1] = 63;
       dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
diff -Nru a/drivers/scsi/u14-34f.h b/drivers/scsi/u14-34f.h
--- a/drivers/scsi/u14-34f.h	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/u14-34f.h	Wed Jul 24 14:03:39 2002
@@ -11,7 +11,7 @@
 int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int u14_34f_abort(Scsi_Cmnd *);
 int u14_34f_reset(Scsi_Cmnd *);
-int u14_34f_biosparam(Disk *, kdev_t, int *);
+int u14_34f_biosparam(Disk *, struct block_device *, int *);
 
 #define U14_34F_VERSION "7.22.00"
 
diff -Nru a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
--- a/drivers/scsi/ultrastor.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/scsi/ultrastor.c	Wed Jul 24 14:03:38 2002
@@ -1020,7 +1020,7 @@
 
 }
 
-int ultrastor_biosparam(Disk * disk, kdev_t dev, int * dkinfo)
+int ultrastor_biosparam(Disk * disk, struct block_device *dev, int * dkinfo)
 {
     int size = disk->capacity;
     unsigned int s = config.heads * config.sectors;
diff -Nru a/drivers/scsi/ultrastor.h b/drivers/scsi/ultrastor.h
--- a/drivers/scsi/ultrastor.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/scsi/ultrastor.h	Wed Jul 24 14:03:37 2002
@@ -12,14 +12,13 @@
 
 #ifndef _ULTRASTOR_H
 #define _ULTRASTOR_H
-#include <linux/kdev_t.h>
 
 int ultrastor_detect(Scsi_Host_Template *);
 const char *ultrastor_info(struct Scsi_Host * shpnt);
 int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int ultrastor_abort(Scsi_Cmnd *);
 int ultrastor_reset(Scsi_Cmnd *, unsigned int);
-int ultrastor_biosparam(Disk *, kdev_t, int *);
+int ultrastor_biosparam(Disk *, struct block_device *, int *);
 
 
 #define ULTRASTOR_14F_MAX_SG 16
diff -Nru a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
--- a/drivers/scsi/wd7000.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/wd7000.c	Wed Jul 24 14:03:39 2002
@@ -1706,9 +1706,9 @@
 /*
  *  This was borrowed directly from aha1542.c. (Zaga)
  */
-int wd7000_biosparam (Disk *disk, kdev_t dev, int *ip)
+int wd7000_biosparam (Disk *disk, struct block_device *bdev, int *ip)
 {
-    dprintk("wd7000_biosparam: dev=%s, size=%d, ", kdevname(dev),
+    dprintk("wd7000_biosparam: dev=%s, size=%d, ", bdevname(bdev),
 	    disk->capacity);
 
     /*
@@ -1727,7 +1727,7 @@
 	/*
 	 * try to figure out the geometry from the partition table
 	 */
-	if ((scsicam_bios_param (disk, dev, info) < 0) ||
+	if ((scsicam_bios_param (disk, bdev, info) < 0) ||
 	    !(((info[0] == 64) && (info[1] == 32)) ||
 	      ((info[0] == 255) && (info[1] == 63)))) {
 	    printk ("wd7000_biosparam: unable to verify geometry for disk with >1GB.\n"
diff -Nru a/drivers/scsi/wd7000.h b/drivers/scsi/wd7000.h
--- a/drivers/scsi/wd7000.h	Wed Jul 24 14:03:39 2002
+++ b/drivers/scsi/wd7000.h	Wed Jul 24 14:03:39 2002
@@ -12,7 +12,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/kdev_t.h>
 
 int wd7000_set_info (char *buffer, int length, struct Scsi_Host *host);
 int wd7000_proc_info (char *buffer, char **start, off_t offset, int length, int hostno, int inout);
@@ -21,7 +20,7 @@
 int wd7000_queuecommand (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int wd7000_abort (Scsi_Cmnd *);
 int wd7000_reset (Scsi_Cmnd *, unsigned int);
-int wd7000_biosparam (Disk *, kdev_t, int *);
+int wd7000_biosparam (Disk *, struct block_device *, int *);
 
 #ifndef NULL
 #define NULL 0L
diff -Nru a/drivers/serial/21285.c b/drivers/serial/21285.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/21285.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,540 @@
+/*
+ * linux/drivers/char/21285.c
+ *
+ * Driver for the serial port on the 21285 StrongArm-110 core logic chip.
+ *
+ * Based on drivers/char/serial.c
+ *
+ *  $Id: 21285.c,v 1.34 2002/07/22 15:27:32 rmk Exp $
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/serial_core.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/hardware/dec21285.h>
+#include <asm/hardware.h>
+
+#define BAUD_BASE		(mem_fclk_21285/64)
+
+#define SERIAL_21285_NAME	"ttyFB"
+#define SERIAL_21285_MAJOR	204
+#define SERIAL_21285_MINOR	4
+
+#define RXSTAT_DUMMY_READ	0x80000000
+#define RXSTAT_FRAME		(1 << 0)
+#define RXSTAT_PARITY		(1 << 1)
+#define RXSTAT_OVERRUN		(1 << 2)
+#define RXSTAT_ANYERR		(RXSTAT_FRAME|RXSTAT_PARITY|RXSTAT_OVERRUN)
+
+#define H_UBRLCR_BREAK		(1 << 0)
+#define H_UBRLCR_PARENB		(1 << 1)
+#define H_UBRLCR_PAREVN		(1 << 2)
+#define H_UBRLCR_STOPB		(1 << 3)
+#define H_UBRLCR_FIFO		(1 << 4)
+
+static const char serial21285_name[] = "Footbridge UART";
+
+#define tx_enabled(port)	((port)->unused[0])
+#define rx_enabled(port)	((port)->unused[1])
+
+/*
+ * The documented expression for selecting the divisor is:
+ *  BAUD_BASE / baud - 1
+ * However, typically BAUD_BASE is not divisible by baud, so
+ * we want to select the divisor that gives us the minimum
+ * error.  Therefore, we want:
+ *  int(BAUD_BASE / baud - 0.5) ->
+ *  int(BAUD_BASE / baud - (baud >> 1) / baud) ->
+ *  int((BAUD_BASE - (baud >> 1)) / baud)
+ */
+
+static void
+serial21285_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	if (tx_enabled(port)) {
+		disable_irq(IRQ_CONTX);
+		tx_enabled(port) = 0;
+	}
+}
+
+static void
+serial21285_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	if (!tx_enabled(port)) {
+		enable_irq(IRQ_CONTX);
+		tx_enabled(port) = 1;
+	}
+}
+
+static void serial21285_stop_rx(struct uart_port *port)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (rx_enabled(port)) {
+		disable_irq(IRQ_CONRX);
+		rx_enabled(port) = 0;
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void serial21285_enable_ms(struct uart_port *port)
+{
+}
+
+static void serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = dev_id;
+	struct tty_struct *tty = port->info->tty;
+	unsigned int status, ch, rxs, max_count = 256;
+
+	status = *CSR_UARTFLG;
+	while (!(status & 0x10) && max_count--) {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				printk(KERN_WARNING "TTY_DONT_FLIP set\n");
+				return;
+			}
+		}
+
+		ch = *CSR_UARTDR;
+
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		port->icount.rx++;
+
+		rxs = *CSR_RXSTAT | RXSTAT_DUMMY_READ;
+		if (rxs & RXSTAT_ANYERR) {
+			if (rxs & RXSTAT_PARITY)
+				port->icount.parity++;
+			else if (rxs & RXSTAT_FRAME)
+				port->icount.frame++;
+			if (rxs & RXSTAT_OVERRUN)
+				port->icount.overrun++;
+
+			rxs &= port->read_status_mask;
+
+			if (rxs & RXSTAT_PARITY)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (rxs & RXSTAT_FRAME)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+
+		if ((rxs & port->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((rxs & RXSTAT_OVERRUN) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character.
+			 */
+			*tty->flip.char_buf_ptr++ = 0;
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			tty->flip.count++;
+		}
+		status = *CSR_UARTFLG;
+	}
+	tty_flip_buffer_push(tty);
+}
+
+static void serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = dev_id;
+	struct circ_buf *xmit = &port->info->xmit;
+	int count = 256;
+
+	if (port->x_char) {
+		*CSR_UARTDR = port->x_char;
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		serial21285_stop_tx(port, 0);
+		return;
+	}
+
+	do {
+		*CSR_UARTDR = xmit->buf[xmit->tail];
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0 && !(*CSR_UARTFLG & 0x20));
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_event(port, EVT_WRITE_WAKEUP);
+
+	if (uart_circ_empty(xmit))
+		serial21285_stop_tx(port, 0);
+}
+
+static unsigned int serial21285_tx_empty(struct uart_port *port)
+{
+	return (*CSR_UARTFLG & 8) ? 0 : TIOCSER_TEMT;
+}
+
+/* no modem control lines */
+static unsigned int serial21285_get_mctrl(struct uart_port *port)
+{
+	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+}
+
+static void serial21285_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+}
+
+static void serial21285_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+	unsigned int h_lcr;
+
+	spin_lock_irqsave(&port->lock, flags);
+	h_lcr = *CSR_H_UBRLCR;
+	if (break_state)
+		h_lcr |= H_UBRLCR_BREAK;
+	else
+		h_lcr &= ~H_UBRLCR_BREAK;
+	*CSR_H_UBRLCR = h_lcr;
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int serial21285_startup(struct uart_port *port)
+{
+	int ret;
+
+	tx_enabled(port) = 1;
+	rx_enabled(port) = 1;
+
+	ret = request_irq(IRQ_CONRX, serial21285_rx_chars, 0,
+			  serial21285_name, port);
+	if (ret == 0) {
+		ret = request_irq(IRQ_CONTX, serial21285_tx_chars, 0,
+				  serial21285_name, port);
+		if (ret)
+			free_irq(IRQ_CONRX, port);
+	}
+
+	return ret;
+}
+
+static void serial21285_shutdown(struct uart_port *port)
+{
+	free_irq(IRQ_CONTX, port);
+	free_irq(IRQ_CONRX, port);
+}
+
+static void
+serial21285_change_speed(struct uart_port *port, unsigned int cflag,
+			 unsigned int iflag, unsigned int quot)
+{
+	unsigned int h_lcr;
+
+	switch (cflag & CSIZE) {
+	case CS5:
+		h_lcr = 0x00;
+		break;
+	case CS6:
+		h_lcr = 0x20;
+		break;
+	case CS7:
+		h_lcr = 0x40;
+		break;
+	default: /* CS8 */
+		h_lcr = 0x60;
+		break;
+	}
+
+	if (cflag & CSTOPB)
+		h_lcr |= H_UBRLCR_STOPB;
+	if (cflag & PARENB) {
+		h_lcr |= H_UBRLCR_PARENB;
+		if (!(cflag & PARODD))
+			h_lcr |= H_UBRLCR_PAREVN;
+	}
+
+	if (port->fifosize)
+		h_lcr |= H_UBRLCR_FIFO;
+
+	port->read_status_mask = RXSTAT_OVERRUN;
+	if (iflag & INPCK)
+		port->read_status_mask |= RXSTAT_FRAME | RXSTAT_PARITY;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= RXSTAT_FRAME | RXSTAT_PARITY;
+	if (iflag & IGNBRK && iflag & IGNPAR)
+		port->ignore_status_mask |= RXSTAT_OVERRUN;
+
+	/*
+	 * Ignore all characters if CREAD is not set.
+	 */
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= RXSTAT_DUMMY_READ;
+
+	quot -= 1;
+
+	*CSR_UARTCON = 0;
+	*CSR_L_UBRLCR = quot & 0xff;
+	*CSR_M_UBRLCR = (quot >> 8) & 0x0f;
+	*CSR_H_UBRLCR = h_lcr;
+	*CSR_UARTCON = 1;
+}
+
+static const char *serial21285_type(struct uart_port *port)
+{
+	return port->type == PORT_21285 ? "DC21285" : NULL;
+}
+
+static void serial21285_release_port(struct uart_port *port)
+{
+	release_mem_region(port->mapbase, 32);
+}
+
+static int serial21285_request_port(struct uart_port *port)
+{
+	return request_mem_region(port->mapbase, 32, serial21285_name)
+			 != NULL ? 0 : -EBUSY;
+}
+
+static void serial21285_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE && serial21285_request_port(port) == 0)
+		port->type = PORT_21285;
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int serial21285_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_21285)
+		ret = -EINVAL;
+	if (ser->irq != NO_IRQ)
+		ret = -EINVAL;
+	if (ser->baud_base != port->uartclk / 16)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops serial21285_ops = {
+	tx_empty:	serial21285_tx_empty,
+	get_mctrl:	serial21285_get_mctrl,
+	set_mctrl:	serial21285_set_mctrl,
+	stop_tx:	serial21285_stop_tx,
+	start_tx:	serial21285_start_tx,
+	stop_rx:	serial21285_stop_rx,
+	enable_ms:	serial21285_enable_ms,
+	break_ctl:	serial21285_break_ctl,
+	startup:	serial21285_startup,
+	shutdown:	serial21285_shutdown,
+	change_speed:	serial21285_change_speed,
+	type:		serial21285_type,
+	release_port:	serial21285_release_port,
+	request_port:	serial21285_request_port,
+	config_port:	serial21285_config_port,
+	verify_port:	serial21285_verify_port,
+};
+
+static struct uart_port serial21285_port = {
+	membase:	0,
+	mapbase:	0x42000160,
+	iotype:		SERIAL_IO_MEM,
+	irq:		NO_IRQ,
+	uartclk:	0,
+	fifosize:	16,
+	ops:		&serial21285_ops,
+	flags:		ASYNC_BOOT_AUTOCONF,
+};
+
+static void serial21285_setup_ports(void)
+{
+	serial21285_port.uartclk = mem_fclk_21285 / 4;
+}
+
+#ifdef CONFIG_SERIAL_21285_CONSOLE
+
+static void
+serial21285_console_write(struct console *co, const char *s,
+			  unsigned int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		while (*CSR_UARTFLG & 0x20)
+			barrier();
+		*CSR_UARTDR = s[i];
+		if (s[i] == '\n') {
+			while (*CSR_UARTFLG & 0x20)
+				barrier();
+			*CSR_UARTDR = '\r';
+		}
+	}
+}
+
+static kdev_t serial21285_console_device(struct console *c)
+{
+	return mk_kdev(SERIAL_21285_MAJOR, SERIAL_21285_MINOR);
+}
+
+static void __init
+serial21285_get_options(struct uart_port *port, int *baud,
+			int *parity, int *bits)
+{
+	if (*CSR_UARTCON == 1) {
+		unsigned int tmp;
+
+		tmp = *CSR_H_UBRLCR;
+		switch (tmp & 0x60) {
+		case 0x00:
+			*bits = 5;
+			break;
+		case 0x20:
+			*bits = 6;
+			break;
+		case 0x40:
+			*bits = 7;
+			break;
+		default:
+		case 0x60:
+			*bits = 8;
+			break;
+		}
+
+		if (tmp & H_UBRLCR_PARENB) {
+			*parity = 'o';
+			if (tmp & H_UBRLCR_PAREVN)
+				*parity = 'e';
+		}
+
+		tmp = *CSR_L_UBRLCR | (*CSR_M_UBRLCR << 8);
+
+		*baud = port->uartclk / (16 * (tmp + 1));
+	}
+}
+
+static int __init serial21285_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port = &serial21285_port;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	if (machine_is_personal_server())
+		baud = 57600;
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		serial21285_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+#ifdef CONFIG_SERIAL_21285_OLD
+static struct console serial21285_old_cons =
+{
+	name:		SERIAL_21285_OLD_NAME,
+	write:		serial21285_console_write,
+	device:		serial21285_console_device,
+	setup:		serial21285_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+#endif
+
+static struct console serial21285_console =
+{
+	name:		SERIAL_21285_NAME,
+	write:		serial21285_console_write,
+	device:		serial21285_console_device,
+	setup:		serial21285_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init rs285_console_init(void)
+{
+	serial21285_setup_ports();
+	register_console(&serial21285_console);
+}
+
+#define SERIAL_21285_CONSOLE	&serial21285_console
+#else
+#define SERIAL_21285_CONSOLE	NULL
+#endif
+
+static struct uart_driver serial21285_reg = {
+	owner:			THIS_MODULE,
+	driver_name:		"ttyFB",
+#ifdef CONFIG_DEVFS_FS
+	dev_name:		"ttyFB%d",
+#else
+	dev_name:		"ttyFB",
+#endif
+	major:			SERIAL_21285_MAJOR,
+	minor:			SERIAL_21285_MINOR,
+	nr:			1,
+	cons:			SERIAL_21285_CONSOLE,
+};
+
+static int __init serial21285_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "Serial: 21285 driver $Revision: 1.34 $\n");
+
+	serial21285_setup_ports();
+
+	ret = uart_register_driver(&serial21285_reg);
+	if (ret == 0)
+		uart_add_one_port(&serial21285_reg, &serial21285_port);
+
+	return ret;
+}
+
+static void __exit serial21285_exit(void)
+{
+	uart_remove_one_port(&serial21285_reg, &serial21285_port);
+	uart_unregister_driver(&serial21285_reg);
+}
+
+module_init(serial21285_init);
+module_exit(serial21285_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Intel Footbridge (21285) serial driver $Revision: 1.34 $");
diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/8250.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,2001 @@
+/*
+ *  linux/drivers/char/8250.c
+ *
+ *  Driver for 8250/16550-type serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King.
+ *
+ * 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.
+ *
+ *  $Id: 8250.c,v 1.84 2002/07/22 15:27:32 rmk Exp $
+ *
+ * A note about mapbase / membase
+ *
+ *  mapbase is the physical address of the IO port.  Currently, we don't
+ *  support this very well, and it may well be dropped from this driver
+ *  in future.  As such, mapbase should be NULL.
+ *
+ *  membase is an 'ioremapped' cookie.  This is compatible with the old
+ *  serial.c driver, and is currently the preferred form.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/compiler.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/slab.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/serial_reg.h>
+#include <linux/serialP.h>
+#include <linux/delay.h>
+#include <linux/kmod.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+#include "8250.h"
+
+/*
+ * Configuration:
+ *   share_irqs - whether we pass SA_SHIRQ to request_irq().  This option
+ *                is unsafe when used on edge-triggered interrupts.
+ */
+unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
+
+/*
+ * Debugging.
+ */
+#if 0
+#define DEBUG_AUTOCONF(fmt...)	printk(fmt)
+#else
+#define DEBUG_AUTOCONF(fmt...)	do { } while (0)
+#endif
+
+#if 0
+#define DEBUG_INTR(fmt...)	printk(fmt)
+#else
+#define DEBUG_INTR(fmt...)	do { } while (0)
+#endif
+
+#define PASS_LIMIT	256
+
+/*
+ * We default to IRQ0 for the "no irq" hack.   Some
+ * machine types want others as well - they're free
+ * to redefine this in their header file.
+ */
+#define is_real_interrupt(irq)	((irq) != 0)
+
+/*
+ * This converts from our new CONFIG_ symbols to the symbols
+ * that asm/serial.h expects.  You _NEED_ to comment out the
+ * linux/config.h include contained inside asm/serial.h for
+ * this to work.
+ */
+#undef CONFIG_SERIAL_MANY_PORTS
+#undef CONFIG_SERIAL_DETECT_IRQ
+#undef CONFIG_SERIAL_MULTIPORT
+#undef CONFIG_HUB6
+
+#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
+#define CONFIG_SERIAL_DETECT_IRQ 1
+#endif
+#ifdef CONFIG_SERIAL_8250_MULTIPORT
+#define CONFIG_SERIAL_MULTIPORT 1
+#endif
+
+/*
+ * HUB6 is always on.  This will be removed once the header
+ * files have been cleaned.
+ */
+#define CONFIG_HUB6 1
+#define CONFIG_SERIAL_MANY_PORTS 1
+
+#include <asm/serial.h>
+
+static struct old_serial_port old_serial_port[] = {
+	SERIAL_PORT_DFNS /* defined in asm/serial.h */
+};
+
+#define UART_NR	ARRAY_SIZE(old_serial_port)
+
+#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
+
+#define PORT_RSA_MAX 4
+static int probe_rsa[PORT_RSA_MAX];
+static int force_rsa[PORT_RSA_MAX];
+#endif /* CONFIG_SERIAL_8250_RSA  */
+
+struct uart_8250_port {
+	struct uart_port	port;
+	struct timer_list	timer;		/* "no irq" timer */
+	struct list_head	list;		/* ports on this IRQ */
+	unsigned char		acr;
+	unsigned char		ier;
+	unsigned char		rev;
+	unsigned char		lcr;
+	unsigned int		lsr_break_flag;
+
+	/*
+	 * We provide a per-port pm hook.
+	 */
+	void			(*pm)(struct uart_port *port,
+				      unsigned int state, unsigned int old);
+};
+
+struct irq_info {
+	spinlock_t		lock;
+	struct list_head	*head;
+};
+
+static struct irq_info irq_lists[NR_IRQS];
+
+/*
+ * Here we define the default xmit fifo size used for each type of UART.
+ */
+static const struct serial_uart_config uart_config[PORT_MAX_8250+1] = {
+	{ "unknown",	1,	0 },
+	{ "8250",	1,	0 },
+	{ "16450",	1,	0 },
+	{ "16550",	1,	0 },
+	{ "16550A",	16,	UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "Cirrus",	1, 	0 },
+	{ "ST16650",	1,	UART_CLEAR_FIFO | UART_STARTECH },
+	{ "ST16650V2",	32,	UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
+	{ "TI16750",	64,	UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "Startech",	1,	0 },
+	{ "16C950/954",	128,	UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "ST16654",	64,	UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
+	{ "XR16850",	128,	UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
+	{ "RSA",	2048,	UART_CLEAR_FIFO | UART_USE_FIFO }
+};
+
+static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
+{
+	offset <<= up->port.regshift;
+
+	switch (up->port.iotype) {
+	case SERIAL_IO_HUB6:
+		outb(up->port.hub6 - 1 + offset, up->port.iobase);
+		return inb(up->port.iobase + 1);
+
+	case SERIAL_IO_MEM:
+		return readb(up->port.membase + offset);
+
+	default:
+		return inb(up->port.iobase + offset);
+	}
+}
+
+static _INLINE_ void
+serial_out(struct uart_8250_port *up, int offset, int value)
+{
+	offset <<= up->port.regshift;
+
+	switch (up->port.iotype) {
+	case SERIAL_IO_HUB6:
+		outb(up->port.hub6 - 1 + offset, up->port.iobase);
+		outb(value, up->port.iobase + 1);
+		break;
+
+	case SERIAL_IO_MEM:
+		writeb(value, up->port.membase + offset);
+		break;
+
+	default:
+		outb(value, up->port.iobase + offset);
+	}
+}
+
+/*
+ * We used to support using pause I/O for certain machines.  We
+ * haven't supported this for a while, but just in case it's badly
+ * needed for certain old 386 machines, I've left these #define's
+ * in....
+ */
+#define serial_inp(up, offset)		serial_in(up, offset)
+#define serial_outp(up, offset, value)	serial_out(up, offset, value)
+
+
+/*
+ * For the 16C950
+ */
+static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
+{
+	serial_out(up, UART_SCR, offset);
+	serial_out(up, UART_ICR, value);
+}
+
+static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
+{
+	unsigned int value;
+
+	serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
+	serial_out(up, UART_SCR, offset);
+	value = serial_in(up, UART_ICR);
+	serial_icr_write(up, UART_ACR, up->acr);
+
+	return value;
+}
+
+#ifdef CONFIG_SERIAL_8250_RSA
+/*
+ * Attempts to turn on the RSA FIFO.  Returns zero on failure.
+ * We set the port uart clock rate if we succeed.
+ */
+static int __enable_rsa(struct uart_8250_port *up)
+{
+	unsigned char mode;
+	int result;
+
+	mode = serial_inp(up, UART_RSA_MSR);
+	result = mode & UART_RSA_MSR_FIFO;
+
+	if (!result) {
+		serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
+		mode = serial_inp(up, UART_RSA_MSR);
+		result = mode & UART_RSA_MSR_FIFO;
+	}
+
+	if (result)
+		up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
+
+	return result;
+}
+
+static void enable_rsa(struct uart_8250_port *up)
+{
+	if (up->port.type == PORT_RSA) {
+		if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
+			spin_lock_irq(&up->port.lock);
+			__enable_rsa(up);
+			spin_unlock_irq(&up->port.lock);
+		}
+		if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
+			serial_outp(up, UART_RSA_FRR, 0);
+	}
+}
+
+/*
+ * Attempts to turn off the RSA FIFO.  Returns zero on failure.
+ * It is unknown why interrupts were disabled in here.  However,
+ * the caller is expected to preserve this behaviour by grabbing
+ * the spinlock before calling this function.
+ */
+static void disable_rsa(struct uart_8250_port *up)
+{
+	unsigned char mode;
+	int result;
+
+	if (up->port.type == PORT_RSA &&
+	    up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
+		spin_lock_irq(&up->port.lock);
+
+		mode = serial_inp(up, UART_RSA_MSR);
+		result = !(mode & UART_RSA_MSR_FIFO);
+
+		if (!result) {
+			serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
+			mode = serial_inp(up, UART_RSA_MSR);
+			result = !(mode & UART_RSA_MSR_FIFO);
+		}
+
+		if (result)
+			up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
+		spin_unlock_irq(&up->port.lock);
+	}
+}
+#endif /* CONFIG_SERIAL_8250_RSA */
+
+/*
+ * This is a quickie test to see how big the FIFO is.
+ * It doesn't work at all the time, more's the pity.
+ */
+static int size_fifo(struct uart_8250_port *up)
+{
+	unsigned char old_fcr, old_mcr, old_dll, old_dlm;
+	int count;
+
+	old_fcr = serial_inp(up, UART_FCR);
+	old_mcr = serial_inp(up, UART_MCR);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+	serial_outp(up, UART_MCR, UART_MCR_LOOP);
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	old_dll = serial_inp(up, UART_DLL);
+	old_dlm = serial_inp(up, UART_DLM);
+	serial_outp(up, UART_DLL, 0x01);
+	serial_outp(up, UART_DLM, 0x00);
+	serial_outp(up, UART_LCR, 0x03);
+	for (count = 0; count < 256; count++)
+		serial_outp(up, UART_TX, count);
+	mdelay(20);/* FIXME - schedule_timeout */
+	for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) &&
+	     (count < 256); count++)
+		serial_inp(up, UART_RX);
+	serial_outp(up, UART_FCR, old_fcr);
+	serial_outp(up, UART_MCR, old_mcr);
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	serial_outp(up, UART_DLL, old_dll);
+	serial_outp(up, UART_DLM, old_dlm);
+
+	return count;
+}
+
+/*
+ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
+ * When this function is called we know it is at least a StarTech
+ * 16650 V2, but it might be one of several StarTech UARTs, or one of
+ * its clones.  (We treat the broken original StarTech 16650 V1 as a
+ * 16550, and why not?  Startech doesn't seem to even acknowledge its
+ * existence.)
+ * 
+ * What evil have men's minds wrought...
+ */
+static void
+autoconfig_startech_uarts(struct uart_8250_port *up)
+{
+	unsigned char scratch, scratch2, scratch3, scratch4;
+
+	/*
+	 * First we check to see if it's an Oxford Semiconductor UART.
+	 *
+	 * If we have to do this here because some non-National
+	 * Semiconductor clone chips lock up if you try writing to the
+	 * LSR register (which serial_icr_read does)
+	 */
+	if (up->port.type == PORT_16550A) {
+		/*
+		 * EFR [4] must be set else this test fails
+		 *
+		 * This shouldn't be necessary, but Mike Hudson
+		 * (Exoray@isys.ca) claims that it's needed for 952
+		 * dual UART's (which are not recommended for new designs).
+		 */
+		up->acr = 0;
+		serial_out(up, UART_LCR, 0xBF);
+		serial_out(up, UART_EFR, 0x10);
+		serial_out(up, UART_LCR, 0x00);
+		/* Check for Oxford Semiconductor 16C950 */
+		scratch = serial_icr_read(up, UART_ID1);
+		scratch2 = serial_icr_read(up, UART_ID2);
+		scratch3 = serial_icr_read(up, UART_ID3);
+		
+		if (scratch == 0x16 && scratch2 == 0xC9 &&
+		    (scratch3 == 0x50 || scratch3 == 0x52 ||
+		     scratch3 == 0x54)) {
+			up->port.type = PORT_16C950;
+			up->rev = serial_icr_read(up, UART_REV) |
+						  (scratch3 << 8);
+			return;
+		}
+	}
+	
+	/*
+	 * We check for a XR16C850 by setting DLL and DLM to 0, and then
+	 * reading back DLL and DLM.  The chip type depends on the DLM
+	 * value read back:
+	 *  0x10 - XR16C850 and the DLL contains the chip revision.
+	 *  0x12 - XR16C2850.
+	 *  0x14 - XR16C854.
+	 */
+
+	/* Save the DLL and DLM */
+
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	scratch3 = serial_inp(up, UART_DLL);
+	scratch4 = serial_inp(up, UART_DLM);
+
+	serial_outp(up, UART_DLL, 0);
+	serial_outp(up, UART_DLM, 0);
+	scratch2 = serial_inp(up, UART_DLL);
+	scratch = serial_inp(up, UART_DLM);
+	serial_outp(up, UART_LCR, 0);
+
+	if (scratch == 0x10 || scratch == 0x12 || scratch == 0x14) {
+		if (scratch == 0x10)
+			up->rev = scratch2;
+		up->port.type = PORT_16850;
+		return;
+	}
+
+	/* Restore the DLL and DLM */
+
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	serial_outp(up, UART_DLL, scratch3);
+	serial_outp(up, UART_DLM, scratch4);
+	serial_outp(up, UART_LCR, 0);
+
+	/*
+	 * We distinguish between the '654 and the '650 by counting
+	 * how many bytes are in the FIFO.  I'm using this for now,
+	 * since that's the technique that was sent to me in the
+	 * serial driver update, but I'm not convinced this works.
+	 * I've had problems doing this in the past.  -TYT
+	 */
+	if (size_fifo(up) == 64)
+		up->port.type = PORT_16654;
+	else
+		up->port.type = PORT_16650V2;
+}
+
+/*
+ * This routine is called by rs_init() to initialize a specific serial
+ * port.  It determines what type of UART chip this serial port is
+ * using: 8250, 16450, 16550, 16550A.  The important question is
+ * whether or not this UART is a 16550A or not, since this will
+ * determine whether or not we can use its FIFO features or not.
+ */
+static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
+{
+	unsigned char status1, status2, scratch, scratch2, scratch3;
+	unsigned char save_lcr, save_mcr;
+	unsigned long flags;
+
+	DEBUG_AUTOCONF("Testing ttyS%d (0x%04x, 0x%08lx)...\n",
+			up->port.line, up->port.iobase, up->port.membase);
+
+	if (!up->port.iobase && !up->port.membase)
+		return;
+
+	/*
+	 * We really do need global IRQs disabled here - we're going to
+	 * be frobbing the chips IRQ enable register to see if it exists.
+	 */
+	spin_lock_irqsave(&up->port.lock, flags);
+//	save_flags(flags); cli();
+
+	if (!(up->port.flags & ASYNC_BUGGY_UART)) {
+		/*
+		 * Do a simple existence test first; if we fail this,
+		 * there's no point trying anything else.
+		 * 
+		 * 0x80 is used as a nonsense port to prevent against
+		 * false positives due to ISA bus float.  The
+		 * assumption is that 0x80 is a non-existent port;
+		 * which should be safe since include/asm/io.h also
+		 * makes this assumption.
+		 */
+		scratch = serial_inp(up, UART_IER);
+		serial_outp(up, UART_IER, 0);
+#ifdef __i386__
+		outb(0xff, 0x080);
+#endif
+		scratch2 = serial_inp(up, UART_IER);
+		serial_outp(up, UART_IER, 0x0F);
+#ifdef __i386__
+		outb(0, 0x080);
+#endif
+		scratch3 = serial_inp(up, UART_IER);
+		serial_outp(up, UART_IER, scratch);
+		if (scratch2 != 0 || scratch3 != 0x0F) {
+			/*
+			 * We failed; there's nothing here
+			 */
+			DEBUG_AUTOCONF("serial: ttyS%d: simple autoconfig "
+				       "failed (%02x, %02x)\n",
+				       up->port.line, scratch2, scratch3);
+			goto out;
+		}
+	}
+
+	save_mcr = serial_in(up, UART_MCR);
+	save_lcr = serial_in(up, UART_LCR);
+
+	/* 
+	 * Check to see if a UART is really there.  Certain broken
+	 * internal modems based on the Rockwell chipset fail this
+	 * test, because they apparently don't implement the loopback
+	 * test mode.  So this test is skipped on the COM 1 through
+	 * COM 4 ports.  This *should* be safe, since no board
+	 * manufacturer would be stupid enough to design a board
+	 * that conflicts with COM 1-4 --- we hope!
+	 */
+	if (!(up->port.flags & ASYNC_SKIP_TEST)) {
+		serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
+		status1 = serial_inp(up, UART_MSR) & 0xF0;
+		serial_outp(up, UART_MCR, save_mcr);
+		if (status1 != 0x90) {
+			DEBUG_AUTOCONF("serial: ttyS%d: no UART loopback "
+				       "failed\n", up->port.line);
+			goto out;
+		}
+	}
+	serial_outp(up, UART_LCR, 0xBF); /* set up for StarTech test */
+	serial_outp(up, UART_EFR, 0);	/* EFR is the same as FCR */
+	serial_outp(up, UART_LCR, 0);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+	scratch = serial_in(up, UART_IIR) >> 6;
+	switch (scratch) {
+		case 0:
+			up->port.type = PORT_16450;
+			break;
+		case 1:
+			up->port.type = PORT_UNKNOWN;
+			break;
+		case 2:
+			up->port.type = PORT_16550;
+			break;
+		case 3:
+			up->port.type = PORT_16550A;
+			break;
+	}
+	if (up->port.type == PORT_16550A) {
+		/* Check for Startech UART's */
+		serial_outp(up, UART_LCR, UART_LCR_DLAB);
+		if (serial_in(up, UART_EFR) == 0) {
+			up->port.type = PORT_16650;
+		} else {
+			serial_outp(up, UART_LCR, 0xBF);
+			if (serial_in(up, UART_EFR) == 0)
+				autoconfig_startech_uarts(up);
+		}
+	}
+	if (up->port.type == PORT_16550A) {
+		/* Check for TI 16750 */
+		serial_outp(up, UART_LCR, save_lcr | UART_LCR_DLAB);
+		serial_outp(up, UART_FCR,
+			    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+		scratch = serial_in(up, UART_IIR) >> 5;
+		if (scratch == 7) {
+			/*
+			 * If this is a 16750, and not a cheap UART
+			 * clone, then it should only go into 64 byte
+			 * mode if the UART_FCR7_64BYTE bit was set
+			 * while UART_LCR_DLAB was latched.
+			 */
+ 			serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+			serial_outp(up, UART_LCR, 0);
+			serial_outp(up, UART_FCR,
+				    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+			scratch = serial_in(up, UART_IIR) >> 5;
+			if (scratch == 6)
+				up->port.type = PORT_16750;
+		}
+		serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+	}
+#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
+	/*
+	 * Only probe for RSA ports if we got the region.
+	 */
+	if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) {
+		int i;
+
+		for (i = 0 ; i < PORT_RSA_MAX ; ++i) {
+			if (!probe_rsa[i] && !force_rsa[i])
+				break;
+			if (((probe_rsa[i] != up->port.iobase) ||
+			     check_region(up->port.iobase + UART_RSA_BASE, 16)) &&
+			    (force_rsa[i] != up->port.iobase))
+				continue;
+			if (__enable_rsa(up)) {
+				up->port.type = PORT_RSA;
+				break;
+			}
+		}
+	}
+#endif
+	serial_outp(up, UART_LCR, save_lcr);
+	if (up->port.type == PORT_16450) {
+		scratch = serial_in(up, UART_SCR);
+		serial_outp(up, UART_SCR, 0xa5);
+		status1 = serial_in(up, UART_SCR);
+		serial_outp(up, UART_SCR, 0x5a);
+		status2 = serial_in(up, UART_SCR);
+		serial_outp(up, UART_SCR, scratch);
+
+		if ((status1 != 0xa5) || (status2 != 0x5a))
+			up->port.type = PORT_8250;
+	}
+
+	up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
+
+	if (up->port.type == PORT_UNKNOWN)
+		goto out;
+
+	/*
+	 * Reset the UART.
+	 */
+#ifdef CONFIG_SERIAL_8250_RSA
+	if (up->port.type == PORT_RSA)
+		serial_outp(up, UART_RSA_FRR, 0);
+#endif
+	serial_outp(up, UART_MCR, save_mcr);
+	serial_outp(up, UART_FCR, (UART_FCR_ENABLE_FIFO |
+				     UART_FCR_CLEAR_RCVR |
+				     UART_FCR_CLEAR_XMIT));
+	serial_outp(up, UART_FCR, 0);
+	(void)serial_in(up, UART_RX);
+	serial_outp(up, UART_IER, 0);
+
+ out:	
+	spin_unlock_irqrestore(&up->port.lock, flags);
+//	restore_flags(flags);
+#ifdef CONFIG_SERIAL_8250_RSA
+	if (up->port.iobase && up->port.type == PORT_RSA) {
+		release_region(up->port.iobase, 8);
+		request_region(up->port.iobase + UART_RSA_BASE, 16,
+			       "serial_rsa");
+	}
+#endif
+}
+
+static void autoconfig_irq(struct uart_8250_port *up)
+{
+	unsigned char save_mcr, save_ier;
+	unsigned char save_ICP = 0;
+	unsigned int ICP = 0;
+	unsigned long irqs;
+	int irq;
+
+	if (up->port.flags & ASYNC_FOURPORT) {
+		ICP = (up->port.iobase & 0xfe0) | 0x1f;
+		save_ICP = inb_p(ICP);
+		outb_p(0x80, ICP);
+		(void) inb_p(ICP);
+	}
+
+	/* forget possible initially masked and pending IRQ */
+	probe_irq_off(probe_irq_on());
+	save_mcr = serial_inp(up, UART_MCR);
+	save_ier = serial_inp(up, UART_IER);
+	serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
+	
+	irqs = probe_irq_on();
+	serial_outp(up, UART_MCR, 0);
+	udelay (10);
+	if (up->port.flags & ASYNC_FOURPORT)  {
+		serial_outp(up, UART_MCR,
+			    UART_MCR_DTR | UART_MCR_RTS);
+	} else {
+		serial_outp(up, UART_MCR,
+			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
+	}
+	serial_outp(up, UART_IER, 0x0f);	/* enable all intrs */
+	(void)serial_inp(up, UART_LSR);
+	(void)serial_inp(up, UART_RX);
+	(void)serial_inp(up, UART_IIR);
+	(void)serial_inp(up, UART_MSR);
+	serial_outp(up, UART_TX, 0xFF);
+	udelay (20);
+	irq = probe_irq_off(irqs);
+
+	serial_outp(up, UART_MCR, save_mcr);
+	serial_outp(up, UART_IER, save_ier);
+
+	if (up->port.flags & ASYNC_FOURPORT)
+		outb_p(save_ICP, ICP);
+
+	up->port.irq = (irq > 0) ? irq : 0;
+}
+
+static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+
+	if (up->ier & UART_IER_THRI) {
+		up->ier &= ~UART_IER_THRI;
+		serial_out(up, UART_IER, up->ier);
+	}
+	if (up->port.type == PORT_16C950 && tty_stop) {
+		up->acr |= UART_ACR_TXDIS;
+		serial_icr_write(up, UART_ACR, up->acr);
+	}
+}
+
+static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+
+	if (!(up->ier & UART_IER_THRI)) {
+		up->ier |= UART_IER_THRI;
+		serial_out(up, UART_IER, up->ier);
+	}
+	/*
+	 * We only do this from uart_start
+	 */
+	if (tty_start && up->port.type == PORT_16C950) {
+		up->acr &= ~UART_ACR_TXDIS;
+		serial_icr_write(up, UART_ACR, up->acr);
+	}
+}
+
+static void serial8250_stop_rx(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	up->ier &= ~UART_IER_RLSI;
+	up->port.read_status_mask &= ~UART_LSR_DR;
+	serial_out(up, UART_IER, up->ier);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void serial8250_enable_ms(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	up->ier |= UART_IER_MSI;
+	serial_out(up, UART_IER, up->ier);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static _INLINE_ void
+receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
+{
+	struct tty_struct *tty = up->port.info->tty;
+	unsigned char ch;
+	int max_count = 256;
+
+	do {
+		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				return; // if TTY_DONT_FLIP is set
+		}
+		ch = serial_inp(up, UART_RX);
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		up->port.icount.rx++;
+
+		if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
+				       UART_LSR_FE | UART_LSR_OE))) {
+			/*
+			 * For statistics only
+			 */
+			if (*status & UART_LSR_BI) {
+				*status &= ~(UART_LSR_FE | UART_LSR_PE);
+				up->port.icount.brk++;
+				/*
+				 * We do the SysRQ and SAK checking
+				 * here because otherwise the break
+				 * may get masked by ignore_status_mask
+				 * or read_status_mask.
+				 */
+				if (uart_handle_break(&up->port))
+					goto ignore_char;
+			} else if (*status & UART_LSR_PE)
+				up->port.icount.parity++;
+			else if (*status & UART_LSR_FE)
+				up->port.icount.frame++;
+			if (*status & UART_LSR_OE)
+				up->port.icount.overrun++;
+
+			/*
+			 * Mask off conditions which should be ingored.
+			 */
+			*status &= up->port.read_status_mask;
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+			if (up->port.line == up->port.cons->index) {
+				/* Recover the break flag from console xmit */
+				*status |= up->lsr_break_flag;
+				up->lsr_break_flag = 0;
+			}
+#endif
+			if (*status & UART_LSR_BI) {
+				DEBUG_INTR("handling break....");
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			} else if (*status & UART_LSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (*status & UART_LSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+		if (uart_handle_sysrq_char(&up->port, ch, regs))
+			goto ignore_char;
+		if ((*status & up->port.ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((*status & UART_LSR_OE) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character.
+			 */
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+	ignore_char:
+		*status = serial_inp(up, UART_LSR);
+	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
+	tty_flip_buffer_push(tty);
+}
+
+static _INLINE_ void transmit_chars(struct uart_8250_port *up)
+{
+	struct circ_buf *xmit = &up->port.info->xmit;
+	int count;
+
+	if (up->port.x_char) {
+		serial_outp(up, UART_TX, up->port.x_char);
+		up->port.icount.tx++;
+		up->port.x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
+		serial8250_stop_tx(&up->port, 0);
+		return;
+	}
+
+	count = up->port.fifosize;
+	do {
+		serial_out(up, UART_TX, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		up->port.icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_event(&up->port, EVT_WRITE_WAKEUP);
+
+	DEBUG_INTR("THRE...");
+
+	if (uart_circ_empty(xmit))
+		serial8250_stop_tx(&up->port, 0);
+}
+
+static _INLINE_ void check_modem_status(struct uart_8250_port *up)
+{
+	int status;
+
+	status = serial_in(up, UART_MSR);
+
+	if ((status & UART_MSR_ANY_DELTA) == 0)
+		return;
+
+	if (status & UART_MSR_TERI)
+		up->port.icount.rng++;
+	if (status & UART_MSR_DDSR)
+		up->port.icount.dsr++;
+	if (status & UART_MSR_DDCD)
+		uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
+	if (status & UART_MSR_DCTS)
+		uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
+
+	wake_up_interruptible(&up->port.info->delta_msr_wait);
+}
+
+/*
+ * This handles the interrupt from one port.
+ */
+static inline void
+serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
+{
+	unsigned int status = serial_inp(up, UART_LSR);
+
+	DEBUG_INTR("status = %x...", status);
+
+	if (status & UART_LSR_DR)
+		receive_chars(up, &status, regs);
+	check_modem_status(up);
+	if (status & UART_LSR_THRE)
+		transmit_chars(up);
+}
+
+/*
+ * This is the serial driver's interrupt routine.
+ *
+ * Arjan thinks the old way was overly complex, so it got simplified.
+ * Alan disagrees, saying that need the complexity to handle the weird
+ * nature of ISA shared interrupts.  (This is a special exception.)
+ *
+ * In order to handle ISA shared interrupts properly, we need to check
+ * that all ports have been serviced, and therefore the ISA interrupt
+ * line has been de-asserted.
+ *
+ * This means we need to loop through all ports. checking that they
+ * don't have an interrupt pending.
+ */
+static void serial8250_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct irq_info *i = dev_id;
+	struct list_head *l, *end = NULL;
+	int pass_counter = 0;
+
+	DEBUG_INTR("serial8250_interrupt(%d)...", irq);
+
+	spin_lock(&i->lock);
+
+	l = i->head;
+	do {
+		struct uart_8250_port *up;
+		unsigned int iir;
+
+		up = list_entry(l, struct uart_8250_port, list);
+
+		iir = serial_in(up, UART_IIR);
+		if (!(iir & UART_IIR_NO_INT)) {
+			spin_lock(&up->port.lock);
+			serial8250_handle_port(up, regs);
+			spin_unlock(&up->port.lock);
+
+			end = NULL;
+		} else if (end == NULL)
+			end = l;
+
+		l = l->next;
+
+		if (l == i->head && pass_counter++ > PASS_LIMIT) {
+			/* If we hit this, we're dead. */
+			printk(KERN_ERR "serial8250: too much work for "
+				"irq%d\n", irq);
+			break;
+		}
+	} while (l != end);
+
+	spin_unlock(&i->lock);
+
+	DEBUG_INTR("end.\n");
+}
+
+/*
+ * To support ISA shared interrupts, we need to have one interrupt
+ * handler that ensures that the IRQ line has been deasserted
+ * before returning.  Failing to do this will result in the IRQ
+ * line being stuck active, and, since ISA irqs are edge triggered,
+ * no more IRQs will be seen.
+ */
+static int serial_link_irq_chain(struct uart_8250_port *up)
+{
+	struct irq_info *i = irq_lists + up->port.irq;
+	int ret, irq_flags = share_irqs ? SA_SHIRQ : 0;
+
+	spin_lock_irq(&i->lock);
+
+	if (i->head) {
+		list_add(&up->list, i->head);
+		spin_unlock_irq(&i->lock);
+
+		ret = 0;
+	} else {
+		INIT_LIST_HEAD(&up->list);
+		i->head = &up->list;
+		spin_unlock_irq(&i->lock);
+
+		ret = request_irq(up->port.irq, serial8250_interrupt,
+				  irq_flags, "serial", i);
+	}
+
+	return ret;
+}
+
+static void serial_unlink_irq_chain(struct uart_8250_port *up)
+{
+	struct irq_info *i = irq_lists + up->port.irq;
+
+	BUG_ON(i->head == NULL);
+
+	if (list_empty(i->head))
+		free_irq(up->port.irq, i);
+
+	spin_lock_irq(&i->lock);
+
+	if (!list_empty(i->head)) {
+		if (i->head == &up->list)
+			i->head = i->head->next;
+		list_del(&up->list);
+	} else {
+		BUG_ON(i->head != &up->list);
+		i->head = NULL;
+	}
+
+	spin_unlock_irq(&i->lock);
+}
+
+/*
+ * This function is used to handle ports that do not have an
+ * interrupt.  This doesn't work very well for 16450's, but gives
+ * barely passable results for a 16550A.  (Although at the expense
+ * of much CPU overhead).
+ */
+static void serial8250_timeout(unsigned long data)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)data;
+	unsigned int timeout;
+	unsigned int iir;
+
+	iir = serial_in(up, UART_IIR);
+	if (!(iir & UART_IIR_NO_INT)) {
+		spin_lock(&up->port.lock);
+		serial8250_handle_port(up, NULL);
+		spin_unlock(&up->port.lock);
+	}
+
+	timeout = up->port.timeout;
+	timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
+	mod_timer(&up->timer, jiffies + timeout);
+}
+
+static unsigned int serial8250_tx_empty(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+	unsigned int ret;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	return ret;
+}
+
+static unsigned int serial8250_get_mctrl(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+	unsigned char status;
+	unsigned int ret;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	status = serial_in(up, UART_MSR);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	ret = 0;
+	if (status & UART_MSR_DCD)
+		ret |= TIOCM_CAR;
+	if (status & UART_MSR_RI)
+		ret |= TIOCM_RNG;
+	if (status & UART_MSR_DSR)
+		ret |= TIOCM_DSR;
+	if (status & UART_MSR_CTS)
+		ret |= TIOCM_CTS;
+	return ret;
+}
+
+static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned char mcr = ALPHA_KLUDGE_MCR;
+
+	if (mctrl & TIOCM_RTS)
+		mcr |= UART_MCR_RTS;
+	if (mctrl & TIOCM_DTR)
+		mcr |= UART_MCR_DTR;
+	if (mctrl & TIOCM_OUT1)
+		mcr |= UART_MCR_OUT1;
+	if (mctrl & TIOCM_OUT2)
+		mcr |= UART_MCR_OUT2;
+	if (mctrl & TIOCM_LOOP)
+		mcr |= UART_MCR_LOOP;
+
+	serial_out(up, UART_MCR, mcr);
+}
+
+static void serial8250_break_ctl(struct uart_port *port, int break_state)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (break_state == -1)
+		up->lcr |= UART_LCR_SBC;
+	else
+		up->lcr &= ~UART_LCR_SBC;
+	serial_out(up, UART_LCR, up->lcr);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static int serial8250_startup(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+	int retval;
+
+	if (up->port.type == PORT_16C950) {
+		/* Wake up and initialize UART */
+		up->acr = 0;
+		serial_outp(up, UART_LCR, 0xBF);
+		serial_outp(up, UART_EFR, UART_EFR_ECB);
+		serial_outp(up, UART_IER, 0);
+		serial_outp(up, UART_LCR, 0);
+		serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
+		serial_outp(up, UART_LCR, 0xBF);
+		serial_outp(up, UART_EFR, UART_EFR_ECB);
+		serial_outp(up, UART_LCR, 0);
+	}
+
+#ifdef CONFIG_SERIAL_8250_RSA
+	/*
+	 * If this is an RSA port, see if we can kick it up to the
+	 * higher speed clock.
+	 */
+	enable_rsa(up);
+#endif
+
+	/*
+	 * Clear the FIFO buffers and disable them.
+	 * (they will be reeanbled in change_speed())
+	 */
+	if (uart_config[up->port.type].flags & 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);
+		serial_outp(up, UART_FCR, 0);
+	}
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	(void) serial_inp(up, UART_LSR);
+	(void) serial_inp(up, UART_RX);
+	(void) serial_inp(up, UART_IIR);
+	(void) serial_inp(up, UART_MSR);
+
+	/*
+	 * At this point, there's no way the LSR could still be 0xff;
+	 * if it is, then bail out, because there's likely no UART
+	 * here.
+	 */
+	if (!(up->port.flags & ASYNC_BUGGY_UART) &&
+	    (serial_inp(up, UART_LSR) == 0xff)) {
+		printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
+		return -ENODEV;
+	}
+
+	/*
+	 * If the "interrupt" for this port doesn't correspond with any
+	 * hardware interrupt, we use a timer-based system.  The original
+	 * driver used to do this with IRQ0.
+	 */
+	if (!is_real_interrupt(up->port.irq)) {
+		unsigned int timeout = up->port.timeout;
+
+		timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
+
+		up->timer.data = (unsigned long)up;
+		mod_timer(&up->timer, jiffies + timeout);
+	} else {
+		retval = serial_link_irq_chain(up);
+		if (retval)
+			return retval;
+	}
+
+	/*
+	 * Now, initialize the UART
+	 */
+	serial_outp(up, UART_LCR, UART_LCR_WLEN8);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (up->port.flags & ASYNC_FOURPORT) {
+		if (!is_real_interrupt(up->port.irq))
+			up->port.mctrl |= TIOCM_OUT1;
+	} else
+		/*
+		 * Most PC uarts need OUT2 raised to enable interrupts.
+		 */
+		if (is_real_interrupt(up->port.irq))
+			up->port.mctrl |= TIOCM_OUT2;
+
+	serial8250_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	/*
+	 * Finally, enable interrupts.  Note: Modem status interrupts
+	 * are set via change_speed(), which will be occuring imminently
+	 * anyway, so we don't enable them here.
+	 */
+	up->ier = UART_IER_RLSI | UART_IER_RDI;
+	serial_outp(up, UART_IER, up->ier);
+
+	if (up->port.flags & ASYNC_FOURPORT) {
+		unsigned int icp;
+		/*
+		 * Enable interrupts on the AST Fourport board
+		 */
+		icp = (up->port.iobase & 0xfe0) | 0x01f;
+		outb_p(0x80, icp);
+		(void) inb_p(icp);
+	}
+
+	/*
+	 * And clear the interrupt registers again for luck.
+	 */
+	(void) serial_inp(up, UART_LSR);
+	(void) serial_inp(up, UART_RX);
+	(void) serial_inp(up, UART_IIR);
+	(void) serial_inp(up, UART_MSR);
+
+	return 0;
+}
+
+static void serial8250_shutdown(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+
+	/*
+	 * Disable interrupts from this port
+	 */
+	up->ier = 0;
+	serial_outp(up, UART_IER, 0);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (up->port.flags & ASYNC_FOURPORT) {
+		/* reset interrupts on the AST Fourport board */
+		inb((up->port.iobase & 0xfe0) | 0x1f);
+		up->port.mctrl |= TIOCM_OUT1;
+	} else
+		up->port.mctrl &= ~TIOCM_OUT2;
+
+	serial8250_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	/*
+	 * Disable break condition and FIFOs
+	 */
+	serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+				  UART_FCR_CLEAR_RCVR |
+				  UART_FCR_CLEAR_XMIT);
+	serial_outp(up, UART_FCR, 0);
+
+#ifdef CONFIG_SERIAL_8250_RSA
+	/*
+	 * Reset the RSA board back to 115kbps compat mode.
+	 */
+	disable_rsa(up);
+#endif
+
+	/*
+	 * Read data port to reset things, and then unlink from
+	 * the IRQ chain.
+	 */
+	(void) serial_in(up, UART_RX);
+
+	if (!is_real_interrupt(up->port.irq))
+		del_timer_sync(&up->timer);
+	else
+		serial_unlink_irq_chain(up);
+}
+
+static void
+serial8250_change_speed(struct uart_port *port, unsigned int cflag,
+			unsigned int iflag, unsigned int quot)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned char cval, fcr = 0;
+	unsigned long flags;
+
+	switch (cflag & CSIZE) {
+	case CS5:
+		cval = 0x00;
+		break;
+	case CS6:
+		cval = 0x01;
+		break;
+	case CS7:
+		cval = 0x02;
+		break;
+	default:
+	case CS8:
+		cval = 0x03;
+		break;
+	}
+
+	if (cflag & CSTOPB)
+		cval |= 0x04;
+	if (cflag & PARENB)
+		cval |= UART_LCR_PARITY;
+	if (!(cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+#ifdef CMSPAR
+	if (cflag & CMSPAR)
+		cval |= UART_LCR_SPAR;
+#endif
+
+	/*
+	 * Work around a bug in the Oxford Semiconductor 952 rev B
+	 * chip which causes it to seriously miscalculate baud rates
+	 * when DLL is 0.
+	 */
+	if ((quot & 0xff) == 0 && up->port.type == PORT_16C950 &&
+	    up->rev == 0x5201)
+		quot ++;
+
+	if (uart_config[up->port.type].flags & UART_USE_FIFO) {
+		if ((up->port.uartclk / quot) < (2400 * 16))
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+#ifdef CONFIG_SERIAL_8250_RSA
+		else if (up->port.type == PORT_RSA)
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14;
+#endif
+		else
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
+	}
+	if (up->port.type == PORT_16750)
+		fcr |= UART_FCR7_64BYTE;
+
+	up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+	if (iflag & IGNPAR)
+		up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (iflag & (BRKINT | PARMRK))
+		up->port.read_status_mask |= UART_LSR_BI;
+
+	/*
+	 * Characteres to ignore
+	 */
+	up->port.ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+	if (iflag & IGNBRK) {
+		up->port.ignore_status_mask |= UART_LSR_BI;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			up->port.ignore_status_mask |= UART_LSR_OE;
+	}
+
+	/*
+	 * ignore all characters if CREAD is not set
+	 */
+	if ((cflag & CREAD) == 0)
+		up->port.ignore_status_mask |= UART_LSR_DR;
+
+	/*
+	 * CTS flow control flag and modem status interrupts
+	 */
+	up->ier &= ~UART_IER_MSI;
+	if (UART_ENABLE_MS(&up->port, cflag))
+		up->ier |= UART_IER_MSI;
+
+	/*
+	 * Ok, we're now changing the port state.  Do it with
+	 * interrupts disabled.
+	 */
+	spin_lock_irqsave(&up->port.lock, flags);
+	serial_out(up, UART_IER, up->ier);
+
+	if (uart_config[up->port.type].flags & UART_STARTECH) {
+		serial_outp(up, UART_LCR, 0xBF);
+		serial_outp(up, UART_EFR, cflag & CRTSCTS ? UART_EFR_CTS :0);
+	}
+	serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+	serial_outp(up, UART_DLL, quot & 0xff);		/* LS of divisor */
+	serial_outp(up, UART_DLM, quot >> 8);		/* MS of divisor */
+	if (up->port.type == PORT_16750)
+		serial_outp(up, UART_FCR, fcr);		/* set fcr */
+	serial_outp(up, UART_LCR, cval);		/* reset DLAB */
+	up->lcr = cval;					/* Save LCR */
+	if (up->port.type != PORT_16750) {
+		if (fcr & UART_FCR_ENABLE_FIFO) {
+			/* emulated UARTs (Lucent Venus 167x) need two steps */
+			serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+		}
+		serial_outp(up, UART_FCR, fcr);		/* set fcr */
+	}
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void
+serial8250_pm(struct uart_port *port, unsigned int state,
+	      unsigned int oldstate)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	if (state) {
+		/* sleep */
+		if (uart_config[up->port.type].flags & UART_STARTECH) {
+			/* Arrange to enter sleep mode */
+			serial_outp(up, UART_LCR, 0xBF);
+			serial_outp(up, UART_EFR, UART_EFR_ECB);
+			serial_outp(up, UART_LCR, 0);
+			serial_outp(up, UART_IER, UART_IERX_SLEEP);
+			serial_outp(up, UART_LCR, 0xBF);
+			serial_outp(up, UART_EFR, 0);
+			serial_outp(up, UART_LCR, 0);
+		}
+		if (up->port.type == PORT_16750) {
+			/* Arrange to enter sleep mode */
+			serial_outp(up, UART_IER, UART_IERX_SLEEP);
+		}
+
+		if (up->pm)
+			up->pm(port, state, oldstate);
+	} else {
+		/* wake */
+		if (uart_config[up->port.type].flags & UART_STARTECH) {
+			/* Wake up UART */
+			serial_outp(up, UART_LCR, 0xBF);
+			serial_outp(up, UART_EFR, UART_EFR_ECB);
+			/*
+			 * Turn off LCR == 0xBF so we actually set the IER
+			 * register on the XR16C850
+			 */
+			serial_outp(up, UART_LCR, 0);
+			serial_outp(up, UART_IER, 0);
+			/*
+			 * Now reset LCR so we can turn off the ECB bit
+			 */
+			serial_outp(up, UART_LCR, 0xBF);
+			serial_outp(up, UART_EFR, 0);
+			/*
+			 * For a XR16C850, we need to set the trigger levels
+			 */
+			if (up->port.type == PORT_16850) {
+				unsigned char fctr;
+
+				fctr = serial_inp(up, UART_FCTR) &
+					 ~(UART_FCTR_RX | UART_FCTR_TX);
+				serial_outp(up, UART_FCTR, fctr |
+						UART_FCTR_TRGD |
+						UART_FCTR_RX);
+				serial_outp(up, UART_TRG, UART_TRG_96);
+				serial_outp(up, UART_FCTR, fctr |
+						UART_FCTR_TRGD |
+						UART_FCTR_TX);
+				serial_outp(up, UART_TRG, UART_TRG_96);
+			}
+			serial_outp(up, UART_LCR, 0);
+		}
+
+		if (up->port.type == PORT_16750) {
+			/* Wake up UART */
+			serial_outp(up, UART_IER, 0);
+		}
+
+		if (up->pm)
+			up->pm(port, state, oldstate);
+	}
+}
+
+/*
+ * Resource handling.  This is complicated by the fact that resources
+ * depend on the port type.  Maybe we should be claiming the standard
+ * 8250 ports, and then trying to get other resources as necessary?
+ */
+static int
+serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res)
+{
+	unsigned int size = 8 << up->port.regshift;
+	int ret = 0;
+
+	switch (up->port.iotype) {
+	case SERIAL_IO_MEM:
+		if (up->port.mapbase) {
+			*res = request_mem_region(up->port.mapbase, size, "serial");
+			if (!*res)
+				ret = -EBUSY;
+		}
+		break;
+
+	case SERIAL_IO_HUB6:
+	case SERIAL_IO_PORT:
+		*res = request_region(up->port.iobase, size, "serial");
+		if (!*res)
+			ret = -EBUSY;
+		break;
+	}
+	return ret;
+}
+
+static int
+serial8250_request_rsa_resource(struct uart_8250_port *up, struct resource **res)
+{
+	unsigned int size = 8 << up->port.regshift;
+	unsigned long start;
+	int ret = 0;
+
+	switch (up->port.iotype) {
+	case SERIAL_IO_MEM:
+		if (up->port.mapbase) {
+			start = up->port.mapbase;
+			start += UART_RSA_BASE << up->port.regshift;
+			*res = request_mem_region(start, size, "serial-rsa");
+			if (!*res)
+				ret = -EBUSY;
+		}
+		break;
+
+	case SERIAL_IO_HUB6:
+	case SERIAL_IO_PORT:
+		start = up->port.iobase;
+		start += UART_RSA_BASE << up->port.regshift;
+		*res = request_region(start, size, "serial-rsa");
+		if (!*res)
+			ret = -EBUSY;
+		break;
+	}
+
+	return ret;
+}
+
+static void serial8250_release_port(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long start, offset = 0, size = 0;
+
+	if (up->port.type == PORT_RSA) {
+		offset = UART_RSA_BASE << up->port.regshift;
+		size = 8;
+	}
+
+	size <<= up->port.regshift;
+
+	switch (up->port.iotype) {
+	case SERIAL_IO_MEM:
+		if (up->port.mapbase) {
+			/*
+			 * Unmap the area.
+			 */
+			iounmap(up->port.membase);
+			up->port.membase = NULL;
+
+			start = up->port.mapbase;
+
+			if (size)
+				release_mem_region(start + offset, size);
+			release_mem_region(start, 8 << up->port.regshift);
+		}
+		break;
+
+	case SERIAL_IO_HUB6:
+	case SERIAL_IO_PORT:
+		start = up->port.iobase;
+
+		if (size)
+			release_region(start + offset, size);
+		release_region(start + offset, 8 << up->port.regshift);
+		break;
+
+	default:
+		break;
+	}
+}
+
+static int serial8250_request_port(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	struct resource *res = NULL, *res_rsa = NULL;
+	int ret = -EBUSY;
+
+	if (up->port.type == PORT_RSA) {
+		ret = serial8250_request_rsa_resource(up, &res_rsa);
+		if (ret)
+			return ret;
+	}
+
+	ret = serial8250_request_std_resource(up, &res);
+
+	/*
+	 * If we have a mapbase, then request that as well.
+	 */
+	if (res != NULL && up->port.iotype == SERIAL_IO_MEM &&
+	    up->port.mapbase) {
+		int size = res->end - res->start + 1;
+
+		up->port.membase = ioremap(up->port.mapbase, size);
+		if (!up->port.membase)
+			ret = -ENOMEM;
+	}
+
+	if (ret) {
+		if (res_rsa)
+			release_resource(res_rsa);
+		if (res)
+			release_resource(res);
+	}
+	return ret;
+}
+
+static void serial8250_config_port(struct uart_port *port, int flags)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	struct resource *res_std = NULL, *res_rsa = NULL;
+	int probeflags = PROBE_ANY;
+	int ret;
+
+#ifdef CONFIG_MCA
+	/*
+	 * Don't probe for MCA ports on non-MCA machines.
+	 */
+	if (up->port.flags & ASYNC_BOOT_ONLYMCA && !MCA_bus)
+		return;
+#endif
+
+	/*
+	 * Find the region that we can probe for.  This in turn
+	 * tells us whether we can probe for the type of port.
+	 */
+	ret = serial8250_request_std_resource(up, &res_std);
+	if (ret)
+		return;
+
+	ret = serial8250_request_rsa_resource(up, &res_rsa);
+	if (ret)
+		probeflags &= ~PROBE_RSA;
+
+	if (flags & UART_CONFIG_TYPE)
+		autoconfig(up, probeflags);
+	if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
+		autoconfig_irq(up);
+
+	/*
+	 * If the port wasn't an RSA port, release the resource.
+	 */
+	if (up->port.type != PORT_RSA && res_rsa)
+		release_resource(res_rsa);
+
+	if (up->port.type == PORT_UNKNOWN)
+		release_resource(res_std);
+}
+
+static int
+serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	if (ser->irq >= NR_IRQS || ser->irq < 0 ||
+	    ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
+	    ser->type > PORT_MAX_8250 || ser->type == PORT_CIRRUS ||
+	    ser->type == PORT_STARTECH)
+		return -EINVAL;
+	return 0;
+}
+
+static const char *
+serial8250_type(struct uart_port *port)
+{
+	int type = port->type;
+
+	if (type >= ARRAY_SIZE(uart_config))
+		type = 0;
+	return uart_config[type].name;
+}
+
+static struct uart_ops serial8250_pops = {
+	tx_empty:	serial8250_tx_empty,
+	set_mctrl:	serial8250_set_mctrl,
+	get_mctrl:	serial8250_get_mctrl,
+	stop_tx:	serial8250_stop_tx,
+	start_tx:	serial8250_start_tx,
+	stop_rx:	serial8250_stop_rx,
+	enable_ms:	serial8250_enable_ms,
+	break_ctl:	serial8250_break_ctl,
+	startup:	serial8250_startup,
+	shutdown:	serial8250_shutdown,
+	change_speed:	serial8250_change_speed,
+	pm:		serial8250_pm,
+	type:		serial8250_type,
+	release_port:	serial8250_release_port,
+	request_port:	serial8250_request_port,
+	config_port:	serial8250_config_port,
+	verify_port:	serial8250_verify_port,
+};
+
+static struct uart_8250_port serial8250_ports[UART_NR];
+
+static void __init serial8250_isa_init_ports(void)
+{
+	static int first = 1;
+	int i;
+
+	if (!first)
+		return;
+	first = 0;
+
+	for (i = 0; i < ARRAY_SIZE(old_serial_port); i++) {
+		serial8250_ports[i].port.iobase  = old_serial_port[i].port;
+		serial8250_ports[i].port.irq     = irq_cannonicalize(old_serial_port[i].irq);
+		serial8250_ports[i].port.uartclk = old_serial_port[i].base_baud * 16;
+		serial8250_ports[i].port.flags   = old_serial_port[i].flags;
+		serial8250_ports[i].port.ops     = &serial8250_pops;
+	}
+}
+
+static void __init serial8250_register_ports(struct uart_driver *drv)
+{
+	int i;
+
+	serial8250_isa_init_ports();
+
+	for (i = 0; i < UART_NR; i++) {
+		serial8250_ports[i].port.line = i;
+		serial8250_ports[i].port.ops = &serial8250_pops;
+		init_timer(&serial8250_ports[i].timer);
+		serial8250_ports[i].timer.function = serial8250_timeout;
+		uart_add_one_port(drv, &serial8250_ports[i].port);
+	}
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(struct uart_8250_port *up)
+{
+	unsigned int status, tmout = 10000;
+
+	/* Wait up to 10ms for the character(s) to be sent. */
+	do {
+		status = serial_in(up, UART_LSR);
+
+		if (status & UART_LSR_BI)
+			up->lsr_break_flag = UART_LSR_BI;
+
+		if (--tmout == 0)
+			break;
+		udelay(1);
+	} while ((status & BOTH_EMPTY) != BOTH_EMPTY);
+
+	/* Wait up to 1s for flow control if necessary */
+	if (up->port.flags & ASYNC_CONS_FLOW) {
+		tmout = 1000000;
+		while (--tmout &&
+		       ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+			udelay(1);
+	}
+}
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ */
+static void
+serial8250_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct uart_8250_port *up = &serial8250_ports[co->index];
+	unsigned int ier;
+	int i;
+
+	/*
+	 *	First save the UER then disable the interrupts
+	 */
+	ier = serial_in(up, UART_IER);
+	serial_out(up, UART_IER, 0);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(up);
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		serial_out(up, UART_TX, *s);
+		if (*s == 10) {
+			wait_for_xmitr(up);
+			serial_out(up, UART_TX, 13);
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the IER
+	 */
+	wait_for_xmitr(up);
+	serial_out(up, UART_IER, ier);
+}
+
+static kdev_t serial8250_console_device(struct console *co)
+{
+	return mk_kdev(TTY_MAJOR, 64 + co->index);
+}
+
+static int __init serial8250_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= UART_NR)
+		co->index = 0;
+	port = &serial8250_ports[co->index].port;
+
+	/*
+	 * Temporary fix.
+	 */
+	spin_lock_init(&port->lock);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console serial8250_console = {
+	name:		"ttyS",
+	write:		serial8250_console_write,
+	device:		serial8250_console_device,
+	setup:		serial8250_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init serial8250_console_init(void)
+{
+	serial8250_isa_init_ports();
+	register_console(&serial8250_console);
+}
+
+#define SERIAL8250_CONSOLE	&serial8250_console
+#else
+#define SERIAL8250_CONSOLE	NULL
+#endif
+
+static struct uart_driver serial8250_reg = {
+	owner:			THIS_MODULE,
+	driver_name:		"serial",
+#ifdef CONFIG_DEVFS_FS
+	dev_name:		"tts/%d",
+#else
+	dev_name:		"ttyS",
+#endif
+	major:			TTY_MAJOR,
+	minor:			64,
+	nr:			UART_NR,
+	cons:			SERIAL8250_CONSOLE,
+};
+
+/*
+ * register_serial and unregister_serial allows for 16x50 serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+
+static int __register_serial(struct serial_struct *req, int line)
+{
+	struct uart_port port;
+
+	port.iobase   = req->port;
+	port.membase  = req->iomem_base;
+	port.irq      = req->irq;
+	port.uartclk  = req->baud_base * 16;
+	port.fifosize = req->xmit_fifo_size;
+	port.regshift = req->iomem_reg_shift;
+	port.iotype   = req->io_type;
+	port.flags    = req->flags | ASYNC_BOOT_AUTOCONF;
+	port.line     = line;
+
+	if (HIGH_BITS_OFFSET)
+		port.iobase |= req->port_high << HIGH_BITS_OFFSET;
+
+	/*
+	 * If a clock rate wasn't specified by the low level
+	 * driver, then default to the standard clock rate.
+	 */
+	if (port.uartclk == 0)
+		port.uartclk = BASE_BAUD * 16;
+
+	return uart_register_port(&serial8250_reg, &port);
+}
+
+/**
+ *	register_serial - configure a 16x50 serial port at runtime
+ *	@req: request structure
+ *
+ *	Configure the serial port specified by the request. If the
+ *	port exists and is in use an error is returned. If the port
+ *	is not currently in the table it is added.
+ *
+ *	The port is then probed and if neccessary the IRQ is autodetected
+ *	If this fails an error is returned.
+ *
+ *	On success the port is ready to use and the line number is returned.
+ */
+int register_serial(struct serial_struct *req)
+{
+	return __register_serial(req, -1);
+}
+
+int __init early_serial_setup(struct serial_struct *req)
+{
+	__register_serial(req, req->line);
+	return 0;
+}
+
+/**
+ *	unregister_serial - remove a 16x50 serial port at runtime
+ *	@line: serial line number
+ *
+ *	Remove one serial port.  This may be called from interrupt
+ *	context.
+ */
+void unregister_serial(int line)
+{
+	uart_unregister_port(&serial8250_reg, line);
+}
+
+/*
+ * This is for ISAPNP only.
+ */
+void serial8250_get_irq_map(unsigned int *map)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++) {
+		if (serial8250_ports[i].port.type != PORT_UNKNOWN &&
+		    serial8250_ports[i].port.irq < 16)
+			*map |= 1 << serial8250_ports[i].port.irq;
+	}
+}
+
+static int __init serial8250_init(void)
+{
+	int ret, i;
+
+	printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.84 $ "
+		"IRQ sharing %sabled\n", share_irqs ? "en" : "dis");
+
+	for (i = 0; i < NR_IRQS; i++)
+		spin_lock_init(&irq_lists[i].lock);
+
+	ret = uart_register_driver(&serial8250_reg);
+	if (ret)
+		return ret;
+
+	serial8250_register_ports(&serial8250_reg);
+	return 0;
+}
+
+static void __exit serial8250_exit(void)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++)
+		uart_remove_one_port(&serial8250_reg, &serial8250_ports[i].port);
+
+	uart_unregister_driver(&serial8250_reg);
+}
+
+module_init(serial8250_init);
+module_exit(serial8250_exit);
+
+EXPORT_SYMBOL(register_serial);
+EXPORT_SYMBOL(unregister_serial);
+EXPORT_SYMBOL(serial8250_get_irq_map);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 serial driver $Revision: 1.84 $");
+
+MODULE_PARM(share_irqs, "i");
+MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
+	" (unsafe)");
+
+#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
+MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
+MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
+MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
+MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA");
+#endif
diff -Nru a/drivers/serial/8250.h b/drivers/serial/8250.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/8250.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,60 @@
+/*
+ *  linux/drivers/char/8250.h
+ *
+ *  Driver for 8250/16550-type serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King.
+ *
+ * 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.
+ *
+ *  $Id: 8250.h,v 1.8 2002/07/21 21:32:30 rmk Exp $
+ */
+
+#include <linux/config.h>
+
+struct serial8250_probe {
+	struct module	*owner;
+	int		(*pci_init_one)(struct pci_dev *dev);
+	void		(*pci_remove_one)(struct pci_dev *dev);
+	void		(*pnp_init)(void);
+};
+
+int serial8250_register_probe(struct serial8250_probe *probe);
+void serial8250_unregister_probe(struct serial8250_probe *probe);
+void serial8250_get_irq_map(unsigned int *map);
+
+struct old_serial_port {
+	unsigned int uart;
+	unsigned int base_baud;
+	unsigned int port;
+	unsigned int irq;
+	unsigned int flags;
+};
+
+#undef SERIAL_DEBUG_PCI
+
+#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
+#define SERIAL_INLINE
+#endif
+  
+#ifdef SERIAL_INLINE
+#define _INLINE_ inline
+#else
+#define _INLINE_
+#endif
+
+#define PROBE_RSA	(1 << 0)
+#define PROBE_ANY	(~0)
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
+#define SERIAL8250_SHARE_IRQS 1
+#else
+#define SERIAL8250_SHARE_IRQS 0
+#endif
diff -Nru a/drivers/serial/8250_cs.c b/drivers/serial/8250_cs.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/8250_cs.c	Wed Jul 24 14:03:38 2002
@@ -0,0 +1,719 @@
+/*======================================================================
+
+    A driver for PCMCIA serial devices
+
+    serial_cs.c 1.123 2000/08/24 18:46:38
+
+    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/major.h>
+#include <linux/tqueue.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.123 2000/08/24 18:46:38 (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;
+
+MODULE_PARM(irq_mask, "i");
+MODULE_PARM(irq_list, "1-4i");
+MODULE_PARM(do_sound, "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))
+
+typedef struct serial_info {
+	dev_link_t		link;
+	int			ndev;
+	int			multi;
+	int			slave;
+	int			manfid;
+	dev_node_t		node[4];
+	int			line[4];
+	struct tq_struct	remove;
+} serial_info_t;
+
+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;
+
+/*====================================================================*/
+
+static void
+cs_error(client_handle_t handle, int func, int ret)
+{
+	error_info_t err = { func, ret };
+	CardServices(ReportError, handle, &err);
+}
+
+/*======================================================================
+
+    After a card is removed, do_serial_release() will unregister
+    the serial device(s), and release the PCMCIA configuration.
+    
+======================================================================*/
+
+/*
+ * This always runs in process context.
+ */
+static void do_serial_release(void *arg)
+{
+	struct serial_info *info = arg;
+	int i;
+
+	DEBUG(0, "serial_release(0x%p)\n", &info->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;
+	}
+}
+
+/*
+ * This may be called from IRQ context.
+ */
+static void serial_remove(dev_link_t *link)
+{
+	struct serial_info *info = link->priv;
+
+	link->state &= ~DEV_PRESENT;
+
+	/*
+	 * FIXME: Since the card has probably been removed,
+	 * we should call into the serial layer and hang up
+	 * the ports on the card immediately.
+	 */
+
+	if (link->state & DEV_CONFIG)
+		schedule_task(&info->remove);
+}
+
+/*======================================================================
+
+    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)
+{
+	serial_info_t *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;
+
+	INIT_TQUEUE(&info->remove, do_serial_release, 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;
+	link->conf.Vcc = 50;
+	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)
+{
+	serial_info_t *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_tasks();
+
+	/*
+	 * Ensure that the ports have been released.
+	 */
+	do_serial_release(info);
+
+	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(serial_info_t * 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 = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
+	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 -1;
+	}
+
+	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;
+	serial_info_t *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;
+	serial_info_t *info = link->priv;
+	tuple_t tuple;
+	u_char buf[256];
+	cisparse_t parse;
+	cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+	int i, base2 = 0;
+
+	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;
+	}
+
+	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;
+	serial_info_t *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:
+	do_serial_release(info);
+}
+
+/*======================================================================
+
+    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;
+	serial_info_t *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 int __init init_serial_cs(void)
+{
+	servinfo_t serv;
+	DEBUG(0, "%s\n", version);
+	CardServices(GetCardServicesInfo, &serv);
+	if (serv.Revision != CS_RELEASE_CODE) {
+		printk(KERN_NOTICE "serial_cs: Card Services release "
+		       "does not match!\n");
+		return -1;
+	}
+	register_pccard_driver(&dev_info, &serial_attach, &serial_detach);
+	return 0;
+}
+
+static void __exit exit_serial_cs(void)
+{
+	DEBUG(0, "serial_cs: unloading\n");
+	unregister_pccard_driver(&dev_info);
+	while (dev_list != NULL)
+		serial_detach(dev_list);
+}
+
+module_init(init_serial_cs);
+module_exit(exit_serial_cs);
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/8250_pci.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,1138 @@
+/*
+ *  linux/drivers/char/8250_pci.c
+ *
+ *  Probe module for 8250/16550-type PCI serial ports.
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King, 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 as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ *  $Id: 8250_pci.c,v 1.19 2002/07/21 21:32:30 rmk Exp $
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/serial.h>
+
+/* 2.4.6 compatibility cruft - to be removed with the old serial.c code */
+#define pci_board __pci_board
+#include <linux/serialP.h>
+#undef pci_board
+
+#include <asm/bitops.h>
+#include <asm/byteorder.h>
+#include <asm/serial.h>
+
+#include "8250.h"
+
+
+#ifndef IS_PCI_REGION_IOPORT
+#define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \
+				      IORESOURCE_IO)
+#endif
+#ifndef IS_PCI_REGION_IOMEM
+#define IS_PCI_REGION_IOMEM(dev, r) (pci_resource_flags((dev), (r)) & \
+				      IORESOURCE_MEM)
+#endif
+#ifndef PCI_IRQ_RESOURCE
+#define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq_resource[r].start)
+#endif
+
+#ifndef pci_get_subvendor
+#define pci_get_subvendor(dev) ((dev)->subsystem_vendor)
+#define pci_get_subdevice(dev)  ((dev)->subsystem_device)
+#endif
+
+struct serial_private {
+	unsigned int nr;
+	struct pci_board *board;
+	int line[0];
+};
+
+struct pci_board {
+	int flags;
+	int num_ports;
+	int base_baud;
+	int uart_offset;
+	int reg_shift;
+	int (*init_fn)(struct pci_dev *dev, struct pci_board *board,
+			int enable);
+	int first_uart_offset;
+};
+
+static int
+get_pci_port(struct pci_dev *dev, struct pci_board *board,
+	     struct serial_struct *req, int idx)
+{
+	unsigned long port;
+	int base_idx;
+	int max_port;
+	int offset;
+
+	base_idx = SPCI_FL_GET_BASE(board->flags);
+	if (board->flags & SPCI_FL_BASE_TABLE)
+		base_idx += idx;
+
+	if (board->flags & SPCI_FL_REGION_SZ_CAP) {
+		max_port = pci_resource_len(dev, base_idx) / 8;
+		if (idx >= max_port)
+			return 1;
+	}
+			
+	offset = board->first_uart_offset;
+
+	/*
+	 * Timedia/SUNIX uses a mixture of BARs and offsets
+	 * Ugh, this is ugly as all hell --- TYT
+	 */
+	if (dev->vendor == PCI_VENDOR_ID_TIMEDIA)
+		switch(idx) {
+		case 0:
+			base_idx = 0;
+			break;
+		case 1:
+			base_idx = 0;
+			offset = 8;
+			break;
+		case 2:
+			base_idx = 1; 
+			break;
+		case 3:
+			base_idx = 1;
+			offset = 8;
+			break;
+		case 4: /* BAR 2 */
+		case 5: /* BAR 3 */
+		case 6: /* BAR 4 */
+		case 7: /* BAR 5 */
+			base_idx = idx - 2;
+		}
+
+	/* AFAVLAB uses a different mixture of BARs and offsets */
+	/* Not that ugly ;) -- HW */
+	if (dev->vendor == PCI_VENDOR_ID_AFAVLAB && idx >= 4) {
+		base_idx = 4;
+		offset = (idx - 4) * 8;
+	}
+
+	/* Some Titan cards are also a little weird */
+	if (dev->vendor == PCI_VENDOR_ID_TITAN &&
+	    (dev->device == PCI_DEVICE_ID_TITAN_400L ||
+	     dev->device == PCI_DEVICE_ID_TITAN_800L)) {
+		switch (idx) {
+		case 0: base_idx = 1;
+			break;
+		case 1: base_idx = 2;
+			break;
+		default:
+			base_idx = 4;
+			offset = 8 * (idx - 2);
+		}
+	}
+  
+	port =  pci_resource_start(dev, base_idx) + offset;
+
+	if ((board->flags & SPCI_FL_BASE_TABLE) == 0)
+		port += idx * (board->uart_offset ? board->uart_offset : 8);
+
+	if (IS_PCI_REGION_IOPORT(dev, base_idx)) {
+		req->port = port;
+		if (HIGH_BITS_OFFSET)
+			req->port_high = port >> HIGH_BITS_OFFSET;
+		else
+			req->port_high = 0;
+		return 0;
+	}
+	req->io_type = SERIAL_IO_MEM;
+	req->iomem_base = ioremap(port, board->uart_offset);
+	if (req->iomem_base == NULL)
+		return -ENOMEM;
+	req->iomem_reg_shift = board->reg_shift;
+	req->port = 0;
+	return 0;
+}
+
+static _INLINE_ int
+get_pci_irq(struct pci_dev *dev, struct pci_board *board, int idx)
+{
+	int base_idx;
+
+	if ((board->flags & SPCI_FL_IRQRESOURCE) == 0)
+		return dev->irq;
+
+	base_idx = SPCI_FL_GET_IRQBASE(board->flags);
+	if (board->flags & SPCI_FL_IRQ_TABLE)
+		base_idx += idx;
+	
+	return PCI_IRQ_RESOURCE(dev, base_idx);
+}
+
+/*
+ * Some PCI serial cards using the PLX 9050 PCI interface chip require
+ * that the card interrupt be explicitly enabled or disabled.  This
+ * seems to be mainly needed on card using the PLX which also use I/O
+ * mapped memory.
+ */
+static int __devinit
+pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+	u8 *p, irq_config = 0;
+
+	if (enable) {
+		irq_config = 0x41;
+		if (dev->vendor == PCI_VENDOR_ID_PANACOM)
+			irq_config = 0x43;
+		if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
+		    (dev->device == PCI_DEVICE_ID_PLX_ROMULUS)) {
+			/*
+			 * As the megawolf cards have the int pins active
+			 * high, and have 2 UART chips, both ints must be
+			 * enabled on the 9050. Also, the UARTS are set in
+			 * 16450 mode by default, so we have to enable the
+			 * 16C950 'enhanced' mode so that we can use the
+			 * deep FIFOs
+			 */
+			irq_config = 0x5b;
+		}
+	}
+
+	/*
+	 * enable/disable interrupts
+	 */
+	p = ioremap(pci_resource_start(dev, 0), 0x80);
+	if (p == NULL)
+		return -ENOMEM;
+	writel(irq_config, (unsigned long)p + 0x4c);
+
+	/*
+	 * Read the register back to ensure that it took effect.
+	 */
+	readl((unsigned long)p + 0x4c);
+	iounmap(p);
+
+	return 0;
+}
+
+
+/*
+ * SIIG serial cards have an PCI interface chip which also controls
+ * the UART clocking frequency. Each UART can be clocked independently
+ * (except cards equiped with 4 UARTs) and initial clocking settings
+ * are stored in the EEPROM chip. It can cause problems because this
+ * version of serial driver doesn't support differently clocked UART's
+ * on single PCI card. To prevent this, initialization functions set
+ * high frequency clocking for all UART's on given card. It is safe (I
+ * hope) because it doesn't touch EEPROM settings to prevent conflicts
+ * with other OSes (like M$ DOS).
+ *
+ *  SIIG support added by Andrey Panin <pazke@mail.tp.ru>, 10/1999
+ * 
+ * There is two family of SIIG serial cards with different PCI
+ * interface chip and different configuration methods:
+ *     - 10x cards have control registers in IO and/or memory space;
+ *     - 20x cards have control registers in standard PCI configuration space.
+ */
+
+#define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
+#define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
+
+static int __devinit
+pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+	u16 data, *p;
+
+	if (!enable)
+		return 0;
+
+	switch (dev->device & 0xfff8) {
+		case PCI_DEVICE_ID_SIIG_1S_10x:	/* 1S */
+			data = 0xffdf;
+			break;
+		case PCI_DEVICE_ID_SIIG_2S_10x:	/* 2S, 2S1P */
+			data = 0xf7ff;
+			break;
+		default:			/* 1S1P, 4S */
+			data = 0xfffb;
+			break;
+	}
+
+	p = ioremap(pci_resource_start(dev, 0), 0x80);
+	if (p == NULL)
+		return -ENOMEM;
+
+	writew(readw((unsigned long) p + 0x28) & data, (unsigned long) p + 0x28);
+	iounmap(p);
+	return 0;
+}
+
+#define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
+#define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
+
+static int __devinit
+pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+	u8 data;
+
+	if (!enable)
+		return 0;
+
+	/* Change clock frequency for the first UART. */
+	pci_read_config_byte(dev, 0x6f, &data);
+	pci_write_config_byte(dev, 0x6f, data & 0xef);
+
+	/* If this card has 2 UART, we have to do the same with second UART. */
+	if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) ||
+	    ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) {
+		pci_read_config_byte(dev, 0x73, &data);
+		pci_write_config_byte(dev, 0x73, data & 0xef);
+	}
+	return 0;
+}
+
+/* Added for EKF Intel i960 serial boards */
+static int __devinit
+pci_inteli960ni_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+	unsigned long oldval;
+
+	if (!(pci_get_subdevice(dev) & 0x1000))
+		return -ENODEV;
+
+	if (!enable) /* is there something to deinit? */
+		return 0;
+   
+	/* is firmware started? */
+	pci_read_config_dword(dev, 0x44, (void*) &oldval); 
+	if (oldval == 0x00001000L) { /* RESET value */ 
+		printk(KERN_DEBUG "Local i960 firmware missing");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+/*
+ * Timedia has an explosion of boards, and to avoid the PCI table from
+ * growing *huge*, we use this function to collapse some 70 entries
+ * in the PCI table into one, for sanity's and compactness's sake.
+ */
+static unsigned short timedia_single_port[] = {
+	0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0
+};
+
+static unsigned short timedia_dual_port[] = {
+	0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
+	0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, 
+	0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, 
+	0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
+	0xD079, 0
+};
+
+static unsigned short timedia_quad_port[] = {
+	0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, 
+	0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, 
+	0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
+	0xB157, 0
+};
+
+static unsigned short timedia_eight_port[] = {
+	0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, 
+	0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
+};
+
+static struct timedia_struct {
+	int num;
+	unsigned short *ids;
+} timedia_data[] = {
+	{ 1, timedia_single_port },
+	{ 2, timedia_dual_port },
+	{ 4, timedia_quad_port },
+	{ 8, timedia_eight_port },
+	{ 0, 0 }
+};
+
+static int __devinit
+pci_timedia_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+	int	i, j;
+	unsigned short *ids;
+
+	if (!enable)
+		return 0;
+
+	for (i = 0; timedia_data[i].num; i++) {
+		ids = timedia_data[i].ids;
+		for (j = 0; ids[j]; j++) {
+			if (pci_get_subdevice(dev) == ids[j]) {
+				board->num_ports = timedia_data[i].num;
+				return 0;
+			}
+		}
+	}
+	return 0;
+}
+
+static int __devinit
+pci_xircom_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+	__set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(HZ/10);
+	return 0;
+}
+
+/*
+ * This is the configuration table for all of the PCI serial boards
+ * which we support.  It is directly indexed by the pci_board_num_t enum
+ * value, which is encoded in the pci_device_id PCI probe table's
+ * driver_data member.
+ */
+enum pci_board_num_t {
+	pbn_b0_1_115200,
+	pbn_default = 0,
+
+	pbn_b0_2_115200,
+	pbn_b0_4_115200,
+
+	pbn_b0_1_921600,
+	pbn_b0_2_921600,
+	pbn_b0_4_921600,
+
+	pbn_b0_bt_1_115200,
+	pbn_b0_bt_2_115200,
+	pbn_b0_bt_8_115200,
+	pbn_b0_bt_1_460800,
+	pbn_b0_bt_2_460800,
+
+	pbn_b1_1_115200,
+	pbn_b1_2_115200,
+	pbn_b1_4_115200,
+	pbn_b1_8_115200,
+
+	pbn_b1_2_921600,
+	pbn_b1_4_921600,
+	pbn_b1_8_921600,
+
+	pbn_b1_2_1382400,
+	pbn_b1_4_1382400,
+	pbn_b1_8_1382400,
+
+	pbn_b2_8_115200,
+	pbn_b2_4_460800,
+	pbn_b2_8_460800,
+	pbn_b2_16_460800,
+	pbn_b2_4_921600,
+	pbn_b2_8_921600,
+
+	pbn_b2_bt_1_115200,
+	pbn_b2_bt_2_115200,
+	pbn_b2_bt_4_115200,
+	pbn_b2_bt_2_921600,
+
+	pbn_panacom,
+	pbn_panacom2,
+	pbn_panacom4,
+	pbn_plx_romulus,
+	pbn_oxsemi,
+	pbn_timedia,
+	pbn_intel_i960,
+	pbn_sgi_ioc3,
+	pbn_nec_nile4,
+
+	pbn_dci_pccom4,
+	pbn_dci_pccom8,
+
+	pbn_xircom_combo,
+
+	pbn_siig10x_0,
+	pbn_siig10x_1,
+	pbn_siig10x_2,
+	pbn_siig10x_4,
+	pbn_siig20x_0,
+	pbn_siig20x_2,
+	pbn_siig20x_4,
+	
+	pbn_computone_4,
+	pbn_computone_6,
+	pbn_computone_8,
+};
+
+static struct pci_board pci_boards[] __devinitdata = {
+	/*
+	 * PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
+	 * Offset to get to next UART's registers,
+	 * Register shift to use for memory-mapped I/O,
+	 * Initialization function, first UART offset
+	 */
+
+	/* Generic serial board, pbn_b0_1_115200, pbn_default */
+	{ SPCI_FL_BASE0, 1, 115200 },		/* pbn_b0_1_115200,
+						   pbn_default */
+
+	{ SPCI_FL_BASE0, 2, 115200 },		/* pbn_b0_2_115200 */
+	{ SPCI_FL_BASE0, 4, 115200 },		/* pbn_b0_4_115200 */
+
+	{ SPCI_FL_BASE0, 1, 921600 },		/* pbn_b0_1_921600 */
+	{ SPCI_FL_BASE0, 2, 921600 },		/* pbn_b0_2_921600 */
+	{ SPCI_FL_BASE0, 4, 921600 },		/* pbn_b0_4_921600 */
+
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b0_bt_1_115200 */
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b0_bt_2_115200 */
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 8, 115200 }, /* pbn_b0_bt_8_115200 */
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, /* pbn_b0_bt_1_460800 */
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, /* pbn_b0_bt_2_460800 */
+
+	{ SPCI_FL_BASE1, 1, 115200 },		/* pbn_b1_1_115200 */
+	{ SPCI_FL_BASE1, 2, 115200 },		/* pbn_b1_2_115200 */
+	{ SPCI_FL_BASE1, 4, 115200 },		/* pbn_b1_4_115200 */
+	{ SPCI_FL_BASE1, 8, 115200 },		/* pbn_b1_8_115200 */
+
+	{ SPCI_FL_BASE1, 2, 921600 },		/* pbn_b1_2_921600 */
+	{ SPCI_FL_BASE1, 4, 921600 },		/* pbn_b1_4_921600 */
+	{ SPCI_FL_BASE1, 8, 921600 },		/* pbn_b1_8_921600 */
+
+	{ SPCI_FL_BASE1, 2, 1382400 },		/* pbn_b1_2_1382400 */
+	{ SPCI_FL_BASE1, 4, 1382400 },		/* pbn_b1_4_1382400 */
+	{ SPCI_FL_BASE1, 8, 1382400 },		/* pbn_b1_8_1382400 */
+
+	{ SPCI_FL_BASE2, 8, 115200 },		/* pbn_b2_8_115200 */
+	{ SPCI_FL_BASE2, 4, 460800 },		/* pbn_b2_4_460800 */
+	{ SPCI_FL_BASE2, 8, 460800 },		/* pbn_b2_8_460800 */
+	{ SPCI_FL_BASE2, 16, 460800 },		/* pbn_b2_16_460800 */
+	{ SPCI_FL_BASE2, 4, 921600 },		/* pbn_b2_4_921600 */
+	{ SPCI_FL_BASE2, 8, 921600 },		/* pbn_b2_8_921600 */
+
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b2_bt_1_115200 */
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b2_bt_2_115200 */
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 115200 }, /* pbn_b2_bt_4_115200 */
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600 }, /* pbn_b2_bt_2_921600 */
+
+	{ SPCI_FL_BASE2, 2, 921600, /* IOMEM */		   /* pbn_panacom */
+		0x400, 7, pci_plx9050_fn },
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,   /* pbn_panacom2 */
+		0x400, 7, pci_plx9050_fn },
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600,   /* pbn_panacom4 */
+		0x400, 7, pci_plx9050_fn },
+	{ SPCI_FL_BASE2, 4, 921600,			   /* pbn_plx_romulus */
+		0x20, 2, pci_plx9050_fn, 0x03 },
+		/* This board uses the size of PCI Base region 0 to
+		 * signal now many ports are available */
+	{ SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 }, /* pbn_oxsemi */
+	{ SPCI_FL_BASE_TABLE, 1, 921600,		   /* pbn_timedia */
+		0, 0, pci_timedia_fn },
+	/* EKF addition for i960 Boards form EKF with serial port */
+	{ SPCI_FL_BASE0, 32, 921600, /* max 256 ports */   /* pbn_intel_i960 */
+		8<<2, 2, pci_inteli960ni_fn, 0x10000},
+	{ SPCI_FL_BASE0 | SPCI_FL_IRQRESOURCE,		   /* pbn_sgi_ioc3 */
+		1, 458333, 0, 0, 0, 0x20178 },
+
+	/*
+	 * NEC Vrc-5074 (Nile 4) builtin UART.
+	 */
+	{ SPCI_FL_BASE0, 1, 520833,			   /* pbn_nec_nile4 */
+		64, 3, NULL, 0x300 },
+
+	{ SPCI_FL_BASE3, 4, 115200, 8 },		   /* pbn_dci_pccom4 */
+	{ SPCI_FL_BASE3, 8, 115200, 8 },		   /* pbn_dci_pccom8 */
+
+	{ SPCI_FL_BASE0, 1, 115200,			   /* pbn_xircom_combo */
+		0, 0, pci_xircom_fn },
+
+	{ SPCI_FL_BASE2, 1, 460800,			   /* pbn_siig10x_0 */
+		0, 0, pci_siig10x_fn },
+	{ SPCI_FL_BASE2, 1, 921600,			   /* pbn_siig10x_1 */
+		0, 0, pci_siig10x_fn },
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,   /* pbn_siig10x_2 */
+		0, 0, pci_siig10x_fn },
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600,   /* pbn_siig10x_4 */
+		0, 0, pci_siig10x_fn },
+	{ SPCI_FL_BASE0, 1, 921600,			   /* pbn_siix20x_0 */
+		0, 0, pci_siig20x_fn },
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600,   /* pbn_siix20x_2 */
+		0, 0, pci_siig20x_fn },
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 921600,   /* pbn_siix20x_4 */
+		0, 0, pci_siig20x_fn },
+
+	{ SPCI_FL_BASE0, 4, 921600, /* IOMEM */		   /* pbn_computone_4 */
+		0x40, 2, NULL, 0x200 },
+	{ SPCI_FL_BASE0, 6, 921600, /* IOMEM */		   /* pbn_computone_6 */
+		0x40, 2, NULL, 0x200 },
+	{ SPCI_FL_BASE0, 8, 921600, /* IOMEM */		   /* pbn_computone_8 */
+		0x40, 2, NULL, 0x200 },
+};
+
+/*
+ * Given a complete unknown PCI device, try to use some heuristics to
+ * guess what the configuration might be, based on the pitiful PCI
+ * serial specs.  Returns 0 on success, 1 on failure.
+ */
+static int __devinit
+serial_pci_guess_board(struct pci_dev *dev, struct pci_board *board)
+{
+	int num_iomem = 0, num_port = 0, first_port = -1;
+	int i;
+	
+	/*
+	 * If it is not a communications device or the programming
+	 * interface is greater than 6, give up.
+	 *
+	 * (Should we try to make guesses for multiport serial devices
+	 * later?) 
+	 */
+	if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
+	    ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
+	    (dev->class & 0xff) > 6)
+		return 1;
+
+	for (i = 0; i < 6; i++) {
+		if (IS_PCI_REGION_IOPORT(dev, i)) {
+			num_port++;
+			if (first_port == -1)
+				first_port = i;
+		}
+		if (IS_PCI_REGION_IOMEM(dev, i))
+			num_iomem++;
+	}
+
+	/*
+	 * If there is 1 or 0 iomem regions, and exactly one port, use
+	 * it.
+	 */
+	if (num_iomem <= 1 && num_port == 1) {
+		board->flags = first_port;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * return an error code to refuse.
+ *
+ * serial_struct is 60 bytes.
+ */
+static int __devinit pci_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	struct serial_private *priv;
+	struct pci_board *board, tmp;
+	struct serial_struct serial_req;
+	int base_baud, rc, k;
+
+	if (ent->driver_data >= ARRAY_SIZE(pci_boards)) {
+		printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n",
+			ent->driver_data);
+		return -EINVAL;
+	}
+
+	board = &pci_boards[ent->driver_data];
+
+	rc = pci_enable_device(dev);
+	if (rc)
+		return rc;
+
+	if (ent->driver_data == pbn_default &&
+	    serial_pci_guess_board(dev, board))
+		return -ENODEV;
+	else if (serial_pci_guess_board(dev, &tmp) == 0) {
+		printk(KERN_INFO "Redundant entry in serial pci_table.  "
+		       "Please send the output of\n"
+		       "lspci -vv, this message (%d,%d,%d,%d)\n"
+		       "and the manufacturer and name of "
+		       "serial board or modem board\n"
+		       "to serial-pci-info@lists.sourceforge.net.\n",
+		       dev->vendor, dev->device,
+		       pci_get_subvendor(dev), pci_get_subdevice(dev));
+	}
+
+	priv = kmalloc(sizeof(struct serial_private) +
+			      sizeof(unsigned int) * board->num_ports,
+			      GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	/*
+	 * Run the initialization function, if any
+	 */
+	if (board->init_fn) {
+		rc = board->init_fn(dev, board, 1);
+		if (rc != 0) {
+			kfree(priv);
+			return rc;
+		}
+	}
+
+	base_baud = board->base_baud;
+	if (!base_baud)
+		base_baud = BASE_BAUD;
+	memset(&serial_req, 0, sizeof(serial_req));
+	for (k = 0; k < board->num_ports; k++) {
+		serial_req.irq = get_pci_irq(dev, board, k);
+		if (get_pci_port(dev, board, &serial_req, k))
+			break;
+#ifdef SERIAL_DEBUG_PCI
+		printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
+		       serial_req.port, serial_req.irq, serial_req.io_type);
+#endif
+		serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
+		serial_req.baud_base = base_baud;
+		
+		priv->line[k] = register_serial(&serial_req);
+		if (priv->line[k] < 0)
+			break;
+	}
+
+	priv->board = board;
+	priv->nr = k;
+
+	pci_set_drvdata(dev, priv);
+
+	return 0;
+}
+
+static void __devexit pci_remove_one(struct pci_dev *dev)
+{
+	struct serial_private *priv = pci_get_drvdata(dev);
+	int i;
+
+	pci_set_drvdata(dev, NULL);
+
+	if (priv) {
+		for (i = 0; i < priv->nr; i++)
+			unregister_serial(priv->line[i]);
+
+		priv->board->init_fn(dev, priv->board, 0);
+
+		pci_disable_device(dev);
+
+		kfree(priv);
+	}
+}
+
+static struct pci_device_id serial_pci_tbl[] __devinitdata = {
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
+		pbn_b1_8_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
+		pbn_b1_4_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
+		pbn_b1_2_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
+		pbn_b1_8_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
+		pbn_b1_4_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
+		pbn_b1_2_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0,
+		pbn_b1_8_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0,
+		pbn_b1_8_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0,
+		pbn_b1_4_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0,
+		pbn_b1_4_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0,
+		pbn_b1_2_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6, 0, 0,
+		pbn_b1_8_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0,
+		pbn_b1_8_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0,
+		pbn_b1_4_921600 },
+
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_bt_1_115200 },
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_bt_2_115200 },
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM422,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_bt_4_115200 },
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM232,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_bt_2_115200 },
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_bt_4_115200 },
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_8_115200 },
+
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b2_bt_2_115200 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b2_bt_2_921600 },
+	/* VScom SPCOM800, from sl@s.pl */
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800, 
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_8_921600 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_4_921600 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_KEYSPAN,
+		PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
+		pbn_panacom },
+	{	PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_panacom4 },
+	{	PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_panacom2 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+		PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0, 
+		pbn_b2_4_460800 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+		PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0, 
+		pbn_b2_8_460800 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+		PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0, 
+		pbn_b2_16_460800 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+		PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0, 
+		pbn_b2_16_460800 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+		PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0, 
+		pbn_b2_4_460800 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+		PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0, 
+		pbn_b2_8_460800 },
+	/* Megawolf Romulus PCI Serial Card, from Mike Hudson */
+	/* (Exoray@isys.ca) */
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
+		0x10b5, 0x106a, 0, 0,
+		pbn_plx_romulus },
+	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b1_4_115200 },
+	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b1_2_115200 },
+	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b1_8_115200 },
+	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b1_8_115200 },
+	{	PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
+		PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, 0, 0, 
+		pbn_b0_4_921600 },
+	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_4_115200 },
+	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_2_115200 },
+
+	/* Digitan DS560-558, from jimd@esoft.com */
+	{	PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b1_1_115200 },
+
+	/* 3Com US Robotics 56k Voice Internal PCI model 5610 */
+	{	PCI_VENDOR_ID_USR, 0x1008,
+		PCI_ANY_ID, PCI_ANY_ID, },
+
+	/* Titan Electronic cards */
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_1_921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_2_921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_4_921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_4_921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L,
+		PCI_ANY_ID, PCI_ANY_ID,
+		SPCI_FL_BASE1, 1, 921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L,
+		PCI_ANY_ID, PCI_ANY_ID,
+		SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
+	/* The 400L and 800L have a custom hack in get_pci_port */
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L,
+		PCI_ANY_ID, PCI_ANY_ID,
+		SPCI_FL_BASE_TABLE, 4, 921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
+		PCI_ANY_ID, PCI_ANY_ID,
+		SPCI_FL_BASE_TABLE, 8, 921600 },
+
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_1 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_1 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_1 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_4 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_4 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_4 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_4 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_4 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_4 },
+
+	/* Computone devices submitted by Doug McNash dmcnash@computone.com */
+	{	PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+		PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
+		0, 0, pbn_computone_4 },
+	{	PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+		PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
+		0, 0, pbn_computone_8 },
+	{	PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+		PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
+		0, 0, pbn_computone_6 },
+
+	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_oxsemi },
+	{	PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
+		PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0, pbn_timedia },
+
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_115200 },
+	/* AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org> */
+	{	PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_8_115200 },
+
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_115200 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_115200 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_460800 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_460800 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_460800 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_1_115200 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_1_460800 },
+
+	/* RAStel 2 port modem, gerg@moreton.com.au */
+	{	PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b2_bt_2_115200 },
+
+	/* EKF addition for i960 Boards form EKF with serial port */
+	{	PCI_VENDOR_ID_INTEL, 0x1960,
+		0xE4BF, PCI_ANY_ID, 0, 0,
+		pbn_intel_i960 },
+
+	/* Xircom Cardbus/Ethernet combos */
+	{	PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_X3201_MDM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_xircom_combo },
+
+	/*
+	 * Untested PCI modems, sent in from various folks...
+	 */
+
+	/* Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de> */
+	{	PCI_VENDOR_ID_ROCKWELL, 0x1004,
+		0x1048, 0x1500, 0, 0,
+		pbn_b1_1_115200 },
+
+	{	PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+		0xFF00, 0, 0, 0,
+		pbn_sgi_ioc3 },
+
+	/*
+	 * NEC Vrc-5074 (Nile 4) builtin UART.
+	 */
+	{	PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NILE4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_nec_nile4 },
+
+	{	PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_dci_pccom4 },
+	{	PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_dci_pccom8 },
+
+	{	PCI_ANY_ID, PCI_ANY_ID,
+		PCI_ANY_ID, PCI_ANY_ID,
+		PCI_CLASS_COMMUNICATION_SERIAL << 8,
+		0xffff00, },
+	{	PCI_ANY_ID, PCI_ANY_ID,
+		PCI_ANY_ID, PCI_ANY_ID,
+		PCI_CLASS_COMMUNICATION_MODEM << 8,
+		0xffff00, },
+	{	PCI_ANY_ID, PCI_ANY_ID,
+		PCI_ANY_ID, PCI_ANY_ID,
+		PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
+		0xffff00, },
+	{ 0, }
+};
+
+#ifndef __devexit_p
+#if defined(MODULE) || defined(CONFIG_HOTPLUG)
+#define __devexit_p(x) x
+#else
+#define __devexit_p(x) NULL
+#endif
+#endif
+
+static struct pci_driver serial_pci_driver = {
+	name:		"serial",
+	probe:		pci_init_one,
+	remove:		__devexit_p(pci_remove_one),
+	id_table:	serial_pci_tbl,
+};
+
+static int __init serial8250_pci_init(void)
+{
+	return pci_module_init(&serial_pci_driver);
+}
+
+static void __exit serial8250_pci_exit(void)
+{
+	pci_unregister_driver(&serial_pci_driver);
+}
+
+module_init(serial8250_pci_init);
+module_exit(serial8250_pci_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module");
+MODULE_DEVICE_TABLE(pci, serial_pci_tbl);
diff -Nru a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/8250_pnp.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,548 @@
+/*
+ *  linux/drivers/char/8250_pnp.c
+ *
+ *  Probe module for 8250/16550-type ISAPNP serial ports.
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King, 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 as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ *  $Id: 8250_pnp.c,v 1.10 2002/07/21 21:32:30 rmk Exp $
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/isapnp.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+
+#include <asm/bitops.h>
+#include <asm/byteorder.h>
+#include <asm/serial.h>
+
+#include "8250.h"
+
+struct pnpbios_device_id
+{
+	char id[8];
+	unsigned long driver_data;
+};
+
+static const struct pnpbios_device_id pnp_dev_table[] = {
+	/* Archtek America Corp. */
+	/* Archtek SmartLink Modem 3334BT Plug & Play */
+	{	"AAC000F",		0	},
+	/* Anchor Datacomm BV */
+	/* SXPro 144 External Data Fax Modem Plug & Play */
+	{	"ADC0001",		0	},
+	/* SXPro 288 External Data Fax Modem Plug & Play */
+	{	"ADC0002",		0	},
+	/* Rockwell 56K ACF II Fax+Data+Voice Modem */
+	{	"AKY1021",		SPCI_FL_NO_SHIRQ	},
+	/* AZT3005 PnP SOUND DEVICE */
+	{	"AZT4001",		0	},
+	/* Best Data Products Inc. Smart One 336F PnP Modem */
+	{	"BDP3336",		0	},
+	/*  Boca Research */
+	/* Boca Complete Ofc Communicator 14.4 Data-FAX */
+	{	"BRI0A49",		0	},
+	/* Boca Research 33,600 ACF Modem */
+	{	"BRI1400",		0	},
+	/* Boca 33.6 Kbps Internal FD34FSVD */
+	{	"BRI3400",		0	},
+	/* Boca 33.6 Kbps Internal FD34FSVD */
+	{	"BRI0A49",		0	},
+	/* Best Data Products Inc. Smart One 336F PnP Modem */
+	{	"BDP3336",		0	},
+	/* Computer Peripherals Inc */
+	/* EuroViVa CommCenter-33.6 SP PnP */
+	{	"CPI4050",		0	},
+	/* Creative Labs */
+	/* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */
+	{	"CTL3001",		0	},
+	/* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
+	{	"CTL3011",		0	},
+	/* Creative */
+	/* Creative Modem Blaster Flash56 DI5601-1 */
+	{	"DMB1032",		0	},
+	/* Creative Modem Blaster V.90 DI5660 */
+	{	"DMB2001",		0	},
+	/* FUJITSU */
+	/* Fujitsu 33600 PnP-I2 R Plug & Play */
+	{	"FUJ0202",		0	},
+	/* Fujitsu FMV-FX431 Plug & Play */
+	{	"FUJ0205",		0	},
+	/* Fujitsu 33600 PnP-I4 R Plug & Play */
+	{	"FUJ0206",		0	},
+	/* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */
+	{	"FUJ0209",		0	},
+	/* Archtek America Corp. */
+	/* Archtek SmartLink Modem 3334BT Plug & Play */
+	{	"GVC000F",		0	},
+	/* Hayes */
+	/* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
+	{	"HAY0001",		0	},
+	/* Hayes Optima 336 V.34 + FAX + Voice PnP */
+	{	"HAY000C",		0	},
+	/* Hayes Optima 336B V.34 + FAX + Voice PnP */
+	{	"HAY000D",		0	},
+	/* Hayes Accura 56K Ext Fax Modem PnP */
+	{	"HAY5670",		0	},
+	/* Hayes Accura 56K Ext Fax Modem PnP */
+	{	"HAY5674",		0	},
+	/* Hayes Accura 56K Fax Modem PnP */
+	{	"HAY5675",		0	},
+	/* Hayes 288, V.34 + FAX */
+	{	"HAYF000",		0	},
+	/* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */
+	{	"HAYF001",		0	},
+	/* IBM */
+	/* IBM Thinkpad 701 Internal Modem Voice */
+	{	"IBM0033",		0	},
+	/* Intertex */
+	/* Intertex 28k8 33k6 Voice EXT PnP */
+	{	"IXDC801",		0	},
+	/* Intertex 33k6 56k Voice EXT PnP */
+	{	"IXDC901",		0	},
+	/* Intertex 28k8 33k6 Voice SP EXT PnP */
+	{	"IXDD801",		0	},
+	/* Intertex 33k6 56k Voice SP EXT PnP */
+	{	"IXDD901",		0	},
+	/* Intertex 28k8 33k6 Voice SP INT PnP */
+	{	"IXDF401",		0	},
+	/* Intertex 28k8 33k6 Voice SP EXT PnP */
+	{	"IXDF801",		0	},
+	/* Intertex 33k6 56k Voice SP EXT PnP */
+	{	"IXDF901",		0	},
+	/* Kortex International */
+	/* KORTEX 28800 Externe PnP */
+	{	"KOR4522",		0	},
+	/* KXPro 33.6 Vocal ASVD PnP */
+	{	"KORF661",		0	},
+	/* Lasat */
+	/* LASAT Internet 33600 PnP */
+	{	"LAS4040",		0	},
+	/* Lasat Safire 560 PnP */
+	{	"LAS4540",		0	},
+	/* Lasat Safire 336  PnP */
+	{	"LAS5440",		0	},
+	/* Microcom, Inc. */
+	/* Microcom TravelPorte FAST V.34 Plug & Play */
+	{	"MNP0281",		0	},
+	/* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */
+	{	"MNP0336",		0	},
+	/* Microcom DeskPorte FAST EP 28.8 Plug & Play */
+	{	"MNP0339",		0	},
+	/* Microcom DeskPorte 28.8P Plug & Play */
+	{	"MNP0342",		0	},
+	/* Microcom DeskPorte FAST ES 28.8 Plug & Play */
+	{	"MNP0500",		0	},
+	/* Microcom DeskPorte FAST ES 28.8 Plug & Play */
+	{	"MNP0501",		0	},
+	/* Microcom DeskPorte 28.8S Internal Plug & Play */
+	{	"MNP0502",		0	},
+	/* Motorola */
+	/* Motorola BitSURFR Plug & Play */
+	{	"MOT1105",		0	},
+	/* Motorola TA210 Plug & Play */
+	{	"MOT1111",		0	},
+	/* Motorola HMTA 200 (ISDN) Plug & Play */
+	{	"MOT1114",		0	},
+	/* Motorola BitSURFR Plug & Play */
+	{	"MOT1115",		0	},
+	/* Motorola Lifestyle 28.8 Internal */
+	{	"MOT1190",		0	},
+	/* Motorola V.3400 Plug & Play */
+	{	"MOT1501",		0	},
+	/* Motorola Lifestyle 28.8 V.34 Plug & Play */
+	{	"MOT1502",		0	},
+	/* Motorola Power 28.8 V.34 Plug & Play */
+	{	"MOT1505",		0	},
+	/* Motorola ModemSURFR External 28.8 Plug & Play */
+	{	"MOT1509",		0	},
+	/* Motorola Premier 33.6 Desktop Plug & Play */
+	{	"MOT150A",		0	},
+	/* Motorola VoiceSURFR 56K External PnP */
+	{	"MOT150F",		0	},
+	/* Motorola ModemSURFR 56K External PnP */
+	{	"MOT1510",		0	},
+	/* Motorola ModemSURFR 56K Internal PnP */
+	{	"MOT1550",		0	},
+	/* Motorola ModemSURFR Internal 28.8 Plug & Play */
+	{	"MOT1560",		0	},
+	/* Motorola Premier 33.6 Internal Plug & Play */
+	{	"MOT1580",		0	},
+	/* Motorola OnlineSURFR 28.8 Internal Plug & Play */
+	{	"MOT15B0",		0	},
+	/* Motorola VoiceSURFR 56K Internal PnP */
+	{	"MOT15F0",		0	},
+	/* Com 1 */
+	/*  Deskline K56 Phone System PnP */
+	{	"MVX00A1",		0	},
+	/* PC Rider K56 Phone System PnP */
+	{	"MVX00F2",		0	},
+	/* Pace 56 Voice Internal Plug & Play Modem */
+	{	"PMC2430",		0	},
+	/* Generic */
+	/* Generic standard PC COM port	 */
+	{	"PNP0500",		0	},
+	/* Generic 16550A-compatible COM port */
+	{	"PNP0501",		0	},
+	/* Compaq 14400 Modem */
+	{	"PNPC000",		0	},
+	/* Compaq 2400/9600 Modem */
+	{	"PNPC001",		0	},
+	/* Dial-Up Networking Serial Cable between 2 PCs */
+	{	"PNPC031",		0	},
+	/* Dial-Up Networking Parallel Cable between 2 PCs */
+	{	"PNPC032",		0	},
+	/* Standard 9600 bps Modem */
+	{	"PNPC100",		0	},
+	/* Standard 14400 bps Modem */
+	{	"PNPC101",		0	},
+	/*  Standard 28800 bps Modem*/
+	{	"PNPC102",		0	},
+	/*  Standard Modem*/
+	{	"PNPC103",		0	},
+	/*  Standard 9600 bps Modem*/
+	{	"PNPC104",		0	},
+	/*  Standard 14400 bps Modem*/
+	{	"PNPC105",		0	},
+	/*  Standard 28800 bps Modem*/
+	{	"PNPC106",		0	},
+	/*  Standard Modem */
+	{	"PNPC107",		0	},
+	/* Standard 9600 bps Modem */
+	{	"PNPC108",		0	},
+	/* Standard 14400 bps Modem */
+	{	"PNPC109",		0	},
+	/* Standard 28800 bps Modem */
+	{	"PNPC10A",		0	},
+	/* Standard Modem */
+	{	"PNPC10B",		0	},
+	/* Standard 9600 bps Modem */
+	{	"PNPC10C",		0	},
+	/* Standard 14400 bps Modem */
+	{	"PNPC10D",		0	},
+	/* Standard 28800 bps Modem */
+	{	"PNPC10E",		0	},
+	/* Standard Modem */
+	{	"PNPC10F",		0	},
+	/* Standard PCMCIA Card Modem */
+	{	"PNP2000",		0	},
+	/* Rockwell */
+	/* Modular Technology */
+	/* Rockwell 33.6 DPF Internal PnP */
+	/* Modular Technology 33.6 Internal PnP */
+	{	"ROK0030",		0	},
+	/* Kortex International */
+	/* KORTEX 14400 Externe PnP */
+	{	"ROK0100",		0	},
+	/* Viking Components, Inc */
+	/* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
+	{	"ROK4920",		0	},
+	/* Rockwell */
+	/* British Telecom */
+	/* Modular Technology */
+	/* Rockwell 33.6 DPF External PnP */
+	/* BT Prologue 33.6 External PnP */
+	/* Modular Technology 33.6 External PnP */
+	{	"RSS00A0",		0	},
+	/* Viking 56K FAX INT */
+	{	"RSS0262",		0	},
+	/* SupraExpress 28.8 Data/Fax PnP modem */
+	{	"SUP1310",		0	},
+	/* SupraExpress 33.6 Data/Fax PnP modem */
+	{	"SUP1421",		0	},
+	/* SupraExpress 33.6 Data/Fax PnP modem */
+	{	"SUP1590",		0	},
+	/* SupraExpress 33.6 Data/Fax PnP modem */
+	{	"SUP1760",		0	},
+	/* Phoebe Micro */
+	/* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
+	{	"TEX0011",		0	},
+	/* Archtek America Corp. */
+	/* Archtek SmartLink Modem 3334BT Plug & Play */
+	{	"UAC000F",		0	},
+	/* 3Com Corp. */
+	/* Gateway Telepath IIvi 33.6 */
+	{	"USR0000",		0	},
+	/*  Sportster Vi 14.4 PnP FAX Voicemail */
+	{	"USR0004",		0	},
+	/* U.S. Robotics 33.6K Voice INT PnP */
+	{	"USR0006",		0	},
+	/* U.S. Robotics 33.6K Voice EXT PnP */
+	{	"USR0007",		0	},
+	/* U.S. Robotics 33.6K Voice INT PnP */
+	{	"USR2002",		0	},
+	/* U.S. Robotics 56K Voice INT PnP */
+	{	"USR2070",		0	},
+	/* U.S. Robotics 56K Voice EXT PnP */
+	{	"USR2080",		0	},
+	/* U.S. Robotics 56K FAX INT */
+	{	"USR3031",		0	},
+	/* U.S. Robotics 56K Voice INT PnP */
+	{	"USR3070",		0	},
+	/* U.S. Robotics 56K Voice EXT PnP */
+	{	"USR3080",		0	},
+	/* U.S. Robotics 56K Voice INT PnP */
+	{	"USR3090",		0	},
+	/* U.S. Robotics 56K Message  */
+	{	"USR9100",		0	},
+	/* U.S. Robotics 56K FAX EXT PnP*/
+	{	"USR9160",		0	},
+	/* U.S. Robotics 56K FAX INT PnP*/
+	{	"USR9170",		0	},
+	/* U.S. Robotics 56K Voice EXT PnP*/
+	{	"USR9180",		0	},
+	/* U.S. Robotics 56K Voice INT PnP*/
+	{	"USR9190",		0	},
+	{	"",			0	}
+};
+
+static void inline avoid_irq_share(struct pci_dev *dev)
+{
+	unsigned int map = 0x1FF8;
+	struct isapnp_irq *irq;
+	struct isapnp_resources *res = dev->sysdata;
+
+	serial8250_get_irq_map(&map);
+
+	for ( ; res; res = res->alt)
+		for (irq = res->irq; irq; irq = irq->next)
+			irq->map = map;
+}
+
+static char *modem_names[] __devinitdata = {
+	"MODEM", "Modem", "modem", "FAX", "Fax", "fax",
+	"56K", "56k", "K56", "33.6", "28.8", "14.4",
+	"33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
+	"33600", "28800", "14400", "V.90", "V.34", "V.32", 0
+};
+
+static int __devinit check_name(char *name)
+{
+	char **tmp;
+
+	for (tmp = modem_names; *tmp; tmp++)
+		if (strstr(name, *tmp))
+			return 1;
+
+	return 0;
+}
+
+static int inline check_compatible_id(struct pci_dev *dev)
+{
+	int i;
+	for (i = 0; i < DEVICE_COUNT_COMPATIBLE; i++)
+		if ((dev->vendor_compatible[i] ==
+		     ISAPNP_VENDOR('P', 'N', 'P')) &&
+		    (swab16(dev->device_compatible[i]) >= 0xc000) &&
+		    (swab16(dev->device_compatible[i]) <= 0xdfff))
+			return 0;
+	return 1;
+}
+
+/*
+ * Given a complete unknown ISA PnP device, try to use some heuristics to
+ * detect modems. Currently use such heuristic set:
+ *     - dev->name or dev->bus->name must contain "modem" substring;
+ *     - device must have only one IO region (8 byte long) with base adress
+ *       0x2e8, 0x3e8, 0x2f8 or 0x3f8.
+ *
+ * Such detection looks very ugly, but can detect at least some of numerous
+ * ISA PnP modems, alternatively we must hardcode all modems in pnp_devices[]
+ * table.
+ */
+static int serial_pnp_guess_board(struct pci_dev *dev, int *flags)
+{
+	struct isapnp_resources *res = (struct isapnp_resources *)dev->sysdata;
+	struct isapnp_resources *resa;
+
+	if (!(check_name(dev->name) || check_name(dev->bus->name)) &&
+	    !(check_compatible_id(dev)))
+		return -ENODEV;
+
+	if (!res || res->next)
+		return -ENODEV;
+
+	for (resa = res->alt; resa; resa = resa->alt) {
+		struct isapnp_port *port;
+		for (port = res->port; port; port = port->next)
+			if ((port->size == 8) &&
+			    ((port->min == 0x2f8) ||
+			     (port->min == 0x3f8) ||
+			     (port->min == 0x2e8) ||
+			     (port->min == 0x3e8)))
+				return 0;
+	}
+
+	return -ENODEV;
+}
+
+static int
+pnp_init_one(struct pci_dev *dev, const struct pnpbios_device_id *ent,
+	     char *slot_name)
+{
+	struct serial_struct serial_req;
+	int ret, line, flags = ent ? ent->driver_data : 0;
+
+	if (!ent) {
+		ret = serial_pnp_guess_board(dev, &flags);
+		if (ret)
+			return ret;
+	}
+
+	if (dev->prepare(dev) < 0) {
+		printk("serial: PNP device '%s' prepare failed\n",
+			slot_name);
+		return -ENODEV;
+	}
+
+	if (dev->active)
+		return -ENODEV;
+
+	if (flags & SPCI_FL_NO_SHIRQ)
+		avoid_irq_share(dev);
+
+	if (dev->activate(dev) < 0) {
+		printk("serial: PNP device '%s' activate failed\n",
+			slot_name);
+		return -ENODEV;
+	}
+
+	memset(&serial_req, 0, sizeof(serial_req));
+	serial_req.irq = dev->irq_resource[0].start;
+	serial_req.port = pci_resource_start(dev, 0);
+	if (HIGH_BITS_OFFSET)
+		serial_req.port = pci_resource_start(dev, 0) >> HIGH_BITS_OFFSET;
+
+#ifdef SERIAL_DEBUG_PNP
+	printk("Setup PNP port: port %x, irq %d, type %d\n",
+	       serial_req.port, serial_req.irq, serial_req.io_type);
+#endif
+
+	serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
+	serial_req.baud_base = 115200;
+	line = register_serial(&serial_req);
+
+	if (line >= 0) {
+		pci_set_drvdata(dev, (void *)(line + 1));
+
+		/*
+		 * Public health warning: remove this once the 2.5
+		 * pnpbios_module_init() stuff is incorporated.
+		 */
+		dev->driver = (void *)pnp_dev_table;
+	} else
+		dev->deactivate(dev);
+
+	return line >= 0 ? 0 : -ENODEV;
+}
+
+static void pnp_remove_one(struct pci_dev *dev)
+{
+	int line = (int)pci_get_drvdata(dev);
+
+	if (line) {
+		pci_set_drvdata(dev, NULL);
+
+		unregister_serial(line - 1);
+
+		dev->deactivate(dev);
+	}
+}
+
+static char hex[] = "0123456789ABCDEF";
+
+/*
+ * This function should vanish when 2.5 comes around and
+ * we have pnpbios_module_init()
+ */
+static int pnp_init(void)
+{
+	const struct pnpbios_device_id *id;
+	struct pci_dev *dev = NULL;
+	int nr = 0, rc = -ENODEV;
+
+#ifdef SERIAL_DEBUG_PNP
+	printk("Entered probe_serial_pnp()\n");
+#endif
+
+	isapnp_for_each_dev(dev) {
+		char slot_name[8];
+		u32 pnpid;
+
+		if (dev->active)
+			continue;
+
+		pnpid = dev->vendor << 16 | dev->device;
+		pnpid = cpu_to_le32(pnpid);
+
+#define HEX(id,a) hex[((id)>>a) & 15]
+#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
+		slot_name[0] = CHAR(pnpid, 26);
+		slot_name[1] = CHAR(pnpid, 21);
+		slot_name[2] = CHAR(pnpid, 16);
+		slot_name[3] = HEX(pnpid, 12);
+		slot_name[4] = HEX(pnpid, 8);
+		slot_name[5] = HEX(pnpid, 4);
+		slot_name[6] = HEX(pnpid, 0);
+		slot_name[7] = '\0';
+		
+		for (id = pnp_dev_table; id->id[0]; id++)
+			if (memcmp(id->id, slot_name, 7) == 0)
+				break;
+
+		if (id->id[0])
+			rc = pnp_init_one(dev, id, slot_name);
+		else
+			rc = pnp_init_one(dev, NULL, slot_name);
+
+		if (rc == 0)
+			nr++;
+	}
+
+#ifdef SERIAL_DEBUG_PNP
+	printk("Leaving probe_serial_pnp() (probe finished)\n");
+#endif
+
+	return nr == 0 ? rc : 0;
+}
+
+static int __init serial8250_pnp_init(void)
+{
+	if (!isapnp_present()) {
+#ifdef SERIAL_DEBUG_PNP
+		printk("Leaving probe_serial_pnp() (no isapnp)\n");
+#endif
+		return -ENODEV;
+	}
+	return pnp_init();
+}
+
+static void __exit serial8250_pnp_exit(void)
+{
+	struct pci_dev *dev = NULL;
+
+	isapnp_for_each_dev(dev) {
+		if (dev->driver != (void *)pnp_dev_table)
+			continue;
+		pnp_remove_one(dev);
+	}
+}
+
+module_init(serial8250_pnp_init);
+module_exit(serial8250_pnp_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 PNPBIOS serial probe module");
+MODULE_DEVICE_TABLE(pnpbios, pnp_dev_table);
diff -Nru a/drivers/serial/Config.help b/drivers/serial/Config.help
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/Config.help	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,225 @@
+# $Id: Config.help,v 1.5 2002/07/06 17:16:24 rmk Exp $
+
+CONFIG_SERIAL_8250
+  This selects whether you want to include the driver for the standard
+  serial ports.  The standard answer is Y.  People who might say N
+  here are those that are setting up dedicated Ethernet WWW/FTP
+  servers, or users that have one of the various bus mice instead of a
+  serial mouse and don't intend to use their machine's standard serial
+  port for anything.  (Note that the Cyclades and Stallion multi
+  serial port drivers do not need this driver built in for them to
+  work.)
+
+  If you want to compile this driver as a module, say M here and read
+  <file:Documentation/modules.txt>.  The module will be called
+  serial.o.
+  [WARNING: Do not compile this driver as a module if you are using
+  non-standard serial ports, since the configuration information will
+  be lost when the driver is unloaded.  This limitation may be lifted
+  in the future.]
+
+  BTW1: If you have a mouseman serial mouse which is not recognized by
+  the X window system, try running gpm first.
+
+  BTW2: If you intend to use a software modem (also called Winmodem)
+  under Linux, forget it.  These modems are crippled and require
+  proprietary drivers which are only available under Windows.
+
+  Most people will say Y or M here, so that they can use serial mice,
+  modems and similar devices connecting to the standard serial ports.
+
+CONFIG_SERIAL_8250_CONSOLE
+  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
+  kernel messages and warnings and which allows logins in single user
+  mode). This could be useful if some terminal or printer is connected
+  to that serial port.
+
+  Even if you say Y here, the currently visible virtual console
+  (/dev/tty0) will still be used as the system console by default, but
+  you can alter that using a kernel command line option such as
+  "console=ttyS1". (Try "man bootparam" or see the documentation of
+  your boot loader (lilo or loadlin) about how to pass options to the
+  kernel at boot time.)
+
+  If you don't have a VGA card installed and you say Y here, the
+  kernel will automatically use the first serial line, /dev/ttyS0, as
+  system console.
+
+  If unsure, say N.
+
+CONFIG_SERIAL_8250_CS
+  Say Y here to enable support for 16-bit PCMCIA serial devices,
+  including serial port cards, modems, and the modem functions of
+  multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are
+  credit-card size devices often used with laptops.)
+
+  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 serial_cs.o.  If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.
+  If unsure, say N.
+
+CONFIG_SERIAL_8250_EXTENDED
+  If you wish to use any non-standard features of the standard "dumb"
+  driver, say Y here. This includes HUB6 support, shared serial
+  interrupts, special multiport support, support for more than the
+  four COM 1/2/3/4 boards, etc.
+
+  Note that the answer to this question won't directly affect the
+  kernel: saying N will just cause the configurator to skip all
+  the questions about serial driver options. If unsure, say N.
+
+CONFIG_SERIAL_8250_MANY_PORTS
+  Say Y here if you have dumb serial boards other than the four
+  standard COM 1/2/3/4 ports. This may happen if you have an AST
+  FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
+  from <http://www.linuxdoc.org/docs.html#howto>), or other custom
+  serial port hardware which acts similar to standard serial port
+  hardware. If you only use the standard COM 1/2/3/4 ports, you can
+  say N here to save some memory. You can also say Y if you have an
+  "intelligent" multiport card such as Cyclades, Digiboards, etc.
+
+CONFIG_SERIAL_8250_SHARE_IRQ
+  Some serial boards have hardware support which allows multiple dumb
+  serial ports on the same board to share a single IRQ. To enable
+  support for this in the serial driver, say Y here.
+
+CONFIG_SERIAL_8250_DETECT_IRQ
+  Say Y here if you want the kernel to try to guess which IRQ
+  to use for your serial port.
+
+  This is considered unsafe; it is far better to configure the IRQ in
+  a boot script using the setserial command.
+
+  If unsure, say N.
+
+CONFIG_SERIAL_8250_MULTIPORT
+  Some multiport serial ports have special ports which are used to
+  signal when there are any serial ports on the board which need
+  servicing. Say Y here to enable the serial driver to take advantage
+  of those special I/O ports.
+
+CONFIG_SERIAL_8250_RSA
+  ::: To be written :::
+
+CONFIG_ATOMWIDE_SERIAL
+  If you have an Atomwide Serial card for an Acorn system, say Y to
+  this option.  The driver can handle 1, 2, or 3 port cards.
+  If unsure, say N.
+
+CONFIG_DUALSP_SERIAL
+  If you have the Serial Port's dual serial card for an Acorn system,
+  say Y to this option.  If unsure, say N.
+
+CONFIG_SERIAL_ANAKIN
+  ::: To be written :::
+CONFIG_SERIAL_ANAKIN_CONSOLE
+  ::: To be written :::
+
+  Even if you say Y here, the currently visible virtual console
+  (/dev/tty0) will still be used as the system console by default, but
+  you can alter that using a kernel command line option such as
+  "console=ttyAN0". (Try "man bootparam" or see the documentation of
+  your boot loader (lilo or loadlin) about how to pass options to the
+  kernel at boot time.)
+
+CONFIG_ANAKIN_DEFAULT_BAUDRATE
+  ::: To be written :::
+
+CONFIG_SERIAL_AMBA
+  This selects the ARM(R) AMBA(R) PrimeCell UART.  If you have an
+  Integrator platform, say Y or M here.
+
+  If unsure, say N.
+
+CONFIG_SERIAL_AMBA_CONSOLE
+  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
+  messages and warnings and which allows logins in single user mode).
+
+  Even if you say Y here, the currently visible framebuffer console
+  (/dev/tty0) will still be used as the system console by default, but
+  you can alter that using a kernel command line option such as
+  "console=ttyAM0". (Try "man bootparam" or see the documentation of
+  your boot loader (lilo or loadlin) about how to pass options to the
+  kernel at boot time.)
+
+CONFIG_SERIAL_CLPS711X
+  ::: To be written :::
+
+CONFIG_SERIAL_CLPS711X_CONSOLE
+  ::: To be written :::
+
+  Even if you say Y here, the currently visible virtual console
+  (/dev/tty0) will still be used as the system console by default, but
+  you can alter that using a kernel command line option such as
+  "console=ttyCL1". (Try "man bootparam" or see the documentation of
+  your boot loader (lilo or loadlin) about how to pass options to the
+  kernel at boot time.)
+
+CONFIG_SERIAL_CLPS711X_OLD_NAME
+  ::: To be written :::
+
+CONFIG_SERIAL_21285
+  If you have a machine based on a 21285 (Footbridge) StrongARM(R)/
+  PCI bridge you can enable its onboard serial port by enabling this
+  option.
+
+CONFIG_SERIAL_21285_OLD
+  Use the old /dev/ttyS name, major 4 minor 64.  This is obsolete
+  and will be removed during later 2.5 development.
+
+CONFIG_SERIAL_21285_CONSOLE
+  If you have enabled the serial port on the 21285 footbridge you can
+  make it the console by answering Y to this option.
+
+  Even if you say Y here, the currently visible virtual console
+  (/dev/tty0) will still be used as the system console by default, but
+  you can alter that using a kernel command line option such as
+  "console=ttyFB". (Try "man bootparam" or see the documentation of
+  your boot loader (lilo or loadlin) about how to pass options to the
+  kernel at boot time.)
+
+CONFIG_SERIAL_UART00
+  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.
+
+CONFIG_SERIAL_UART00_CONSOLE
+  Say Y here if you want to support a serial console on an Excalibur
+  hard logic uart or uart00 IP core.
+
+  Even if you say Y here, the currently visible virtual console
+  (/dev/tty0) will still be used as the system console by default, but
+  you can alter that using a kernel command line option such as
+  "console=ttyS1". (Try "man bootparam" or see the documentation of
+  your boot loader (lilo or loadlin) about how to pass options to the
+  kernel at boot time.)
+
+CONFIG_SERIAL_SA1100
+  If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
+  can enable its onboard serial port by enabling this option.
+  Please read <file:Documentation/arm/SA1100/serial_UART> for further
+  info.
+
+CONFIG_SERIAL_SA1100_CONSOLE
+  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.
+
+  Even if you say Y here, the currently visible virtual console
+  (/dev/tty0) will still be used as the system console by default, but
+  you can alter that using a kernel command line option such as
+  "console=ttySA0". (Try "man bootparam" or see the documentation of
+  your boot loader (lilo or loadlin) about how to pass options to the
+  kernel at boot time.)
+
+#CONFIG_SERIAL_L7200
+#  If you have a LinkUp Systems L7200 board you can enable its two
+#  onboard serial ports by enabling this option. The device numbers
+#  are major ID 4 with minor 64 and 65 respectively.
+#
+#CONFIG_SERIAL_L7200_CONSOLE
+#  If you have enabled the serial ports on the L7200 development board
+#  you can make the first serial port the console by answering Y to
+#  this option.
+
diff -Nru a/drivers/serial/Config.in b/drivers/serial/Config.in
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/Config.in	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,77 @@
+#
+# Serial device configuration
+#
+# $Id: Config.in,v 1.15 2002/07/06 17:16:24 rmk Exp $
+#
+mainmenu_option next_comment
+comment 'Serial drivers'
+
+#
+# The new 8250/16550 serial drivers
+dep_tristate '8250/16550 and compatible serial support (EXPERIMENTAL)' CONFIG_SERIAL_8250 $CONFIG_EXPERIMENTAL
+dep_bool '  Console on 8250/16550 and compatible serial port (EXPERIMENTAL)' CONFIG_SERIAL_8250_CONSOLE $CONFIG_SERIAL_8250 $CONFIG_EXPERIMENTAL
+dep_tristate '  8250/16550 PCMCIA device support' CONFIG_SERIAL_8250_CS $CONFIG_PCMCIA $CONFIG_SERIAL_8250
+
+dep_mbool 'Extended 8250/16550 serial driver options' CONFIG_SERIAL_8250_EXTENDED $CONFIG_SERIAL_8250
+dep_bool '  Support more than 4 serial ports' CONFIG_SERIAL_8250_MANY_PORTS $CONFIG_SERIAL_8250_EXTENDED
+dep_bool '  Support for sharing serial interrupts' CONFIG_SERIAL_8250_SHARE_IRQ $CONFIG_SERIAL_8250_EXTENDED
+dep_bool '  Autodetect IRQ on standard ports (unsafe)' CONFIG_SERIAL_8250_DETECT_IRQ $CONFIG_SERIAL_8250_EXTENDED
+dep_bool '  Support special multiport boards' CONFIG_SERIAL_8250_MULTIPORT $CONFIG_SERIAL_8250_EXTENDED
+dep_bool '  Support RSA serial ports' CONFIG_SERIAL_8250_RSA $CONFIG_SERIAL_8250_EXTENDED
+
+comment 'Non-8250 serial port support'
+
+if [ "$CONFIG_ARM" = "y" ]; then
+   dep_tristate 'Acorn Atomwide 16550 serial port support' CONFIG_ATOMWIDE_SERIAL $CONFIG_ARCH_ACORN $CONFIG_SERIAL_8250
+   dep_tristate 'Acorn Dual 16550 serial port support' CONFIG_DUALSP_SERIAL $CONFIG_ARCH_ACORN $CONFIG_SERIAL_8250
+   dep_bool 'Anakin serial port support' CONFIG_SERIAL_ANAKIN $CONFIG_ARCH_ANAKIN
+   dep_bool '  Console on Anakin serial port' CONFIG_SERIAL_ANAKIN_CONSOLE $CONFIG_SERIAL_ANAKIN
+   if [ "$CONFIG_SERIAL_ANAKIN" = "y" ]; then
+      int  '  Default Anakin serial baudrate' CONFIG_ANAKIN_DEFAULT_BAUDRATE 9600
+   fi
+
+   dep_tristate 'ARM AMBA serial port support' CONFIG_SERIAL_AMBA $CONFIG_ARCH_INTEGRATOR
+   dep_bool '  Support for console on AMBA serial port' CONFIG_SERIAL_AMBA_CONSOLE $CONFIG_SERIAL_AMBA
+   if [ "$CONFIG_SERIAL_AMBA" = "y" ]; then
+      define_bool CONFIG_SERIAL_INTEGRATOR y
+   fi
+
+   dep_tristate 'CLPS711X serial port support' CONFIG_SERIAL_CLPS711X $CONFIG_ARCH_CLPS711X
+   dep_bool '  Support for console on CLPS711X serial port' CONFIG_SERIAL_CLPS711X_CONSOLE $CONFIG_SERIAL_CLPS711X
+   dep_bool '  Use the old 2.4 names for CLPS711X serial port' CONFIG_SERIAL_CLPS711X_OLD_NAME $CONFIG_SERIAL_CLPS711X
+
+   dep_tristate 'DC21285 serial port support' CONFIG_SERIAL_21285 $CONFIG_FOOTBRIDGE
+   dep_bool '  Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD $CONFIG_SERIAL_21285 $CONFIG_OBSOLETE
+   dep_bool '  Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE $CONFIG_SERIAL_21285
+
+   dep_bool 'Excalibur serial port (uart00) support' CONFIG_SERIAL_UART00 $CONFIG_ARCH_CAMELOT
+   dep_bool '  Support for console on Excalibur serial port' CONFIG_SERIAL_UART00_CONSOLE $CONFIG_SERIAL_UART00
+
+   dep_bool 'SA1100 serial port support' CONFIG_SERIAL_SA1100 $CONFIG_ARCH_SA1100
+   dep_bool '  Console on SA1100 serial port' CONFIG_SERIAL_SA1100_CONSOLE $CONFIG_SERIAL_SA1100
+fi
+
+if [ "$CONFIG_SERIAL_AMBA" = "y"   -o "$CONFIG_SERIAL_CLPS711X" = "y" -o \
+     "$CONFIG_SERIAL_21285" = "y"  -o "$CONFIG_SERIAL_SA1100" = "y" -o \
+     "$CONFIG_SERIAL_ANAKIN" = "y" -o "$CONFIG_SERIAL_UART00" = "y" -o \
+     "$CONFIG_SERIAL_8250" = "y"   -o "$CONFIG_SERIAL_ROCKETPORT" = "y" ]; then
+   define_bool CONFIG_SERIAL_CORE y
+else
+   if [ "$CONFIG_SERIAL_AMBA" = "m"   -o "$CONFIG_SERIAL_CLPS711X" = "m" -o \
+        "$CONFIG_SERIAL_21285" = "m"  -o "$CONFIG_SERIAL_SA1100" = "m" -o \
+        "$CONFIG_SERIAL_ANAKIN" = "m" -o "$CONFIG_SERIAL_UART00" = "m" -o \
+        "$CONFIG_SERIAL_8250" = "m"   -o "$CONFIG_SERIAL_ROCKETPORT" = "m" ]; then
+      define_bool CONFIG_SERIAL_CORE m
+   fi
+fi
+if [ "$CONFIG_SERIAL_AMBA_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_CLPS711X_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_21285_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_SA1100_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_ANAKIN_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_UART00_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_8250_CONSOLE" = "y" ]; then
+   define_bool CONFIG_SERIAL_CORE_CONSOLE y
+fi
+
+endmenu
diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/Makefile	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,22 @@
+#
+# Makefile for the kernel serial device drivers.
+#
+#  $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $
+#
+
+export-objs	:= core.o 8250.o
+
+serial-8250-y :=
+serial-8250-$(CONFIG_PCI) += 8250_pci.o
+serial-8250-$(CONFIG_ISAPNP) += 8250_pnp.o
+obj-$(CONFIG_SERIAL_CORE) += 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_ANAKIN) += anakin.o
+obj-$(CONFIG_SERIAL_AMBA) += amba.o
+obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
+obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
+obj-$(CONFIG_SERIAL_UART00) += uart00.o
+
+include $(TOPDIR)/Rules.make
diff -Nru a/drivers/serial/amba.c b/drivers/serial/amba.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/amba.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,774 @@
+/*
+ *  linux/drivers/char/amba.c
+ *
+ *  Driver for AMBA serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright 1999 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
+ *
+ *  $Id: amba.c,v 1.37 2002/07/22 15:27:32 rmk Exp $
+ *
+ * This is a generic driver for ARM AMBA-type serial ports.  They
+ * have a lot of 16550-like features, but are not register compatable.
+ * Note that although they do have CTS, DCD and DSR inputs, they do
+ * not have an RI input, nor do they have DTR or RTS outputs.  If
+ * required, these have to be supplied via some other means (eg, GPIO)
+ * and hooked into this driver.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.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/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#if defined(CONFIG_SERIAL_AMBA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#include <asm/hardware/serial_amba.h>
+
+#define UART_NR		2
+
+#define SERIAL_AMBA_MAJOR	204
+#define SERIAL_AMBA_MINOR	16
+#define SERIAL_AMBA_NR		UART_NR
+
+#define AMBA_ISR_PASS_LIMIT	256
+
+/*
+ * Access macros for the AMBA UARTs
+ */
+#define UART_GET_INT_STATUS(p)	readb((p)->membase + AMBA_UARTIIR)
+#define UART_PUT_ICR(p, c)	writel((c), (p)->membase + AMBA_UARTICR)
+#define UART_GET_FR(p)		readb((p)->membase + AMBA_UARTFR)
+#define UART_GET_CHAR(p)	readb((p)->membase + AMBA_UARTDR)
+#define UART_PUT_CHAR(p, c)	writel((c), (p)->membase + AMBA_UARTDR)
+#define UART_GET_RSR(p)		readb((p)->membase + AMBA_UARTRSR)
+#define UART_GET_CR(p)		readb((p)->membase + AMBA_UARTCR)
+#define UART_PUT_CR(p,c)	writel((c), (p)->membase + AMBA_UARTCR)
+#define UART_GET_LCRL(p)	readb((p)->membase + AMBA_UARTLCR_L)
+#define UART_PUT_LCRL(p,c)	writel((c), (p)->membase + AMBA_UARTLCR_L)
+#define UART_GET_LCRM(p)	readb((p)->membase + AMBA_UARTLCR_M)
+#define UART_PUT_LCRM(p,c)	writel((c), (p)->membase + AMBA_UARTLCR_M)
+#define UART_GET_LCRH(p)	readb((p)->membase + AMBA_UARTLCR_H)
+#define UART_PUT_LCRH(p,c)	writel((c), (p)->membase + AMBA_UARTLCR_H)
+#define UART_RX_DATA(s)		(((s) & AMBA_UARTFR_RXFE) == 0)
+#define UART_TX_READY(s)	(((s) & AMBA_UARTFR_TXFF) == 0)
+#define UART_TX_EMPTY(p)	((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0)
+
+#define UART_DUMMY_RSR_RX	256
+#define UART_PORT_SIZE		64
+
+/*
+ * On the Integrator platform, the port RTS and DTR are provided by
+ * bits in the following SC_CTRLS register bits:
+ *        RTS  DTR
+ *  UART0  7    6
+ *  UART1  5    4
+ */
+#define SC_CTRLC	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
+#define SC_CTRLS	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
+
+/*
+ * We wrap our port structure around the generic uart_port.
+ */
+struct uart_amba_port {
+	struct uart_port	port;
+	unsigned int		dtr_mask;
+	unsigned int		rts_mask;
+	unsigned int		old_status;
+};
+
+static void ambauart_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	unsigned int cr;
+
+	cr = UART_GET_CR(port);
+	cr &= ~AMBA_UARTCR_TIE;
+	UART_PUT_CR(port, cr);
+}
+
+static void ambauart_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	unsigned int cr;
+
+	cr = UART_GET_CR(port);
+	cr |= AMBA_UARTCR_TIE;
+	UART_PUT_CR(port, cr);
+}
+
+static void ambauart_stop_rx(struct uart_port *port)
+{
+	unsigned long flags;
+	unsigned int cr;
+
+	spin_lock_irqsave(&port->lock, flags);
+	cr = UART_GET_CR(port);
+	cr &= ~(AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE);
+	UART_PUT_CR(port, cr);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void ambauart_enable_ms(struct uart_port *port)
+{
+	unsigned long flags;
+	unsigned int cr;
+
+	spin_lock_irqsave(&port->lock, flags);
+	cr = UART_GET_CR(port);
+	cr |= AMBA_UARTCR_MSIE;
+	UART_PUT_CR(port, cr);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void
+#ifdef SUPPORT_SYSRQ
+ambauart_rx_chars(struct uart_port *port, struct pt_regs *regs)
+#else
+ambauart_rx_chars(struct uart_port *port)
+#endif
+{
+	struct tty_struct *tty = port->info->tty;
+	unsigned int status, ch, rsr, max_count = 256;
+
+	status = UART_GET_FR(port);
+	while (UART_RX_DATA(status) && max_count--) {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				printk(KERN_WARNING "TTY_DONT_FLIP set\n");
+				return;
+			}
+		}
+
+		ch = UART_GET_CHAR(port);
+
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		port->icount.rx++;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
+		if (rsr & AMBA_UARTRSR_ANY) {
+			if (rsr & AMBA_UARTRSR_BE) {
+				rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE);
+				port->icount.brk++;
+				if (uart_handle_break(port))
+					goto ignore_char;
+			} else if (rsr & AMBA_UARTRSR_PE)
+				port->icount.parity++;
+			else if (rsr & AMBA_UARTRSR_FE)
+				port->icount.frame++;
+			if (rsr & AMBA_UARTRSR_OE)
+				port->icount.overrun++;
+
+			rsr &= port->read_status_mask;
+
+			if (rsr & AMBA_UARTRSR_BE)
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			else if (rsr & AMBA_UARTRSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (rsr & AMBA_UARTRSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(port, ch, regs))
+			goto ignore_char;
+
+		if ((rsr & port->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((rsr & AMBA_UARTRSR_OE) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character
+			 */
+			*tty->flip.char_buf_ptr++ = 0;
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			tty->flip.count++;
+		}
+	ignore_char:
+		status = UART_GET_FR(port);
+	}
+	tty_flip_buffer_push(tty);
+	return;
+}
+
+static void ambauart_tx_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+	int count;
+
+	if (port->x_char) {
+		UART_PUT_CHAR(port, port->x_char);
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		ambauart_stop_tx(port);
+		return;
+	}
+
+	count = port->fifosize >> 1;
+	do {
+		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_event(port, EVT_WRITE_WAKEUP);
+
+	if (uart_circ_empty(xmit))
+		ambauart_stop_tx(port);
+}
+
+static void ambauart_modem_status(struct uart_port *port)
+{
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+	unsigned int status, delta;
+
+	UART_PUT_ICR(&uap->port, 0);
+
+	status = UART_GET_FR(&uap->port) & AMBA_UARTFR_MODEM_ANY;
+
+	delta = status ^ uap->old_status;
+	uap->old_status = status;
+
+	if (!delta)
+		return;
+
+	if (delta & AMBA_UARTFR_DCD)
+		uart_handle_dcd_change(&uap->port, status & AMBA_UARTFR_DCD);
+
+	if (delta & AMBA_UARTFR_DSR)
+		uap->port.icount.dsr++;
+
+	if (delta & AMBA_UARTFR_CTS)
+		uart_handle_cts_change(&uap->port, status & AMBA_UARTFR_CTS);
+
+	wake_up_interruptible(&uap->port.info->delta_msr_wait);
+}
+
+static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = dev_id;
+	unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
+
+	status = UART_GET_INT_STATUS(port);
+	do {
+		if (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS))
+#ifdef SUPPORT_SYSRQ
+			ambauart_rx_chars(port, regs);
+#else
+			ambauart_rx_chars(port);
+#endif
+		if (status & AMBA_UARTIIR_MIS)
+			ambauart_modem_status(port);
+		if (status & AMBA_UARTIIR_TIS)
+			ambauart_tx_chars(port);
+
+		if (pass_counter-- == 0)
+			break;
+
+		status = UART_GET_INT_STATUS(port);
+	} while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS |
+			   AMBA_UARTIIR_TIS));
+}
+
+static unsigned int ambauart_tx_empty(struct uart_port *port)
+{
+	return UART_GET_FR(port) & AMBA_UARTFR_BUSY ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int ambauart_get_mctrl(struct uart_port *port)
+{
+	unsigned int result = 0;
+	unsigned int status;
+
+	status = UART_GET_FR(port);
+	if (status & AMBA_UARTFR_DCD)
+		result |= TIOCM_CAR;
+	if (status & AMBA_UARTFR_DSR)
+		result |= TIOCM_DSR;
+	if (status & AMBA_UARTFR_CTS)
+		result |= TIOCM_CTS;
+
+	return result;
+}
+
+static void ambauart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+	unsigned int ctrls = 0, ctrlc = 0;
+
+	if (mctrl & TIOCM_RTS)
+		ctrlc |= uap->rts_mask;
+	else
+		ctrls |= uap->rts_mask;
+
+	if (mctrl & TIOCM_DTR)
+		ctrlc |= uap->dtr_mask;
+	else
+		ctrls |= uap->dtr_mask;
+
+	__raw_writel(ctrls, SC_CTRLS);
+	__raw_writel(ctrlc, SC_CTRLC);
+}
+
+static void ambauart_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+	unsigned int lcr_h;
+
+	spin_lock_irqsave(&port->lock, flags);
+	lcr_h = UART_GET_LCRH(port);
+	if (break_state == -1)
+		lcr_h |= AMBA_UARTLCR_H_BRK;
+	else
+		lcr_h &= ~AMBA_UARTLCR_H_BRK;
+	UART_PUT_LCRH(port, lcr_h);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int ambauart_startup(struct uart_port *port)
+{
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+	int retval;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(port->irq, ambauart_int, 0, "amba", port);
+	if (retval)
+		return retval;
+
+	/*
+	 * initialise the old status of the modem signals
+	 */
+	uap->old_status = UART_GET_FR(port) & AMBA_UARTFR_MODEM_ANY;
+
+	/*
+	 * Finally, enable interrupts
+	 */
+	UART_PUT_CR(port, AMBA_UARTCR_UARTEN | AMBA_UARTCR_RIE |
+			  AMBA_UARTCR_RTIE);
+
+	return 0;
+}
+
+static void ambauart_shutdown(struct uart_port *port)
+{
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(port->irq, port);
+
+	/*
+	 * disable all interrupts, disable the port
+	 */
+	UART_PUT_CR(port, 0);
+
+	/* disable break condition and fifos */
+	UART_PUT_LCRH(port, UART_GET_LCRH(port) &
+		~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN));
+}
+
+static void
+ambauart_change_speed(struct uart_port *port, unsigned int cflag,
+		      unsigned int iflag, unsigned int quot)
+{
+	unsigned int lcr_h, old_cr;
+	unsigned long flags;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5:
+		lcr_h = AMBA_UARTLCR_H_WLEN_5;
+		break;
+	case CS6:
+		lcr_h = AMBA_UARTLCR_H_WLEN_6;
+		break;
+	case CS7:
+		lcr_h = AMBA_UARTLCR_H_WLEN_7;
+		break;
+	default: // CS8
+		lcr_h = AMBA_UARTLCR_H_WLEN_8;
+		break;
+	}
+	if (cflag & CSTOPB)
+		lcr_h |= AMBA_UARTLCR_H_STP2;
+	if (cflag & PARENB) {
+		lcr_h |= AMBA_UARTLCR_H_PEN;
+		if (!(cflag & PARODD))
+			lcr_h |= AMBA_UARTLCR_H_EPS;
+	}
+	if (port->fifosize > 1)
+		lcr_h |= AMBA_UARTLCR_H_FEN;
+
+	port->read_status_mask = AMBA_UARTRSR_OE;
+	if (iflag & INPCK)
+		port->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
+	if (iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= AMBA_UARTRSR_BE;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
+	if (iflag & IGNBRK) {
+		port->ignore_status_mask |= AMBA_UARTRSR_BE;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= AMBA_UARTRSR_OE;
+	}
+
+	/*
+	 * Ignore all characters if CREAD is not set.
+	 */
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+
+	/* first, disable everything */
+	spin_lock_irqsave(&port->lock, flags);
+	old_cr = UART_GET_CR(port) & ~AMBA_UARTCR_MSIE;
+
+	if (UART_ENABLE_MS(port, cflag))
+		old_cr |= AMBA_UARTCR_MSIE;
+
+	UART_PUT_CR(port, 0);
+
+	/* Set baud rate */
+	quot -= 1;
+	UART_PUT_LCRM(port, ((quot & 0xf00) >> 8));
+	UART_PUT_LCRL(port, (quot & 0xff));
+
+	/*
+	 * ----------v----------v----------v----------v-----
+	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
+	 * ----------^----------^----------^----------^-----
+	 */
+	UART_PUT_LCRH(port, lcr_h);
+	UART_PUT_CR(port, old_cr);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *ambauart_type(struct uart_port *port)
+{
+	return port->type == PORT_AMBA ? "AMBA" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void ambauart_release_port(struct uart_port *port)
+{
+	release_mem_region(port->mapbase, UART_PORT_SIZE);
+}
+
+/*
+ * Request the memory region(s) being used by 'port'
+ */
+static int ambauart_request_port(struct uart_port *port)
+{
+	return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_amba")
+			!= NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void ambauart_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		port->type = PORT_AMBA;
+		ambauart_request_port(port);
+	}
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int ambauart_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
+		ret = -EINVAL;
+	if (ser->irq < 0 || ser->irq >= NR_IRQS)
+		ret = -EINVAL;
+	if (ser->baud_base < 9600)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops amba_pops = {
+	tx_empty:	ambauart_tx_empty,
+	set_mctrl:	ambauart_set_mctrl,
+	get_mctrl:	ambauart_get_mctrl,
+	stop_tx:	ambauart_stop_tx,
+	start_tx:	ambauart_start_tx,
+	stop_rx:	ambauart_stop_rx,
+	enable_ms:	ambauart_enable_ms,
+	break_ctl:	ambauart_break_ctl,
+	startup:	ambauart_startup,
+	shutdown:	ambauart_shutdown,
+	change_speed:	ambauart_change_speed,
+	type:		ambauart_type,
+	release_port:	ambauart_release_port,
+	request_port:	ambauart_request_port,
+	config_port:	ambauart_config_port,
+	verify_port:	ambauart_verify_port,
+};
+
+static struct uart_amba_port amba_ports[UART_NR] = {
+	{
+		port:	{
+			membase:	(void *)IO_ADDRESS(INTEGRATOR_UART0_BASE),
+			mapbase:	INTEGRATOR_UART0_BASE,
+			iotype:		SERIAL_IO_MEM,
+			irq:		IRQ_UARTINT0,
+			uartclk:	14745600,
+			fifosize:	16,
+			ops:		&amba_pops,
+			flags:		ASYNC_BOOT_AUTOCONF,
+			line:		0,
+		},
+		dtr_mask:	1 << 5,
+		rts_mask:	1 << 4,
+	},
+	{
+		port:	{
+			membase:	(void *)IO_ADDRESS(INTEGRATOR_UART1_BASE),
+			mapbase:	INTEGRATOR_UART1_BASE,
+			iotype:		SERIAL_IO_MEM,
+			irq:		IRQ_UARTINT1,
+			uartclk:	14745600,
+			fifosize:	16,
+			ops:		&amba_pops,
+			flags:		ASYNC_BOOT_AUTOCONF,
+			line:		1,
+		},
+		dtr_mask:	1 << 7,
+		rts_mask:	1 << 6,
+	}
+};
+
+#ifdef CONFIG_SERIAL_AMBA_CONSOLE
+
+static void
+ambauart_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct uart_port *port = &amba_ports[co->index].port;
+	unsigned int status, old_cr;
+	int i;
+
+	/*
+	 *	First save the CR then disable the interrupts
+	 */
+	old_cr = UART_GET_CR(port);
+	UART_PUT_CR(port, AMBA_UARTCR_UARTEN);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_FR(port);
+		} while (!UART_TX_READY(status));
+		UART_PUT_CHAR(port, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_FR(port);
+			} while (!UART_TX_READY(status));
+			UART_PUT_CHAR(port, '\r');
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the TCR
+	 */
+	do {
+		status = UART_GET_FR(port);
+	} while (status & AMBA_UARTFR_BUSY);
+	UART_PUT_CR(port, old_cr);
+}
+
+static kdev_t ambauart_console_device(struct console *co)
+{
+	return mk_kdev(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + co->index);
+}
+
+static void __init
+ambauart_console_get_options(struct uart_port *port, int *baud,
+			     int *parity, int *bits)
+{
+	if (UART_GET_CR(port) & AMBA_UARTCR_UARTEN) {
+		unsigned int lcr_h, quot;
+		lcr_h = UART_GET_LCRH(port);
+
+		*parity = 'n';
+		if (lcr_h & AMBA_UARTLCR_H_PEN) {
+			if (lcr_h & AMBA_UARTLCR_H_EPS)
+				*parity = 'e';
+			else
+				*parity = 'o';
+		}
+
+		if ((lcr_h & 0x60) == AMBA_UARTLCR_H_WLEN_7)
+			*bits = 7;
+		else
+			*bits = 8;
+
+		quot = UART_GET_LCRL(port) | UART_GET_LCRM(port) << 8;
+		*baud = port->uartclk / (16 * (quot + 1));
+	}
+}
+
+static int __init ambauart_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 38400;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= UART_NR)
+		co->index = 0;
+	port = &amba_ports[co->index].port;
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		ambauart_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console amba_console = {
+	name:		"ttyAM",
+	write:		ambauart_console_write,
+	device:		ambauart_console_device,
+	setup:		ambauart_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init ambauart_console_init(void)
+{
+	register_console(&amba_console);
+}
+
+#define AMBA_CONSOLE	&amba_console
+#else
+#define AMBA_CONSOLE	NULL
+#endif
+
+static struct uart_driver amba_reg = {
+	owner:			THIS_MODULE,
+	driver_name:		"ttyAM",
+#ifdef CONFIG_DEVFS_FS
+	dev_name:		"ttyAM%d",
+#else
+	dev_name:		"ttyAM",
+#endif
+	major:			SERIAL_AMBA_MAJOR,
+	minor:			SERIAL_AMBA_MINOR,
+	nr:			UART_NR,
+	cons:			AMBA_CONSOLE,
+};
+
+static int __init ambauart_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "Serial: AMBA driver $Revision: 1.37 $\n");
+
+	ret = uart_register_driver(&amba_reg);
+	if (ret == 0) {
+		int i;
+
+		for (i = 0; i < UART_NR; i++)
+			uart_add_one_port(&amba_reg, &amba_ports[i].port);
+	}
+	return ret;
+}
+
+static void __exit ambauart_exit(void)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++)
+		uart_remove_one_port(&amba_reg, &amba_ports[i].port);
+
+	uart_unregister_driver(&amba_reg);
+}
+
+module_init(ambauart_init);
+module_exit(ambauart_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
+MODULE_DESCRIPTION("ARM AMBA serial port driver $Revision: 1.37 $");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/serial/anakin.c b/drivers/serial/anakin.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/anakin.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,540 @@
+/*
+ *  linux/drivers/char/anakin.c
+ *
+ *  Based on driver for AMBA serial ports, by ARM Limited,
+ *  Deep Blue Solutions Ltd., Linus Torvalds and Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Aleph One Ltd. for Acunia N.V.
+ *
+ *  Copyright (C) 2001 Blue Mug, Inc. for Acunia N.V.
+ *
+ * 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.
+ *
+ *  Changelog:
+ *   20-Apr-2001 TTC	Created
+ *   05-May-2001 W/TTC	Updated for serial_core.c
+ *   27-Jun-2001 jonm	Minor changes; add mctrl support, switch to 
+ *   			SA_INTERRUPT. Works reliably now. No longer requires
+ *   			changes to the serial_core API.
+ *
+ *  $Id: anakin.c,v 1.29 2002/07/22 15:27:32 rmk Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.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/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#include <linux/serial_core.h>
+
+#include <asm/arch/serial_reg.h>
+
+#define UART_NR			5
+
+#define SERIAL_ANAKIN_NAME	"ttyAN"
+#define SERIAL_ANAKIN_MAJOR	204
+#define SERIAL_ANAKIN_MINOR	32
+
+static unsigned int txenable[NR_IRQS];		/* Software interrupt register */
+
+static inline unsigned int
+anakin_in(struct uart_port *port, unsigned int offset)
+{
+	return __raw_readl(port->base + offset);
+}
+
+static inline void
+anakin_out(struct uart_port *port, unsigned int offset, unsigned int value)
+{
+	__raw_writel(value, port->base + offset);
+}
+
+static void
+anakin_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	txenable[port->irq] = 0;
+}
+
+static inline void
+anakin_transmit_buffer(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+
+	while (!(anakin_in(port, 0x10) & TXEMPTY));
+	anakin_out(port, 0x14, xmit->buf[xmit->tail]);
+	anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
+	xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
+        port->icount.tx++;
+
+	if (uart_circ_empty(xmit))
+		anakin_stop_tx(port, 0); 
+}
+
+static inline void
+anakin_transmit_x_char(struct uart_port *port)
+{
+	anakin_out(port, 0x14, port->x_char);
+	anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
+	port->icount.tx++;
+	port->x_char = 0;
+}
+
+static void
+anakin_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	// is it this... or below
+	if (!txenable[port->irq]) {
+		txenable[port->irq] = TXENABLE;
+
+		if ((anakin_in(port, 0x10) & TXEMPTY)) {
+		    anakin_transmit_buffer(port);
+		}
+	}
+}
+
+static void
+anakin_stop_rx(struct uart_port *port)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	while (anakin_in(port, 0x10) & RXRELEASE) 
+	    anakin_in(port, 0x14);
+	anakin_out(port, 0x18, anakin_in(port, 0x18) | BLOCKRX);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void
+anakin_enable_ms(struct uart_port *port)
+{
+}
+
+static inline void
+anakin_rx_chars(struct uart_port *port)
+{
+	unsigned int ch;
+	struct tty_struct *tty = port->info->tty;
+
+	if (!(anakin_in(port, 0x10) & RXRELEASE))
+		return;
+
+	ch = anakin_in(port, 0x14) & 0xff;
+
+	if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+		*tty->flip.char_buf_ptr++ = ch;
+		*tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+		port->icount.rx++;
+		tty->flip.count++;
+	} 
+	tty_flip_buffer_push(tty);
+}
+
+static inline void
+anakin_overrun_chars(struct uart_port *port)
+{
+	unsigned int ch;
+
+	ch = anakin_in(port, 0x14);
+	port->icount.overrun++;
+}
+
+static inline void
+anakin_tx_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+
+	if (port->x_char) {
+		anakin_transmit_x_char(port);
+		return; 
+	}
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		anakin_stop_tx(port, 0);
+		return;
+	}
+
+	anakin_transmit_buffer(port);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_event(port, EVT_WRITE_WAKEUP);
+}
+
+static void
+anakin_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int status;
+	struct uart_port *port = dev_id;
+
+	status = anakin_in(port, 0x1c);
+
+	if (status & RX) 
+		anakin_rx_chars(port);
+
+	if (status & OVERRUN) 
+		anakin_overrun_chars(port);
+
+	if (txenable[port->irq] && (status & TX)) 
+		anakin_tx_chars(port);
+}
+
+static unsigned int
+anakin_tx_empty(struct uart_port *port)
+{
+	return anakin_in(port, 0x10) & TXEMPTY ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int
+anakin_get_mctrl(struct uart_port *port)
+{
+	unsigned int status = 0;
+
+	status |= (anakin_in(port, 0x10) & CTS ? TIOCM_CTS : 0);
+	status |= (anakin_in(port, 0x18) & DCD ? TIOCM_CAR : 0);
+	status |= (anakin_in(port, 0x18) & DTR ? TIOCM_DTR : 0);
+	status |= (anakin_in(port, 0x18) & RTS ? TIOCM_RTS : 0);
+	
+	return status;
+}
+
+static void
+anakin_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	unsigned int status;
+
+	status = anakin_in(port, 0x18);
+
+	if (mctrl & TIOCM_RTS) 
+		status |= RTS;
+	else 
+		status &= ~RTS;
+
+	if (mctrl & TIOCM_CAR)
+		status |= DCD;
+	else 
+		status &= ~DCD;
+
+	anakin_out(port, 0x18, status);
+}
+
+static void
+anakin_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+	unsigned int status;
+
+	spin_lock_irqsave(&port->lock, flags);
+	status = anakin_in(port, 0x20);
+
+	if (break_state == -1)
+		status |= SETBREAK;
+	else
+		status &= ~SETBREAK;
+
+	anakin_out(port, 0x20, status);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int anakin_startup(struct uart_port *port)
+{
+	int retval;
+	unsigned int read,write;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(port->irq, anakin_int, SA_INTERRUPT,
+			     "serial_anakin", port);
+	if (retval)
+		return retval;
+
+	/*
+	 * initialise the old status of the modem signals
+	 */
+	port->old_status = 0;
+
+	/*
+	 * Finally, disable IRQ and softIRQs for first byte)
+	 */
+	txenable[port->irq] = 0;
+	read = anakin_in(port, 0x18);
+	write = (read & ~(RTS | DTR | BLOCKRX)) | IRQENABLE;
+	anakin_out(port, 0x18, write);
+
+	return 0;
+}
+
+static void anakin_shutdown(struct uart_port *port)
+{
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(port->irq, port);
+
+	/*
+	 * disable all interrupts, disable the port
+	 */
+	anakin_out(port, 0x18, anakin_in(port, 0x18) & ~IRQENABLE);
+}
+
+static void
+anakin_change_speed(struct uart_port *port, unsigned int cflag,
+		    unsigned int iflag, unsigned int quot)
+{
+	unsigned int flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	while (!(anakin_in(port, 0x10) & TXEMPTY));
+	anakin_out(port, 0x10, (anakin_in(port, 0x10) & ~PRESCALER)
+			| (quot << 3));
+
+	//parity always set to none
+	anakin_out(port, 0x18, anakin_in(port, 0x18) & ~PARITY);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *anakin_type(struct port *port)
+{
+	return port->type == PORT_ANAKIN ? "ANAKIN" : NULL;
+}
+
+static struct uart_ops anakin_pops = {
+	tx_empty:	anakin_tx_empty,
+	set_mctrl:	anakin_set_mctrl,
+	get_mctrl:	anakin_get_mctrl,
+	stop_tx:	anakin_stop_tx,
+	start_tx:	anakin_start_tx,
+	stop_rx:	anakin_stop_rx,
+	enable_ms:	anakin_enable_ms,
+	break_ctl:	anakin_break_ctl,
+	startup:	anakin_startup,
+	shutdown:	anakin_shutdown,
+	change_speed:	anakin_change_speed,
+	type:		anakin_type,
+};
+
+static struct uart_port anakin_ports[UART_NR] = {
+	{
+		base:		IO_BASE + UART0,
+		irq:		IRQ_UART0,
+		uartclk:	3686400,
+		fifosize:	0,
+		ops:		&anakin_pops,
+		flags:		ASYNC_BOOT_AUTOCONF,
+		line:		0,
+	},
+	{
+		base:		IO_BASE + UART1,
+		irq:		IRQ_UART1,
+		uartclk:	3686400,
+		fifosize:	0,
+		ops:		&anakin_pops,
+		flags:		ASYNC_BOOT_AUTOCONF,
+		line:		1,
+	},
+	{
+		base:		IO_BASE + UART2,
+		irq:		IRQ_UART2,
+		uartclk:	3686400,
+		fifosize:	0,
+		ops:		&anakin_pops,
+		flags:		ASYNC_BOOT_AUTOCONF,
+		line:		2,
+	},
+	{
+		base:		IO_BASE + UART3,
+		irq:		IRQ_UART3,
+		uartclk:	3686400,
+		fifosize:	0,
+		ops:		&anakin_pops,
+		flags:		ASYNC_BOOT_AUTOCONF,
+		line:		3,
+	},
+	{
+		base:		IO_BASE + UART4,
+		irq:		IRQ_UART4,
+		uartclk:	3686400,
+		fifosize:	0,
+		ops:		&anakin_pops,
+		flags:		ASYNC_BOOT_AUTOCONF,
+		line:		4,
+	},
+};
+
+
+#ifdef CONFIG_SERIAL_ANAKIN_CONSOLE
+
+static void
+anakin_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct uart_port *port = &anakin_ports[co->index];
+	unsigned int flags, status, i;
+
+	/*
+	 *	First save the status then disable the interrupts
+	 */
+	local_irq_save(flags);
+	status = anakin_in(port, 0x18);
+	anakin_out(port, 0x18, status & ~IRQENABLE);
+	local_irq_restore(flags);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		while (!(anakin_in(port, 0x10) & TXEMPTY));
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		anakin_out(port, 0x14, *s);
+		anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
+
+		if (*s == 10) {
+			while (!(anakin_in(port, 0x10) & TXEMPTY));
+			anakin_out(port, 0x14, 13);
+			anakin_out(port, 0x18, anakin_in(port, 0x18)
+					| SENDREQUEST);
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the interrupts
+	 */
+	while (!(anakin_in(port, 0x10) & TXEMPTY));
+
+	if (status & IRQENABLE) {
+		local_irq_save(flags);
+ 		anakin_out(port, 0x18, anakin_in(port, 0x18) | IRQENABLE);
+		local_irq_restore(flags);
+	}
+}
+
+static kdev_t
+anakin_console_device(struct console *co)
+{
+	return mk_kdev(SERIAL_ANAKIN_MAJOR, SERIAL_ANAKIN_MINOR + co->index);
+}
+
+/*
+ * Read the current UART setup.
+ */
+static void __init
+anakin_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+	int paritycode;
+
+	*baud = GETBAUD (anakin_in(port, 0x10) & PRESCALER);
+	paritycode = GETPARITY(anakin_in(port, 0x18) & PARITY);
+	switch (paritycode) {
+	  case NONEPARITY: *parity = 'n'; break;
+	  case ODDPARITY: *parity = 'o'; break;
+	  case EVENPARITY: *parity = 'e'; break;
+	}
+	*bits = 8;
+}
+
+static int __init
+anakin_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = CONFIG_ANAKIN_DEFAULT_BAUDRATE;
+	int bits = 8;
+	int parity = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= UART_NR)
+		co->index = 0;
+	port = &anakin_ports[co->index];
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits);
+	else
+		anakin_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits);
+}
+
+static struct console anakin_console = {
+	name:		SERIAL_ANAKIN_NAME,
+	write:		anakin_console_write,
+	device:		anakin_console_device,
+	setup:		anakin_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init
+anakin_console_init(void)
+{
+	register_console(&anakin_console);
+}
+
+#define ANAKIN_CONSOLE		&anakin_console
+#else
+#define ANAKIN_CONSOLE		NULL
+#endif
+
+static struct uart_register anakin_reg = {
+	driver_name:		SERIAL_ANAKIN_NAME,
+	dev_name:		SERIAL_ANAKIN_NAME,
+	major:			SERIAL_ANAKIN_MAJOR,
+	minor:			SERIAL_ANAKIN_MINOR,
+	nr:			UART_NR,
+	cons:			ANAKIN_CONSOLE,
+};
+
+static int __init
+anakin_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "Serial: Anakin driver $Revision: 1.29 $\n");
+
+	ret = uart_register_driver(&anakin_reg);
+	if (ret == 0) {
+		int i;
+
+		for (i = 0; i < UART_NR; i++)
+			uart_add_one_port(&anakin_reg, &anakin_ports[i]);
+	}
+	return ret;
+}
+
+__initcall(anakin_init);
+
+MODULE_DESCRIPTION("Anakin serial driver");
+MODULE_AUTHOR("Tak-Shing Chan <chan@aleph1.co.uk>");
+MODULE_SUPPORTED_DEVICE("ttyAN");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
diff -Nru a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/clps711x.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,629 @@
+/*
+ *  linux/drivers/char/clps711x.c
+ *
+ *  Driver for CLPS711x serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright 1999 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
+ *
+ *  $Id: clps711x.c,v 1.40 2002/07/22 15:27:32 rmk Exp $
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.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/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/spinlock.h>
+
+#include <asm/bitops.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#include <asm/hardware/clps7111.h>
+
+#define UART_NR		2
+
+#ifndef CONFIG_SERIAL_CLPS711X_OLD_NAME
+#define SERIAL_CLPS711X_NAME	"ttyCL"
+#define SERIAL_CLPS711X_MAJOR	204
+#define SERIAL_CLPS711X_MINOR	40
+#define SERIAL_CLPS711X_NR	UART_NR
+
+#else
+#warning The old names/device number for this driver if compatabity is needed
+#define SERIAL_CLPS711X_NAME    "ttyAM"
+#define SERIAL_CLPS711X_MAJOR   204
+#define SERIAL_CLPS711X_MINOR   16
+#define SERIAL_CLPS711X_NR      UART_NR
+
+#endif
+
+/*
+ * We use the relevant SYSCON register as a base address for these ports.
+ */
+#define UBRLCR(port)		((port)->iobase + UBRLCR1 - SYSCON1)
+#define UARTDR(port)		((port)->iobase + UARTDR1 - SYSCON1)
+#define SYSFLG(port)		((port)->iobase + SYSFLG1 - SYSCON1)
+#define SYSCON(port)		((port)->iobase + SYSCON1 - SYSCON1)
+
+#define TX_IRQ(port)		((port)->irq)
+#define RX_IRQ(port)		((port)->irq + 1)
+
+#define UART_ANY_ERR		(UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR)
+
+#define tx_enabled(port)	((port)->unused[0])
+
+static void
+clps711xuart_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	if (tx_enabled(port)) {
+		disable_irq(TX_IRQ(port));
+		tx_enabled(port) = 0;
+	}
+}
+
+static void
+clps711xuart_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	if (!tx_enabled(port)) {
+		enable_irq(TX_IRQ(port));
+		tx_enabled(port) = 1;
+	}
+}
+
+static void clps711xuart_stop_rx(struct uart_port *port)
+{
+	disable_irq(RX_IRQ(port));
+}
+
+static void clps711xuart_enable_ms(struct uart_port *port)
+{
+}
+
+static void 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;
+	unsigned int status, ch, flg, ignored = 0;
+
+	status = clps_readl(SYSFLG(port));
+	while (!(status & SYSFLG_URXFE)) {
+		ch = clps_readl(UARTDR(port));
+
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		port->icount.rx++;
+
+		flg = TTY_NORMAL;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		if (ch & UART_ANY_ERR)
+			goto handle_error;
+
+		if (uart_handle_sysrq_char(port, ch, regs))
+			goto ignore_char;
+
+	error_return:
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+	ignore_char:
+		status = clps_readl(SYSFLG(port));
+	}
+ out:
+	tty_flip_buffer_push(tty);
+	return;
+
+ handle_error:
+	if (ch & UARTDR_PARERR)
+		port->icount.parity++;
+	else if (ch & UARTDR_FRMERR)
+		port->icount.frame++;
+	if (ch & UARTDR_OVERR)
+		port->icount.overrun++;
+
+	if (ch & port->ignore_status_mask) {
+		if (++ignored > 100)
+			goto out;
+		goto ignore_char;
+	}
+	ch &= port->read_status_mask;
+
+	if (ch & UARTDR_PARERR)
+		flg = TTY_PARITY;
+	else if (ch & UARTDR_FRMERR)
+		flg = TTY_FRAME;
+
+	if (ch & UARTDR_OVERR) {
+		/*
+		 * CHECK: does overrun affect the current character?
+		 * ASSUMPTION: it does not.
+		 */
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		ch = 0;
+		flg = TTY_OVERRUN;
+	}
+#ifdef SUPPORT_SYSRQ
+	port->sysrq = 0;
+#endif
+	goto error_return;
+}
+
+static void 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;
+	int count;
+
+	if (port->x_char) {
+		clps_writel(port->x_char, UARTDR(port));
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		clps711xuart_stop_tx(port);
+		return;
+	}
+
+	count = port->fifosize >> 1;
+	do {
+		clps_writel(xmit->buf[xmit->tail], UARTDR(port));
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_event(port, EVT_WRITE_WAKEUP);
+
+	if (uart_circ_empty(xmit))
+		clps711xuart_stop_tx(port);
+}
+
+static unsigned int clps711xuart_tx_empty(struct uart_port *port)
+{
+	unsigned int status = clps_readl(SYSFLG(port));
+	return status & SYSFLG_UBUSY ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int clps711xuart_get_mctrl(struct uart_port *port)
+{
+	unsigned int port_addr;
+	unsigned int result = 0;
+	unsigned int status;
+
+	port_addr = SYSFLG(port);
+	if (port_addr == SYSFLG1) {
+		status = clps_readl(SYSFLG1);
+		if (status & SYSFLG1_DCD)
+			result |= TIOCM_CAR;
+		if (status & SYSFLG1_DSR)
+			result |= TIOCM_DSR;
+		if (status & SYSFLG1_CTS)
+			result |= TIOCM_CTS;
+	}
+
+	return result;
+}
+
+static void
+clps711xuart_set_mctrl_null(struct uart_port *port, unsigned int mctrl)
+{
+}
+
+static void clps711xuart_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+	unsigned int ubrlcr;
+
+	spin_lock_irqsave(&port->lock, flags);
+	ubrlcr = clps_readl(UBRLCR(port));
+	if (break_state == -1)
+		ubrlcr |= UBRLCR_BREAK;
+	else
+		ubrlcr &= ~UBRLCR_BREAK;
+	clps_writel(ubrlcr, UBRLCR(port));
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int clps711xuart_startup(struct uart_port *port)
+{
+	unsigned int syscon;
+	int retval;
+
+	tx_enabled(port) = 1;
+
+	/*
+	 * Allocate the IRQs
+	 */
+	retval = request_irq(TX_IRQ(port), clps711xuart_int_tx, 0,
+			     "clps711xuart_tx", port);
+	if (retval)
+		return retval;
+
+	retval = request_irq(RX_IRQ(port), clps711xuart_int_rx, 0,
+			     "clps711xuart_rx", port);
+	if (retval) {
+		free_irq(TX_IRQ(port), port);
+		return retval;
+	}
+
+	/*
+	 * enable the port
+	 */
+	syscon = clps_readl(SYSCON(port));
+	syscon |= SYSCON_UARTEN;
+	clps_writel(syscon, SYSCON(port));
+
+	return 0;
+}
+
+static void clps711xuart_shutdown(struct uart_port *port)
+{
+	unsigned int ubrlcr, syscon;
+
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(TX_IRQ(port), port);	/* TX interrupt */
+	free_irq(RX_IRQ(port), port);	/* RX interrupt */
+
+	/*
+	 * disable the port
+	 */
+	syscon = clps_readl(SYSCON(port));
+	syscon &= ~SYSCON_UARTEN;
+	clps_writel(syscon, SYSCON(port));
+
+	/*
+	 * disable break condition and fifos
+	 */
+	ubrlcr = clps_readl(UBRLCR(port));
+	ubrlcr &= ~(UBRLCR_FIFOEN | UBRLCR_BREAK);
+	clps_writel(ubrlcr, UBRLCR(port));
+}
+
+static void
+clps711xuart_change_speed(struct uart_port *port, unsigned int cflag,
+			  unsigned int iflag, unsigned int quot)
+{
+	unsigned int ubrlcr;
+	unsigned long flags;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5:
+		ubrlcr = UBRLCR_WRDLEN5;
+		break;
+	case CS6:
+		ubrlcr = UBRLCR_WRDLEN6;
+		break;
+	case CS7:
+		ubrlcr = UBRLCR_WRDLEN7;
+		break;
+	default: // CS8
+		ubrlcr = UBRLCR_WRDLEN8;
+		break;
+	}
+	if (cflag & CSTOPB)
+		ubrlcr |= UBRLCR_XSTOP;
+	if (cflag & PARENB) {
+		ubrlcr |= UBRLCR_PRTEN;
+		if (!(cflag & PARODD))
+			ubrlcr |= UBRLCR_EVENPRT;
+	}
+	if (port->fifosize > 1)
+		ubrlcr |= UBRLCR_FIFOEN;
+
+	port->read_status_mask = UARTDR_OVERR;
+	if (iflag & INPCK)
+		port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= UARTDR_FRMERR | UARTDR_PARERR;
+	if (iflag & IGNBRK) {
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns to (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= UARTDR_OVERR;
+	}
+
+	quot -= 1;
+
+	/* first, disable everything */
+	spin_lock_irqsave(&port->lock, flags);
+
+	clps_writel(ubrlcr | quot, UBRLCR(port));
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *clps711xuart_type(struct uart_port *port)
+{
+	return port->type == PORT_CLPS711X ? "CLPS711x" : NULL;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void clps711xuart_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE)
+		port->type = PORT_CLPS711X;
+}
+
+static void clps711xuart_release_port(struct uart_port *port)
+{
+}
+
+static int clps711xuart_request_port(struct uart_port *port)
+{
+	return 0;
+}
+
+static struct uart_ops clps711x_pops = {
+	tx_empty:	clps711xuart_tx_empty,
+	set_mctrl:	clps711xuart_set_mctrl_null,
+	get_mctrl:	clps711xuart_get_mctrl,
+	stop_tx:	clps711xuart_stop_tx,
+	start_tx:	clps711xuart_start_tx,
+	stop_rx:	clps711xuart_stop_rx,
+	enable_ms:	clps711xuart_enable_ms,
+	break_ctl:	clps711xuart_break_ctl,
+	startup:	clps711xuart_startup,
+	shutdown:	clps711xuart_shutdown,
+	change_speed:	clps711xuart_change_speed,
+	type:		clps711xuart_type,
+	config_port:	clps711xuart_config_port,
+	release_port:	clps711xuart_release_port,
+	request_port:	clps711xuart_request_port,
+};
+
+static struct uart_port clps711x_ports[UART_NR] = {
+	{
+		iobase:		SYSCON1,
+		irq:		IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */
+		uartclk:	3686400,
+		fifosize:	16,
+		ops:		&clps711x_pops,
+		flags:		ASYNC_BOOT_AUTOCONF,
+	},
+	{
+		iobase:		SYSCON2,
+		irq:		IRQ_UTXINT2, /* IRQ_URXINT2 */
+		uartclk:	3686400,
+		fifosize:	16,
+		ops:		&clps711x_pops,
+		flags:		ASYNC_BOOT_AUTOCONF,
+	}
+};
+
+#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ *
+ *	Note that this is called with interrupts already disabled
+ */
+static void
+clps711xuart_console_write(struct console *co, const char *s,
+			   unsigned int count)
+{
+	struct uart_port *port = clps711x_ports + co->index;
+	unsigned int status, syscon;
+	int i;
+
+	/*
+	 *	Ensure that the port is enabled.
+	 */
+	syscon = clps_readl(SYSCON(port));
+	clps_writel(syscon | SYSCON_UARTEN, SYSCON(port));
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = clps_readl(SYSFLG(port));
+		} while (status & SYSFLG_UTXFF);
+		clps_writel(s[i], UARTDR(port));
+		if (s[i] == '\n') {
+			do {
+				status = clps_readl(SYSFLG(port));
+			} while (status & SYSFLG_UTXFF);
+			clps_writel('\r', UARTDR(port));
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the uart state.
+	 */
+	do {
+		status = clps_readl(SYSFLG(port));
+	} while (status & SYSFLG_UBUSY);
+
+	clps_writel(syscon, SYSCON(port));
+}
+
+static kdev_t clps711xuart_console_device(struct console *co)
+{
+	return mk_kdev(SERIAL_CLPS711X_MAJOR, SERIAL_CLPS711X_MINOR + co->index);
+}
+
+static void __init
+clps711xuart_console_get_options(struct uart_port *port, int *baud,
+				 int *parity, int *bits)
+{
+	if (clps_readl(SYSCON(port)) & SYSCON_UARTEN) {
+		unsigned int ubrlcr, quot;
+
+		ubrlcr = clps_readl(UBRLCR(port));
+
+		*parity = 'n';
+		if (ubrlcr & UBRLCR_PRTEN) {
+			if (ubrlcr & UBRLCR_EVENPRT)
+				*parity = 'e';
+			else
+				*parity = 'o';
+		}
+
+		if ((ubrlcr & UBRLCR_WRDLEN_MASK) == UBRLCR_WRDLEN7)
+			*bits = 7;
+		else
+			*bits = 8;
+
+		quot = ubrlcr & UBRLCR_BAUD_MASK;
+		*baud = port->uartclk / (16 * (quot + 1));
+	}
+}
+
+static int __init clps711xuart_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 38400;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	port = uart_get_console(clps711x_ports, UART_NR, co);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		clps711xuart_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console clps711x_console = {
+	name:		SERIAL_CLPS711X_NAME,
+	write:		clps711xuart_console_write,
+	device:		clps711xuart_console_device,
+	setup:		clps711xuart_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init clps711xuart_console_init(void)
+{
+	register_console(&clps711x_console);
+}
+
+#define CLPS711X_CONSOLE	&clps711x_console
+#else
+#define CLPS711X_CONSOLE	NULL
+#endif
+
+static struct uart_driver clps711x_reg = {
+	driver_name:		"ttyCL",
+#ifdef CONFIG_DEVFS_FS
+	dev_name:		SERIAL_CLPS711X_NAME,
+#else
+	dev_name:		SERIAL_CLPS711X_NAME,
+#endif
+
+	major:			SERIAL_CLPS711X_MAJOR,
+	minor:			SERIAL_CLPS711X_MINOR,
+	nr:			UART_NR,
+
+	cons:			CLPS711X_CONSOLE,
+};
+
+static int __init clps711xuart_init(void)
+{
+	int ret, i;
+
+	printk(KERN_INFO "Serial: CLPS711x driver $Revision: 1.40 $\n");
+
+	ret = uart_register_driver(&clps711x_reg);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < UART_NR; i++)
+		uart_add_one_port(&clps711x_reg, &clps711x_ports[i]);
+
+	return 0;
+}
+
+static void __exit clps711xuart_exit(void)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++)
+		uart_remove_one_port(&clps711x_reg, &clps711x_ports[i]);
+
+	uart_unregister_driver(&clps711x_reg);
+}
+
+module_init(clps711xuart_init);
+module_exit(clps711xuart_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("Deep Blue Solutions Ltd");
+MODULE_DESCRIPTION("CLPS-711x generic serial driver $Revision: 1.40 $");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/serial/core.c b/drivers/serial/core.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/core.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,2474 @@
+/*
+ *  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
+ *
+ *  $Id: core.c,v 1.91 2002/07/22 15:27:32 rmk Exp $
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.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/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/pm.h>
+#include <linux/serial_core.h>
+#include <linux/smp_lock.h>
+#include <linux/serial.h> /* for serial_state and serial_icounter_struct */
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#undef	DEBUG
+#ifdef DEBUG
+#define DPRINTK(x...)	printk(x)
+#else
+#define DPRINTK(x...)	do { } while (0)
+#endif
+
+#ifndef CONFIG_PM
+#define pm_access(pm)		do { } while (0)
+#define pm_unregister(pm)	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)
+
+static void uart_change_speed(struct uart_info *info, struct termios *old_termios);
+static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
+
+/*
+ * This routine is used by the interrupt handler to schedule processing in
+ * the software interrupt portion of the driver.
+ */
+void uart_event(struct uart_port *port, int event)
+{
+	struct uart_info *info = port->info;
+
+	set_bit(0, &info->event);
+	tasklet_schedule(&info->tlet);
+}
+
+static void uart_stop(struct tty_struct *tty)
+{
+	struct uart_info *info = tty->driver_data;
+	struct uart_port *port = info->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_info *info = tty->driver_data;
+	struct uart_port *port = info->port;
+
+	if (!uart_circ_empty(&info->xmit) && info->xmit.buf &&
+	    !tty->stopped && !tty->hw_stopped)
+		port->ops->start_tx(port, 1);
+}
+
+static void uart_start(struct tty_struct *tty)
+{
+	struct uart_info *info = tty->driver_data;
+	unsigned long flags;
+
+	pm_access(info->state->pm);
+
+	spin_lock_irqsave(&info->port->lock, flags);
+	__uart_start(tty);
+	spin_unlock_irqrestore(&info->port->lock, flags);
+}
+
+static void uart_tasklet_action(unsigned long data)
+{
+	struct uart_info *info = (struct uart_info *)data;
+	struct tty_struct *tty;
+
+	tty = info->tty;
+	if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event))
+		return;
+
+	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)
+
+static inline void uart_update_altspeed(struct uart_info *info)
+{
+	unsigned int flags = info->port->flags & UPF_SPD_MASK;
+
+	if (flags == UPF_SPD_HI)
+		info->tty->alt_speed = 57600;
+	if (flags == UPF_SPD_VHI)
+		info->tty->alt_speed = 115200;
+	if (flags == UPF_SPD_SHI)
+		info->tty->alt_speed = 230400;
+	if (flags == UPF_SPD_WARP)
+		info->tty->alt_speed = 460800;
+}
+
+/*
+ * Startup the port.  This will be called once per open.  All calls
+ * will be serialised by the global port semaphore.
+ */
+static int uart_startup(struct uart_info *info, int init_hw)
+{
+	struct uart_port *port = info->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);
+		uart_update_altspeed(info);
+	}
+
+	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(info, 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;
+
+		if (info->tty)
+			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 port_sem.
+ */
+static void uart_shutdown(struct uart_info *info)
+{
+	struct uart_port *port = info->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(info->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;
+}
+
+static inline
+unsigned int uart_calculate_quot(struct uart_info *info, unsigned int baud)
+{
+	struct uart_port *port = info->port;
+	unsigned int quot;
+
+	/* Special case: B0 rate */
+	if (baud == 0)
+		baud = 9600;
+
+	/* Old HI/VHI/custom speed handling */
+	if (baud == 38400 &&
+	    ((port->flags & UPF_SPD_MASK) == UPF_SPD_CUST))
+		quot = info->state->custom_divisor;
+	else
+		quot = port->uartclk / (16 * baud);
+
+	return quot;
+}
+
+static void
+uart_change_speed(struct uart_info *info, struct termios *old_termios)
+{
+	struct uart_port *port = info->port;
+	unsigned int quot, cflag, bits, try;
+
+	/*
+	 * If we have no tty, termios, or the port does not exist,
+	 * then we can't set the parameters for this port.
+	 */
+	if (!info->tty || !info->tty->termios || port->type == PORT_UNKNOWN)
+		return;
+
+	/*
+	 * Set flags based on termios cflag
+	 */
+	cflag = info->tty->termios->c_cflag;
+
+	/* 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++;
+
+	for (try = 0; try < 3; try ++) {
+		unsigned int baud;
+
+		/* Determine divisor based on baud rate */
+		baud = tty_get_baud_rate(info->tty);
+		quot = uart_calculate_quot(info, baud);
+		if (quot)
+			break;
+
+		/*
+		 * Oops, the quotient was zero.  Try again with
+		 * the old baud rate if possible.
+		 */
+		info->tty->termios->c_cflag &= ~CBAUD;
+		if (old_termios) {
+			info->tty->termios->c_cflag |=
+				 (old_termios->c_cflag & CBAUD);
+			old_termios = NULL;
+			continue;
+		}
+
+		/*
+		 * As a last resort, if the quotient is zero,
+		 * default to 9600 bps
+		 */
+		info->tty->termios->c_cflag |= B9600;
+	}
+
+	/*
+	 * 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) / (port->uartclk / (16 * quot)) + HZ/50;
+
+	if (cflag & CRTSCTS)
+		info->flags |= UIF_CTS_FLOW;
+	else
+		info->flags &= ~UIF_CTS_FLOW;
+	if (cflag & CLOCAL)
+		info->flags &= ~UIF_CHECK_CD;
+	else
+		info->flags |= UIF_CHECK_CD;
+
+	port->ops->change_speed(port, cflag, info->tty->termios->c_iflag, quot);
+}
+
+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_info *info = tty->driver_data;
+
+	if (tty)
+		__uart_put_char(info->port, &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_info *info = tty->driver_data;
+	int ret;
+
+	if (!tty || !info->xmit.buf)
+		return 0;
+
+	if (from_user)
+		ret = __uart_user_write(info->port, &info->xmit, buf, count);
+	else
+		ret = __uart_kern_write(info->port, &info->xmit, buf, count);
+
+	uart_start(tty);
+	return ret;
+}
+
+static int uart_write_room(struct tty_struct *tty)
+{
+	struct uart_info *info = tty->driver_data;
+
+	return uart_circ_chars_free(&info->xmit);
+}
+
+static int uart_chars_in_buffer(struct tty_struct *tty)
+{
+	struct uart_info *info = tty->driver_data;
+
+	return uart_circ_chars_pending(&info->xmit);
+}
+
+static void uart_flush_buffer(struct tty_struct *tty)
+{
+	struct uart_info *info = tty->driver_data;
+	unsigned long flags;
+
+	DPRINTK("uart_flush_buffer(%d) called\n",
+	        MINOR(tty->device) - tty->driver.minor_start);
+
+	spin_lock_irqsave(&info->port->lock, flags);
+	uart_circ_clear(&info->xmit);
+	spin_unlock_irqrestore(&info->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_info *info = tty->driver_data;
+	struct uart_port *port = info->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_info *info = tty->driver_data;
+
+	if (I_IXOFF(tty))
+		uart_send_xchar(tty, STOP_CHAR(tty));
+
+	if (tty->termios->c_cflag & CRTSCTS)
+		uart_clear_mctrl(info->port, TIOCM_RTS);
+}
+
+static void uart_unthrottle(struct tty_struct *tty)
+{
+	struct uart_info *info = tty->driver_data;
+	struct uart_port *port = info->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_info *info, struct serial_struct *retinfo)
+{
+	struct uart_state *state = info->state;
+	struct uart_port *port = info->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 = port->iobase >> HIGH_BITS_OFFSET;
+	tmp.irq		    = port->irq;
+	tmp.flags	    = port->flags | info->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  = state->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_info *info, struct serial_struct *newinfo)
+{
+	struct serial_struct new_serial;
+	struct uart_state *state = info->state;
+	struct uart_port *port = info->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_cannonicalize(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(&port_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 = state->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));
+		state->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 (state->count > 1 || info->blocked_open != 0)
+			goto exit;
+
+		/*
+		 * We need to shutdown the serial port at the old
+		 * port/type/irq combination.
+		 */
+		uart_shutdown(info);
+	}
+
+	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);
+
+		/*
+		 * 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            = new_serial.flags & UPF_FLAGS;
+	state->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;
+	info->tty->low_latency = (port->flags & UPF_LOW_LATENCY) ? 1 : 0;
+
+ check_and_exit:
+	retval = 0;
+	if (port->type == PORT_UNKNOWN)
+		goto exit;
+	if (info->flags & UIF_INITIALIZED) {
+		if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
+		    old_custom_divisor != state->custom_divisor) {
+			uart_update_altspeed(info);
+			uart_change_speed(info, NULL);
+		}
+	} else
+		retval = uart_startup(info, 1);
+ exit:
+	up(&port_sem);
+	return retval;
+}
+
+
+/*
+ * uart_get_lsr_info - get line status register info
+ */
+static int uart_get_lsr_info(struct uart_info *info, unsigned int *value)
+{
+	struct uart_port *port = info->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 (info->port->x_char ||
+	    ((uart_circ_chars_pending(&info->xmit) > 0) &&
+	     !info->tty->stopped && !info->tty->hw_stopped))
+		result &= ~TIOCSER_TEMT;
+	
+	return put_user(result, value);
+}
+
+static int uart_get_modem_info(struct uart_port *port, unsigned int *value)
+{
+	unsigned int result = port->mctrl;
+
+	result |= port->ops->get_mctrl(port);
+
+	return put_user(result, value);
+}
+
+static int
+uart_set_modem_info(struct uart_port *port, unsigned int cmd,
+		    unsigned int *value)
+{
+	unsigned int arg, set, clear;
+	int ret = 0;
+
+	if (get_user(arg, value))
+		return -EFAULT;
+
+	set = clear = 0;
+	switch (cmd) {
+	case TIOCMBIS:
+		set = arg;
+		break;
+	case TIOCMBIC:
+		clear = arg;
+		break;
+	case TIOCMSET:
+		set = arg;
+		clear = ~arg;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	if (ret == 0)
+		uart_update_mctrl(port, set, clear);
+	return ret;
+}
+
+static void uart_break_ctl(struct tty_struct *tty, int break_state)
+{
+	struct uart_info *info = tty->driver_data;
+	struct uart_port *port = info->port;
+
+	BUG_ON(!kernel_locked());
+
+	if (port->type != PORT_UNKNOWN)
+		port->ops->break_ctl(port, break_state);
+}
+
+static int uart_do_autoconfig(struct uart_info *info)
+{
+	struct uart_port *port = info->port;
+	int flags, ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	/*
+	 * Take the 'count' lock.  This prevents count
+	 * from incrementing, and hence any extra opens
+	 * of the port while we're auto-configging.
+	 */
+	if (down_interruptible(&port_sem))
+		return -ERESTARTSYS;
+
+	ret = -EBUSY;
+	if (info->state->count == 1 && info->blocked_open == 0) {
+		uart_shutdown(info);
+
+		/*
+		 * 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(info, 1);
+	}
+	up(&port_sem);
+	return ret;
+}
+
+static int
+uart_wait_modem_status(struct uart_info *info, unsigned long arg)
+{
+	struct uart_port *port = info->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));
+	spin_unlock_irq(&port->lock);
+
+	/*
+	 * Force modem status interrupts on
+	 */
+	port->ops->enable_ms(port);
+
+	add_wait_queue(&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(&info->delta_msr_wait, &wait);
+
+	return ret;
+}
+
+/*
+ * Called via sys_ioctl under the BKL.  We can use spin_lock_irq() here.
+ */
+static int
+uart_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd,
+	   unsigned long arg)
+{
+	struct uart_info *info = tty->driver_data;
+	struct serial_icounter_struct icount;
+	struct uart_icount cnow;
+	int ret = -ENOIOCTLCMD;
+
+	BUG_ON(!kernel_locked());
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
+
+	switch (cmd) {
+		case TIOCMGET:
+			ret = uart_get_modem_info(info->port,
+						  (unsigned int *)arg);
+			break;
+
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			ret = uart_set_modem_info(info->port, cmd,
+						  (unsigned int *)arg);
+			break;
+
+		case TIOCGSERIAL:
+			ret = uart_get_info(info, (struct serial_struct *)arg);
+			break;
+
+		case TIOCSSERIAL:
+			ret = uart_set_info(info, (struct serial_struct *)arg);
+			break;
+
+		case TIOCSERCONFIG:
+			ret = uart_do_autoconfig(info);
+			break;
+
+		case TIOCSERGETLSR: /* Get line status register */
+			ret = uart_get_lsr_info(info, (unsigned int *)arg);
+			break;
+
+		/*
+		 * 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
+		 */
+		case TIOCMIWAIT:
+			ret = uart_wait_modem_status(info, arg);
+			break;
+
+		/*
+		 * 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.
+		 */
+		case TIOCGICOUNT:
+			spin_lock_irq(&info->port->lock);
+			memcpy(&cnow, &info->port->icount,
+			       sizeof(struct uart_icount));
+			spin_unlock_irq(&info->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;
+
+			ret = copy_to_user((void *)arg, &icount, sizeof(icount))
+					? -EFAULT : 0;
+			break;
+
+		case TIOCSERGWILD: /* obsolete */
+		case TIOCSERSWILD: /* obsolete */
+			ret = 0;
+			break;
+
+		default: {
+			struct uart_port *port = info->port;
+			if (port->ops->ioctl)
+				ret = port->ops->ioctl(port, cmd, arg);
+			break;
+		}
+	}
+	return ret;
+}
+
+static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct uart_info *info = 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(info, old_termios);
+
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
+		uart_clear_mctrl(info->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(info->port, mask);
+	}
+
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
+		spin_lock_irqsave(&info->port->lock, flags);
+		tty->hw_stopped = 0;
+		__uart_start(tty);
+		spin_unlock_irqrestore(&info->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(&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_driver *drv = (struct uart_driver *)tty->driver.driver_state;
+	struct uart_info *info = tty->driver_data;
+	struct uart_port *port = info->port;
+	struct uart_state *state;
+	unsigned long flags;
+
+	BUG_ON(!kernel_locked());
+
+	if (!info)
+		return;
+
+	state = info->state;
+
+	DPRINTK("uart_close() called\n");
+
+	/*
+	 * This is safe, as long as the BKL exists in
+	 * do_tty_hangup(), and we're protected by the BKL.
+	 */
+	if (tty_hung_up_p(filp))
+		goto done;
+
+	spin_lock_irqsave(&info->port->lock, flags);
+	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: %d\n",
+		       tty->driver.name, info->port->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		spin_unlock_irqrestore(&info->port->lock, flags);
+		goto done;
+	}
+
+	/*
+	 * The UIF_CLOSING flag protects us against further opens
+	 * of this port.
+	 */
+	info->flags |= UIF_CLOSING;
+	spin_unlock_irqrestore(&info->port->lock, flags);
+
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->state->closing_wait != USF_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->state->closing_wait);
+
+	/*
+	 * At this point, we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts.
+	 */
+	if (info->flags & UIF_INITIALIZED) {
+		port->ops->stop_rx(port);
+		/*
+		 * 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);
+	}
+	down(&port_sem);
+	uart_shutdown(info);
+	up(&port_sem);
+	uart_flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = NULL;
+	if (info->blocked_open) {
+		if (info->state->close_delay) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(info->state->close_delay);
+			set_current_state(TASK_RUNNING);
+		}
+	} else {
+#ifdef CONFIG_PM
+		/*
+		 * Put device into D3 state.
+		 */
+		pm_send(info->state->pm, PM_SUSPEND, (void *)3);
+#else
+		if (port->ops->pm)
+			port->ops->pm(port, 3, 0);
+#endif
+	}
+
+	/*
+	 * Wake up anyone trying to open this port.
+	 */
+	info->flags &= ~(UIF_NORMAL_ACTIVE|UIF_CLOSING);
+	wake_up_interruptible(&info->open_wait);
+
+ done:
+	if (drv->owner)
+		__MOD_DEC_USE_COUNT(drv->owner);
+}
+
+static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct uart_info *info = tty->driver_data;
+	struct uart_port *port = info->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_info *info = tty->driver_data;
+	struct uart_state *state = info->state;
+
+	BUG_ON(!kernel_locked());
+
+	uart_flush_buffer(tty);
+	down(&port_sem);
+	if (info->flags & UIF_CLOSING) {
+		up(&port_sem);
+		return;
+	}
+	uart_shutdown(info);
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~UIF_NORMAL_ACTIVE;
+	info->tty = NULL;
+	up(&port_sem);
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * 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_info *info)
+{
+	struct tty_struct *tty = info->tty;
+
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+	struct console *c = info->port->cons;
+
+	if (c && c->cflag && c->index == info->port->line) {
+		tty->termios->c_cflag = c->cflag;
+		c->cflag = 0;
+	}
+#endif
+
+	/*
+	 * 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(info, NULL);
+
+		/*
+		 * And finally enable the RTS and DTR signals.
+		 */
+		if (tty->termios->c_cflag & CBAUD)
+			uart_set_mctrl(info->port, TIOCM_DTR | TIOCM_RTS);
+	}
+}
+
+static int
+uart_block_til_ready(struct file *filp, struct uart_info *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct uart_state *state = info->state;
+	struct uart_port *port = info->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))
+			break;
+
+		/*
+		 * If the device is in the middle of being closed, block
+		 * until it's done.  We will need to re-initialise the
+		 * port.  Hmm, is it legal to block a non-blocking open?
+		 */
+		if (info->flags & UIF_CLOSING)
+			goto wait;
+
+		/*
+		 * 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(info->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;
+
+	 wait:
+		schedule();
+
+		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 (tty_hung_up_p(filp) || !(info->flags & UIF_INITIALIZED))
+		return (port->flags & UPF_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS;
+
+	return 0;
+}
+
+static struct uart_info *uart_get(struct uart_driver *drv, int line)
+{
+	struct uart_state *state = drv->state + line;
+	struct uart_info *info = NULL;
+
+	down(&port_sem);
+	if (!state->port)
+		goto out;
+
+	state->count++;
+	info = state->info;
+
+	if (!info) {
+		info = kmalloc(sizeof(struct uart_info), GFP_KERNEL);
+		if (info) {
+			memset(info, 0, sizeof(struct uart_info));
+			init_waitqueue_head(&info->open_wait);
+			init_waitqueue_head(&info->delta_msr_wait);
+
+			/*
+			 * Link the info into the other structures.
+			 */
+			info->port  = state->port;
+			info->state = state;
+			state->port->info = info;
+
+			tasklet_init(&info->tlet, uart_tasklet_action,
+				     (unsigned long)info);
+			state->info = info;
+		} else
+			state->count--;
+	}
+
+ out:
+	up(&port_sem);
+	return info;
+}
+
+/*
+ * 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_info *info;
+	int retval, line = minor(tty->device) - tty->driver.minor_start;
+
+	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;
+
+	/*
+	 * If we fail to increment the module use count, we can't have
+	 * any other users of this tty (since this implies that the module
+	 * is about to be unloaded).  Therefore, it is safe to set
+	 * tty->driver_data to be NULL, so uart_close() doesn't bite us.
+	 */
+	if (!try_inc_mod_count(drv->owner)) {
+		tty->driver_data = NULL;
+		goto fail;
+	}
+
+	/*
+	 * FIXME: This one isn't fun.  We can't guarantee that the tty isn't
+	 * already in open, nor can we guarantee the state of tty->driver_data
+	 */
+	info = uart_get(drv, line);
+	retval = -ENOMEM;
+	if (!info) {
+		if (tty->driver_data)
+			goto fail;
+		else
+			goto out;
+	}
+
+	/*
+	 * 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 = info;
+	info->tty = tty;
+	info->tty->low_latency = (info->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
+
+	/*
+	 * If the port is in the middle of closing, bail out now.
+	 */
+	if (tty_hung_up_p(filp) || (info->flags & UIF_CLOSING)) {
+	    	wait_event_interruptible(info->open_wait,
+					 !(info->flags & UIF_CLOSING));
+		retval = (info->port->flags & UPF_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS;
+		goto fail;
+	}
+
+	/*
+	 * Make sure the device is in D0 state.
+	 */
+	if (info->state->count == 1) {
+#ifdef CONFIG_PM
+		pm_send(info->state->pm, PM_RESUME, (void *)0);
+#else
+		struct uart_port *port = info->port;
+		if (port->ops->pm)
+			port->ops->pm(port, 0, 3);
+#endif
+	}
+
+	/*
+	 * Start up the serial port.  We have this semaphore here to
+	 * prevent uart_startup or uart_shutdown being re-entered if
+	 * we sleep while requesting an IRQ.
+	 */
+	down(&port_sem);
+	retval = uart_startup(info, 0);
+	up(&port_sem);
+	if (retval)
+		goto fail;
+
+	/*
+	 * Wait until the port is ready.
+	 */
+	retval = uart_block_til_ready(filp, info);
+
+	/*
+	 * If this is the first open to succeed, adjust things to suit.
+	 */
+	if (retval == 0 && !(info->flags & UIF_NORMAL_ACTIVE)) {
+		info->flags |= UIF_NORMAL_ACTIVE;
+
+		uart_update_termios(info);
+	}
+
+	return retval;
+
+ out:
+	if (drv->owner)
+		__MOD_DEC_USE_COUNT(drv->owner);
+ fail:
+	return retval;
+}
+
+#ifdef CONFIG_PROC_FS
+
+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;
+}
+
+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;
+	}
+
+	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);
+	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)
+{
+	unsigned int cflag = CREAD | HUPCL | CLOCAL;
+	unsigned int quot;
+	int i;
+
+	/*
+	 * Construct a cflag setting.
+	 */
+	for (i = 0; baud_rates[i].rate; i++)
+		if (baud_rates[i].rate <= baud)
+			break;
+
+	cflag |= baud_rates[i].cflag;
+
+	if (bits == 7)
+		cflag |= CS7;
+	else
+		cflag |= CS8;
+
+	switch (parity) {
+	case 'o': case 'O':
+		cflag |= PARODD;
+		/*fall through*/
+	case 'e': case 'E':
+		cflag |= PARENB;
+		break;
+	}
+
+	if (flow == 'r')
+		cflag |= CRTSCTS;
+
+	co->cflag = cflag;
+	quot = (port->uartclk / (16 * baud));
+	port->ops->change_speed(port, cflag, 0, quot);
+
+	return 0;
+}
+
+extern void ambauart_console_init(void);
+extern void anakin_console_init(void);
+extern void clps711xuart_console_init(void);
+extern void rs285_console_init(void);
+extern void sa1100_rs_console_init(void);
+extern void serial8250_console_init(void);
+extern void uart00_console_init(void);
+
+/*
+ * Central "initialise all serial consoles" container.  Needs to be killed.
+ */
+void __init uart_console_init(void)
+{
+#ifdef CONFIG_SERIAL_AMBA_CONSOLE
+	ambauart_console_init();
+#endif
+#ifdef CONFIG_SERIAL_ANAKIN_CONSOLE
+	anakin_console_init();
+#endif
+#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
+	clps711xuart_console_init();
+#endif
+#ifdef CONFIG_SERIAL_21285_CONSOLE
+	rs285_console_init();
+#endif
+#ifdef CONFIG_SERIAL_SA1100_CONSOLE
+	sa1100_rs_console_init();
+#endif
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	serial8250_console_init();
+#endif
+#ifdef CONFIG_SERIAL_UART00_CONSOLE
+	uart00_console_init();
+#endif
+}
+#endif /* CONFIG_SERIAL_CORE_CONSOLE */
+
+#ifdef CONFIG_PM
+/*
+ *  Serial port power management.
+ *
+ * This is pretty coarse at the moment - either all on or all off.  We
+ * should probably some day do finer power management here some day.
+ *
+ * We don't actually save any state; the serial driver already has the
+ * state held internally to re-setup the port when we come out of D3.
+ */
+static int uart_pm_set_state(struct uart_state *state, int pm_state, int oldstate)
+{
+	struct uart_port *port;
+	struct uart_ops *ops;
+	int running = state->info &&
+		      state->info->flags & UIF_INITIALIZED;
+
+	down(&port_sem);
+
+	if (!state->port || state->port->type == PORT_UNKNOWN) {
+		up(&port_sem);
+		return 0;
+	}
+
+	port = state->port;
+	ops = port->ops;
+
+	DPRINTK("pm: %08x: %d -> %d, %srunning\n",
+		port->iobase, dev->state, pm_state, running ? "" : "not ");
+
+	if (pm_state == 0) {
+		if (ops->pm)
+			ops->pm(port, pm_state, oldstate);
+		if (running) {
+			/*
+			 * The port lock isn't taken here -
+			 * the port isn't initialised.
+			 */
+			ops->set_mctrl(port, 0);
+			ops->startup(port);
+			uart_change_speed(state->info, NULL);
+			spin_lock_irq(&port->lock);
+			ops->set_mctrl(port, port->mctrl);
+			ops->start_tx(port, 0);
+			spin_unlock_irq(&port->lock);
+		}
+
+		/*
+		 * Re-enable the console device after suspending.
+		 */
+		if (port->cons && port->cons->index == port->line)
+			port->cons->flags |= CON_ENABLED;
+	} else if (pm_state == 1) {
+		if (ops->pm)
+			ops->pm(port, pm_state, oldstate);
+	} else {
+		/*
+		 * Disable the console device before suspending.
+		 */
+		if (port->cons && port->cons->index == port->line)
+			port->cons->flags &= ~CON_ENABLED;
+
+		if (running) {
+			spin_lock_irq(&port->lock);
+			ops->stop_tx(port, 0);
+			ops->set_mctrl(port, 0);
+			spin_unlock_irq(&port->lock);
+			ops->stop_rx(port);
+			ops->shutdown(port);
+		}
+		if (ops->pm)
+			ops->pm(port, pm_state, oldstate);
+	}
+	up(&port_sem);
+
+	return 0;
+}
+
+/*
+ *  Wakeup support.
+ */
+static int uart_pm_set_wakeup(struct uart_state *state, int data)
+{
+	int err = 0;
+
+	if (state->port->ops->set_wake)
+		err = state->port->ops->set_wake(state->port, data);
+
+	return err;
+}
+
+static int uart_pm(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+	struct uart_state *state = dev->data;
+	int err = 0;
+
+	switch (rqst) {
+	case PM_SUSPEND:
+	case PM_RESUME:
+		err = uart_pm_set_state(state, (int)data, dev->state);
+		break;
+
+	case PM_SET_WAKEUP:
+		err = uart_pm_set_wakeup(state, (int)data);
+		break;
+	}
+	return err;
+}
+#endif
+
+static inline void
+uart_report_port(struct uart_driver *drv, struct uart_port *port)
+{
+	printk("%s%d at ", drv->dev_name, port->line);
+	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_register_port(struct uart_driver *drv, struct uart_state *state,
+		     struct uart_port *port)
+{
+	unsigned int flags;
+
+	state->port = port;
+
+	spin_lock_init(&port->lock);
+	port->type = PORT_UNKNOWN;
+	port->cons = drv->cons;
+	port->info = state->info;
+
+	/*
+	 * If there isn't a port here, don't do anything further.
+	 */
+	if (!port->iobase && !port->mapbase)
+		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->ops->config_port(port, flags);
+
+	/*
+	 * Register the port whether it's detected or not.  This allows
+	 * setserial to be used to alter this ports parameters.
+	 */
+	tty_register_devfs(drv->tty_driver, 0, drv->minor + port->line);
+
+	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);
+
+#ifdef CONFIG_PM
+		/*
+		 * Power down all ports by default, except the
+		 * console if we have one.  We need to drop the
+		 * port semaphore here.
+		 */
+		if (state->pm && (!drv->cons || port->line != drv->cons->index)) {
+			up(&port_sem);
+			pm_send(state->pm, PM_SUSPEND, (void *)3);
+			down(&port_sem);
+		}
+#endif
+	}
+}
+
+/*
+ *	Hangup the port.  This must be done outside the port_sem
+ *	since uart_hangup() grabs this same semaphore.  Grr.
+ */
+static void
+__uart_hangup_port(struct uart_driver *drv, struct uart_state *state)
+{
+	struct uart_info *info = state->info;
+
+	if (info && info->tty)
+		tty_vhangup(info->tty);
+}
+
+/*
+ * This reverses the affects of __uart_register_port.
+ */
+static void
+__uart_unregister_port(struct uart_driver *drv, struct uart_state *state)
+{
+	struct uart_port *port = state->port;
+	struct uart_info *info = state->info;
+
+	state->info = NULL;
+
+	/*
+	 * Remove the devices from devfs
+	 */
+	tty_unregister_devfs(drv->tty_driver, drv->minor + port->line);
+
+	/*
+	 * 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);
+	}
+}
+
+/**
+ *	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;
+	struct termios **termios = 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.  Note that we also
+	 * allocate space for an integer for reference counting.
+	 */
+	drv->state = kmalloc(sizeof(struct uart_state) * drv->nr +
+			     sizeof(int), GFP_KERNEL);
+	retval = -ENOMEM;
+	if (!drv->state)
+		goto out;
+
+	memset(drv->state, 0, sizeof(struct uart_state) * drv->nr +
+			sizeof(int));
+
+	termios = kmalloc(sizeof(struct termios *) * drv->nr * 2 +
+			  sizeof(struct tty_struct *) * drv->nr, GFP_KERNEL);
+	if (!termios)
+		goto out;
+
+	memset(termios, 0, sizeof(struct termios *) * drv->nr * 2 +
+			   sizeof(struct tty_struct *) * drv->nr);
+
+	normal  = kmalloc(sizeof(struct tty_driver), GFP_KERNEL);
+	if (!normal)
+		goto out;
+
+	memset(normal, 0, sizeof(struct tty_driver));
+
+	drv->tty_driver = normal;
+
+	normal->magic		= TTY_DRIVER_MAGIC;
+	normal->driver_name	= drv->driver_name;
+	normal->name		= drv->dev_name;
+	normal->major		= drv->major;
+	normal->minor_start	= drv->minor;
+	normal->num		= drv->nr;
+	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->refcount	= (int *)(drv->state + drv->nr);
+	normal->termios		= termios;
+	normal->termios_locked	= termios + drv->nr;
+	normal->table		= (struct tty_struct **)(termios + drv->nr * 2);
+	normal->driver_state    = drv;
+
+	normal->open		= uart_open;
+	normal->close		= uart_close;
+	normal->write		= uart_write;
+	normal->put_char	= uart_put_char;
+	normal->flush_chars	= uart_flush_chars;
+	normal->write_room	= uart_write_room;
+	normal->chars_in_buffer	= uart_chars_in_buffer;
+	normal->flush_buffer	= uart_flush_buffer;
+	normal->ioctl		= uart_ioctl;
+	normal->throttle	= uart_throttle;
+	normal->unthrottle	= uart_unthrottle;
+	normal->send_xchar	= uart_send_xchar;
+	normal->set_termios	= uart_set_termios;
+	normal->stop		= uart_stop;
+	normal->start		= uart_start;
+	normal->hangup		= uart_hangup;
+	normal->break_ctl	= uart_break_ctl;
+	normal->wait_until_sent	= uart_wait_until_sent;
+#ifdef CONFIG_PROC_FS
+	normal->read_proc	= uart_read_proc;
+#endif
+
+	/*
+	 * 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;
+#ifdef CONFIG_PM
+		state->pm = pm_register(PM_SYS_DEV, PM_SYS_COM, uart_pm);
+		if (state->pm)
+			state->pm->data = state;
+#endif
+	}
+
+	retval = tty_register_driver(normal);
+ out:
+	if (retval < 0) {
+#ifdef CONFIG_PM
+		for (i = 0; i < drv->nr; i++)
+			pm_unregister(drv->state[i].pm);
+#endif
+		kfree(normal);
+		kfree(drv->state);
+		kfree(termios);
+	}
+	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)
+{
+	int i;
+
+	for (i = 0; i < drv->nr; i++)
+		pm_unregister(drv->state[i].pm);
+
+	tty_unregister_driver(drv->tty_driver);
+
+	kfree(drv->state);
+	kfree(drv->tty_driver->termios);
+	kfree(drv->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;
+
+	BUG_ON(in_interrupt());
+
+	if (port->line >= drv->nr)
+		return -EINVAL;
+
+	state = drv->state + port->line;
+
+	down(&port_sem);
+	__uart_register_port(drv, state, port);
+	up(&port_sem);
+
+	return 0;
+}
+
+/**
+ *	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);
+
+	__uart_hangup_port(drv, state);
+
+	down(&port_sem);
+	__uart_unregister_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 (state->count != 0 ||
+		    (state->info && state->info->blocked_open != 0)) {
+			ret = -EBUSY;
+			goto out;
+		}
+
+		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     = drv->state - state;
+
+		__uart_register_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 %s%d\n",
+			drv->dev_name, line);
+		return;
+	}
+
+	state = drv->state + line;
+
+	__uart_hangup_port(drv, state);
+
+	down(&port_sem);
+	__uart_unregister_port(drv, state);
+	up(&port_sem);
+}
+
+EXPORT_SYMBOL(uart_event);
+EXPORT_SYMBOL(uart_register_driver);
+EXPORT_SYMBOL(uart_unregister_driver);
+EXPORT_SYMBOL(uart_register_port);
+EXPORT_SYMBOL(uart_unregister_port);
+
+MODULE_DESCRIPTION("Serial driver core");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/sa1100.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,890 @@
+/*
+ *  linux/drivers/char/sa1100.c
+ *
+ *  Driver for SA11x0 serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  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
+ *
+ *  $Id: sa1100.c,v 1.43 2002/07/22 15:27:32 rmk Exp $
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.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/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/hardware.h>
+#include <asm/mach/serial_sa1100.h>
+
+#if defined(CONFIG_SERIAL_SA1100_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+/* We've been assigned a range on the "Low-density serial ports" major */
+#define SERIAL_SA1100_MAJOR	204
+#define MINOR_START		5
+
+#define NR_PORTS		3
+
+#define SA1100_ISR_PASS_LIMIT	256
+
+/*
+ * Convert from ignore_status_mask or read_status_mask to UTSR[01]
+ */
+#define SM_TO_UTSR0(x)	((x) & 0xff)
+#define SM_TO_UTSR1(x)	((x) >> 8)
+#define UTSR0_TO_SM(x)	((x))
+#define UTSR1_TO_SM(x)	((x) << 8)
+
+#define UART_GET_UTCR0(sport)	__raw_readl((sport)->port.membase + UTCR0)
+#define UART_GET_UTCR1(sport)	__raw_readl((sport)->port.membase + UTCR1)
+#define UART_GET_UTCR2(sport)	__raw_readl((sport)->port.membase + UTCR2)
+#define UART_GET_UTCR3(sport)	__raw_readl((sport)->port.membase + UTCR3)
+#define UART_GET_UTSR0(sport)	__raw_readl((sport)->port.membase + UTSR0)
+#define UART_GET_UTSR1(sport)	__raw_readl((sport)->port.membase + UTSR1)
+#define UART_GET_CHAR(sport)	__raw_readl((sport)->port.membase + UTDR)
+
+#define UART_PUT_UTCR0(sport,v)	__raw_writel((v),(sport)->port.membase + UTCR0)
+#define UART_PUT_UTCR1(sport,v)	__raw_writel((v),(sport)->port.membase + UTCR1)
+#define UART_PUT_UTCR2(sport,v)	__raw_writel((v),(sport)->port.membase + UTCR2)
+#define UART_PUT_UTCR3(sport,v)	__raw_writel((v),(sport)->port.membase + UTCR3)
+#define UART_PUT_UTSR0(sport,v)	__raw_writel((v),(sport)->port.membase + UTSR0)
+#define UART_PUT_UTSR1(sport,v)	__raw_writel((v),(sport)->port.membase + UTSR1)
+#define UART_PUT_CHAR(sport,v)	__raw_writel((v),(sport)->port.membase + UTDR)
+
+/*
+ * This is the size of our serial port register set.
+ */
+#define UART_PORT_SIZE	0x24
+
+/*
+ * This determines how often we check the modem status signals
+ * for any change.  They generally aren't connected to an IRQ
+ * so we have to poll them.  We also check immediately before
+ * filling the TX fifo incase CTS has been dropped.
+ */
+#define MCTRL_TIMEOUT	(250*HZ/1000)
+
+struct sa1100_port {
+	struct uart_port	port;
+	struct timer_list	timer;
+	unsigned int		old_status;
+};
+
+/*
+ * Handle any change of modem status signal since we were last called.
+ */
+static void sa1100_mctrl_check(struct sa1100_port *sport)
+{
+	unsigned int status, changed;
+
+	status = sport->port.ops->get_mctrl(&sport->port);
+	changed = status ^ sport->old_status;
+
+	if (changed == 0)
+		return;
+
+	sport->old_status = status;
+
+	if (changed & TIOCM_RI)
+		sport->port.icount.rng++;
+	if (changed & TIOCM_DSR)
+		sport->port.icount.dsr++;
+	if (changed & TIOCM_CAR)
+		uart_handle_dcd_change(&sport->port, status & TIOCM_CAR);
+	if (changed & TIOCM_CTS)
+		uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
+
+	wake_up_interruptible(&sport->port.info->delta_msr_wait);
+}
+
+/*
+ * This is our per-port timeout handler, for checking the
+ * modem status signals.
+ */
+static void sa1100_timeout(unsigned long data)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)data;
+	unsigned long flags;
+
+	if (sport->port.info) {
+		spin_lock_irqsave(&sport->port.lock, flags);
+		sa1100_mctrl_check(sport);
+		spin_unlock_irqrestore(&sport->port.lock, flags);
+
+		mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT);
+	}
+}
+
+/*
+ * interrupts disabled on entry
+ */
+static void sa1100_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	u32 utcr3;
+
+	utcr3 = UART_GET_UTCR3(sport);
+	UART_PUT_UTCR3(sport, utcr3 & ~UTCR3_TIE);
+	sport->port.read_status_mask &= ~UTSR0_TO_SM(UTSR0_TFS);
+}
+
+/*
+ * interrupts may not be disabled on entry
+ */
+static void sa1100_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	unsigned long flags;
+	u32 utcr3;
+
+	spin_lock_irqsave(&sport->port.lock, flags);
+	utcr3 = UART_GET_UTCR3(sport);
+	sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS);
+	UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE);
+	spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+/*
+ * Interrupts enabled
+ */
+static void sa1100_stop_rx(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	unsigned long flags;
+	u32 utcr3;
+
+	spin_lock_irqsave(&sport->port.lock, flags);
+	utcr3 = UART_GET_UTCR3(sport);
+	UART_PUT_UTCR3(sport, utcr3 & ~UTCR3_RIE);
+	spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+/*
+ * Set the modem control timer to fire immediately.
+ */
+static void sa1100_enable_ms(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	mod_timer(&sport->timer, jiffies);
+}
+
+static void
+sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
+{
+	struct tty_struct *tty = sport->port.info->tty;
+	unsigned int status, ch, flg, ignored = 0;
+
+	status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
+		 UTSR0_TO_SM(UART_GET_UTSR0(sport));
+	while (status & UTSR1_TO_SM(UTSR1_RNE)) {
+		ch = UART_GET_CHAR(sport);
+
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		sport->port.icount.rx++;
+
+		flg = TTY_NORMAL;
+
+		/*
+		 * note that the error handling code is
+		 * out of the main execution path
+		 */
+		if (status & UTSR1_TO_SM(UTSR1_PRE | UTSR1_FRE | UTSR1_ROR))
+			goto handle_error;
+
+		if (uart_handle_sysrq_char(&sport->port, ch, regs))
+			goto ignore_char;
+
+	error_return:
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+	ignore_char:
+		status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
+			 UTSR0_TO_SM(UART_GET_UTSR0(sport));
+	}
+ out:
+	tty_flip_buffer_push(tty);
+	return;
+
+ handle_error:
+	if (status & UTSR1_TO_SM(UTSR1_PRE))
+		sport->port.icount.parity++;
+	else if (status & UTSR1_TO_SM(UTSR1_FRE))
+		sport->port.icount.frame++;
+	if (status & UTSR1_TO_SM(UTSR1_ROR))
+		sport->port.icount.overrun++;
+
+	if (status & sport->port.ignore_status_mask) {
+		if (++ignored > 100)
+			goto out;
+		goto ignore_char;
+	}
+
+	status &= sport->port.read_status_mask;
+
+	if (status & UTSR1_TO_SM(UTSR1_PRE))
+		flg = TTY_PARITY;
+	else if (status & UTSR1_TO_SM(UTSR1_FRE))
+		flg = TTY_FRAME;
+
+	if (status & UTSR1_TO_SM(UTSR1_ROR)) {
+		/*
+		 * overrun does *not* affect the character
+		 * we read from the FIFO
+		 */
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		ch = 0;
+		flg = TTY_OVERRUN;
+	}
+#ifdef SUPPORT_SYSRQ
+	sport->port.sysrq = 0;
+#endif
+	goto error_return;
+}
+
+static void sa1100_tx_chars(struct sa1100_port *sport)
+{
+	struct circ_buf *xmit = &sport->port.info->xmit;
+
+	if (sport->port.x_char) {
+		UART_PUT_CHAR(sport, sport->port.x_char);
+		sport->port.icount.tx++;
+		sport->port.x_char = 0;
+		return;
+	}
+
+	/*
+	 * Check the modem control lines before
+	 * transmitting anything.
+	 */
+	sa1100_mctrl_check(sport);
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
+		sa1100_stop_tx(&sport->port, 0);
+		return;
+	}
+
+	/*
+	 * Tried using FIFO (not checking TNF) for fifo fill:
+	 * still had the '4 bytes repeated' problem.
+	 */
+	while (UART_GET_UTSR1(sport) & UTSR1_TNF) {
+		UART_PUT_CHAR(sport, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		sport->port.icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	}
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_event(&sport->port, EVT_WRITE_WAKEUP);
+
+	if (uart_circ_empty(xmit))
+		sa1100_stop_tx(&sport->port, 0);
+}
+
+static void sa1100_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct sa1100_port *sport = dev_id;
+	unsigned int status, pass_counter = 0;
+
+	spin_lock(&sport->port.lock);
+	status = UART_GET_UTSR0(sport);
+	status &= SM_TO_UTSR0(sport->port.read_status_mask) | ~UTSR0_TFS;
+	do {
+		if (status & (UTSR0_RFS | UTSR0_RID)) {
+			/* Clear the receiver idle bit, if set */
+			if (status & UTSR0_RID)
+				UART_PUT_UTSR0(sport, UTSR0_RID);
+			sa1100_rx_chars(sport, regs);
+		}
+
+		/* Clear the relevent break bits */
+		if (status & (UTSR0_RBB | UTSR0_REB))
+			UART_PUT_UTSR0(sport, status & (UTSR0_RBB | UTSR0_REB));
+
+		if (status & UTSR0_RBB)
+			sport->port.icount.brk++;
+
+		if (status & UTSR0_REB)
+			uart_handle_break(&sport->port);
+
+		if (status & UTSR0_TFS)
+			sa1100_tx_chars(sport);
+		if (pass_counter++ > SA1100_ISR_PASS_LIMIT)
+			break;
+		status = UART_GET_UTSR0(sport);
+		status &= SM_TO_UTSR0(sport->port.read_status_mask) |
+			  ~UTSR0_TFS;
+	} while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID));
+	spin_unlock(&sport->port.lock);
+}
+
+/*
+ * Return TIOCSER_TEMT when transmitter is not busy.
+ */
+static unsigned int sa1100_tx_empty(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	return UART_GET_UTSR1(sport) & UTSR1_TBY ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int sa1100_get_mctrl(struct uart_port *port)
+{
+	return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+}
+
+static void sa1100_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+}
+
+/*
+ * Interrupts always disabled.
+ */
+static void sa1100_break_ctl(struct uart_port *port, int break_state)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	unsigned long flags;
+	unsigned int utcr3;
+
+	spin_lock_irqsave(&sport->port.lock, flags);
+	utcr3 = UART_GET_UTCR3(sport);
+	if (break_state == -1)
+		utcr3 |= UTCR3_BRK;
+	else
+		utcr3 &= ~UTCR3_BRK;
+	UART_PUT_UTCR3(sport, utcr3);
+	spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static int sa1100_startup(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	int retval;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(sport->port.irq, sa1100_int, 0,
+			     "serial_sa1100", sport);
+	if (retval)
+		return retval;
+
+	/*
+	 * Finally, clear and enable interrupts
+	 */
+	UART_PUT_UTSR0(sport, -1);
+	UART_PUT_UTCR3(sport, UTCR3_RXE | UTCR3_TXE | UTCR3_RIE);
+
+	/*
+	 * Enable modem status interrupts
+	 */
+	sa1100_enable_ms(&sport->port);
+
+	return 0;
+}
+
+static void sa1100_shutdown(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	/*
+	 * Stop our timer.
+	 */
+	del_timer_sync(&sport->timer);
+
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(sport->port.irq, sport);
+
+	/*
+	 * Disable all interrupts, port and break condition.
+	 */
+	UART_PUT_UTCR3(sport, 0);
+}
+
+static void
+sa1100_change_speed(struct uart_port *port, unsigned int cflag,
+		    unsigned int iflag, unsigned int quot)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	unsigned long flags;
+	unsigned int utcr0, old_utcr3;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS7:
+		utcr0 = 0;
+		break;
+	default:
+		utcr0 = UTCR0_DSS;
+		break;
+	}
+	if (cflag & CSTOPB)
+		utcr0 |= UTCR0_SBS;
+	if (cflag & PARENB) {
+		utcr0 |= UTCR0_PE;
+		if (!(cflag & PARODD))
+			utcr0 |= UTCR0_OES;
+	}
+
+	sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS);
+	sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR);
+	if (iflag & INPCK)
+		sport->port.read_status_mask |=
+				UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
+	if (iflag & (BRKINT | PARMRK))
+		sport->port.read_status_mask |=
+				UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);
+
+	/*
+	 * Characters to ignore
+	 */
+	sport->port.ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		sport->port.ignore_status_mask |=
+				UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
+	if (iflag & IGNBRK) {
+		sport->port.ignore_status_mask |=
+				UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			sport->port.ignore_status_mask |=
+				UTSR1_TO_SM(UTSR1_ROR);
+	}
+
+	del_timer_sync(&sport->timer);
+
+	/* first, disable interrupts and drain transmitter */
+	spin_lock_irqsave(&sport->port.lock, flags);
+	old_utcr3 = UART_GET_UTCR3(sport);
+	UART_PUT_UTCR3(sport, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE));
+
+	while (UART_GET_UTSR1(sport) & UTSR1_TBY);
+
+	/* then, disable everything */
+	UART_PUT_UTCR3(sport, 0);
+
+	/* set the parity, stop bits and data size */
+	UART_PUT_UTCR0(sport, utcr0);
+
+	/* set the baud rate */
+	quot -= 1;
+	UART_PUT_UTCR1(sport, ((quot & 0xf00) >> 8));
+	UART_PUT_UTCR2(sport, (quot & 0xff));
+
+	UART_PUT_UTSR0(sport, -1);
+
+	UART_PUT_UTCR3(sport, old_utcr3);
+	spin_unlock_irqrestore(&sport->port.lock, flags);
+
+	if (UART_ENABLE_MS(&sport->port, cflag))
+		sa1100_enable_ms(&sport->port);
+}
+
+static const char *sa1100_type(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	return sport->port.type == PORT_SA1100 ? "SA1100" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'.
+ */
+static void sa1100_release_port(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	release_mem_region(sport->port.mapbase, UART_PORT_SIZE);
+}
+
+/*
+ * Request the memory region(s) being used by 'port'.
+ */
+static int sa1100_request_port(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	return request_mem_region(sport->port.mapbase, UART_PORT_SIZE,
+			"serial_sa1100") != NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void sa1100_config_port(struct uart_port *port, int flags)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	if (flags & UART_CONFIG_TYPE &&
+	    sa1100_request_port(&sport->port) == 0)
+		sport->port.type = PORT_SA1100;
+}
+
+/*
+ * Verify the new serial_struct (for TIOCSSERIAL).
+ * The only change we allow are to the flags and type, and
+ * even then only between PORT_SA1100 and PORT_UNKNOWN
+ */
+static int
+sa1100_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	int ret = 0;
+
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_SA1100)
+		ret = -EINVAL;
+	if (sport->port.irq != ser->irq)
+		ret = -EINVAL;
+	if (ser->io_type != SERIAL_IO_MEM)
+		ret = -EINVAL;
+	if (sport->port.uartclk / 16 != ser->baud_base)
+		ret = -EINVAL;
+	if ((void *)sport->port.mapbase != ser->iomem_base)
+		ret = -EINVAL;
+	if (sport->port.iobase != ser->port)
+		ret = -EINVAL;
+	if (ser->hub6 != 0)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops sa1100_pops = {
+	tx_empty:	sa1100_tx_empty,
+	set_mctrl:	sa1100_set_mctrl,
+	get_mctrl:	sa1100_get_mctrl,
+	stop_tx:	sa1100_stop_tx,
+	start_tx:	sa1100_start_tx,
+	stop_rx:	sa1100_stop_rx,
+	enable_ms:	sa1100_enable_ms,
+	break_ctl:	sa1100_break_ctl,
+	startup:	sa1100_startup,
+	shutdown:	sa1100_shutdown,
+	change_speed:	sa1100_change_speed,
+	type:		sa1100_type,
+	release_port:	sa1100_release_port,
+	request_port:	sa1100_request_port,
+	config_port:	sa1100_config_port,
+	verify_port:	sa1100_verify_port,
+};
+
+static struct sa1100_port sa1100_ports[NR_PORTS];
+
+/*
+ * Setup the SA1100 serial ports.  Note that we don't include the IrDA
+ * port here since we have our own SIR/FIR driver (see drivers/net/irda)
+ *
+ * Note also that we support "console=ttySAx" where "x" is either 0 or 1.
+ * Which serial port this ends up being depends on the machine you're
+ * running this kernel on.  I'm not convinced that this is a good idea,
+ * but that's the way it traditionally works.
+ *
+ * Note that NanoEngine UART3 becomes UART2, and UART2 is no longer
+ * used here.
+ */
+static void __init sa1100_init_ports(void)
+{
+	static int first = 1;
+	int i;
+
+	if (!first)
+		return;
+	first = 0;
+
+	for (i = 0; i < NR_PORTS; i++) {
+		sa1100_ports[i].port.uartclk   = 3686400;
+		sa1100_ports[i].port.ops       = &sa1100_pops;
+		sa1100_ports[i].port.fifosize  = 8;
+		sa1100_ports[i].port.line      = i;
+		sa1100_ports[i].port.iotype    = SERIAL_IO_MEM;
+		init_timer(&sa1100_ports[i].timer);
+		sa1100_ports[i].timer.function = sa1100_timeout;
+		sa1100_ports[i].timer.data     = (unsigned long)&sa1100_ports[i];
+	}
+
+	/*
+	 * make transmit lines outputs, so that when the port
+	 * is closed, the output is in the MARK state.
+	 */
+	PPDR |= PPC_TXD1 | PPC_TXD3;
+	PPSR |= PPC_TXD1 | PPC_TXD3;
+}
+
+void __init sa1100_register_uart_fns(struct sa1100_port_fns *fns)
+{
+	if (fns->get_mctrl)
+		sa1100_pops.get_mctrl = fns->get_mctrl;
+	if (fns->set_mctrl)
+		sa1100_pops.set_mctrl = fns->set_mctrl;
+
+	sa1100_pops.pm       = fns->pm;
+	sa1100_pops.set_wake = fns->set_wake;
+}
+
+void __init sa1100_register_uart(int idx, int port)
+{
+	if (idx >= NR_PORTS) {
+		printk(KERN_ERR __FUNCTION__ ": bad index number %d\n", idx);
+		return;
+	}
+
+	switch (port) {
+	case 1:
+		sa1100_ports[idx].port.membase = (void *)&Ser1UTCR0;
+		sa1100_ports[idx].port.mapbase = _Ser1UTCR0;
+		sa1100_ports[idx].port.irq     = IRQ_Ser1UART;
+		sa1100_ports[idx].port.flags   = ASYNC_BOOT_AUTOCONF;
+		break;
+
+	case 2:
+		sa1100_ports[idx].port.membase = (void *)&Ser2UTCR0;
+		sa1100_ports[idx].port.mapbase = _Ser2UTCR0;
+		sa1100_ports[idx].port.irq     = IRQ_Ser2ICP;
+		sa1100_ports[idx].port.flags   = ASYNC_BOOT_AUTOCONF;
+		break;
+
+	case 3:
+		sa1100_ports[idx].port.membase = (void *)&Ser3UTCR0;
+		sa1100_ports[idx].port.mapbase = _Ser3UTCR0;
+		sa1100_ports[idx].port.irq     = IRQ_Ser3UART;
+		sa1100_ports[idx].port.flags   = ASYNC_BOOT_AUTOCONF;
+		break;
+
+	default:
+		printk(KERN_ERR __FUNCTION__ ": bad port number %d\n", port);
+	}
+}
+
+
+#ifdef CONFIG_SERIAL_SA1100_CONSOLE
+
+/*
+ * Interrupts are disabled on entering
+ */
+static void
+sa1100_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct sa1100_port *sport = &sa1100_ports[co->index];
+	unsigned int old_utcr3, status, i;
+
+	/*
+	 *	First, save UTCR3 and then disable interrupts
+	 */
+	old_utcr3 = UART_GET_UTCR3(sport);
+	UART_PUT_UTCR3(sport, (old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)) |
+				UTCR3_TXE);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_UTSR1(sport);
+		} while (!(status & UTSR1_TNF));
+		UART_PUT_CHAR(sport, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_UTSR1(sport);
+			} while (!(status & UTSR1_TNF));
+			UART_PUT_CHAR(sport, '\r');
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore UTCR3
+	 */
+	do {
+		status = UART_GET_UTSR1(sport);
+	} while (status & UTSR1_TBY);
+	UART_PUT_UTCR3(sport, old_utcr3);
+}
+
+static kdev_t sa1100_console_device(struct console *co)
+{
+	return mk_kdev(SERIAL_SA1100_MAJOR, MINOR_START + co->index);
+}
+
+/*
+ * If the port was already initialised (eg, by a boot loader),
+ * try to determine the current setup.
+ */
+static void __init
+sa1100_console_get_options(struct sa1100_port *sport, int *baud,
+			   int *parity, int *bits)
+{
+	unsigned int utcr3;
+
+	utcr3 = UART_GET_UTCR3(sport) & (UTCR3_RXE | UTCR3_TXE);
+	if (utcr3 == (UTCR3_RXE | UTCR3_TXE)) {
+		/* ok, the port was enabled */
+		unsigned int utcr0, quot;
+
+		utcr0 = UART_GET_UTCR0(sport);
+
+		*parity = 'n';
+		if (utcr0 & UTCR0_PE) {
+			if (utcr0 & UTCR0_OES)
+				*parity = 'e';
+			else
+				*parity = 'o';
+		}
+
+		if (utcr0 & UTCR0_DSS)
+			*bits = 8;
+		else
+			*bits = 7;
+
+		quot = UART_GET_UTCR2(sport) | UART_GET_UTCR1(sport) << 8;
+		quot &= 0xfff;
+		*baud = sport->port.uartclk / (16 * (quot + 1));
+	}
+}
+
+static int __init
+sa1100_console_setup(struct console *co, char *options)
+{
+	struct sa1100_port *sport;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index == -1 || co->index >= NR_PORTS)
+		co->index = 0;
+	sport = &sa1100_ports[co->index];
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		sa1100_console_get_options(sport, &baud, &parity, &bits);
+
+	return uart_set_options(&sport->port, co, baud, parity, bits, flow);
+}
+
+static struct console sa1100_console = {
+	name:		"ttySA",
+	write:		sa1100_console_write,
+	device:		sa1100_console_device,
+	setup:		sa1100_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init sa1100_rs_console_init(void)
+{
+	sa1100_init_ports();
+	register_console(&sa1100_console);
+}
+
+#define SA1100_CONSOLE	&sa1100_console
+#else
+#define SA1100_CONSOLE	NULL
+#endif
+
+static struct uart_driver sa1100_reg = {
+	owner:			THIS_MODULE,
+	driver_name:		"ttySA",
+#ifdef CONFIG_DEVFS_FS
+	dev_name:		"ttySA%d",
+#else
+	dev_name:		"ttySA",
+#endif
+	major:			SERIAL_SA1100_MAJOR,
+	minor:			MINOR_START,
+	nr:			NR_PORTS,
+	cons:			SA1100_CONSOLE,
+};
+
+static int __init sa1100_serial_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "Serial: SA11x0 driver $Revision: 1.43 $\n");
+
+	sa1100_init_ports();
+	ret = uart_register_driver(&sa1100_reg);
+	if (ret == 0) {
+		int i;
+
+		for (i = 0; i < NR_PORTS; i++)
+			uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port);
+	}
+	return ret;
+}
+
+static void __exit sa1100_serial_exit(void)
+{
+	int i;
+
+	for (i = 0; i < NR_PORTS; i++)
+		uart_remove_one_port(&sa1100_reg, &sa1100_ports[i].port);
+
+	uart_unregister_driver(&sa1100_reg);
+}
+
+module_init(sa1100_serial_init);
+module_exit(sa1100_serial_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("Deep Blue Solutions Ltd");
+MODULE_DESCRIPTION("SA1100 generic serial port driver $Revision: 1.43 $");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/serial/uart00.c b/drivers/serial/uart00.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/uart00.c	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,778 @@
+/*
+ *  linux/drivers/char/uart00.c
+ *
+ *  Driver for UART00 serial ports
+ *
+ *  Based on drivers/char/serial_amba.c, by ARM Limited & 
+ *                                          Deep Blue Solutions Ltd.
+ *  Copyright 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id: uart00.c,v 1.33 2002/07/21 21:32:31 rmk Exp $
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.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/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/pld/pld_hotswap.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/sizes.h>
+
+#if defined(CONFIG_SERIAL_UART00_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+#include <asm/arch/excalibur.h>
+#define UART00_TYPE (volatile unsigned int*)
+#include <asm/arch/uart00.h>
+#include <asm/arch/int_ctrl00.h>
+
+#define UART_NR		2
+
+#define SERIAL_UART00_NAME	"ttyUA"
+#define SERIAL_UART00_MAJOR	204
+#define SERIAL_UART00_MINOR	16      /* Temporary - will change in future */
+#define SERIAL_UART00_NR	UART_NR
+#define UART_PORT_SIZE 0x50
+
+#define UART00_ISR_PASS_LIMIT	256
+
+/*
+ * Access macros for the UART00 UARTs
+ */
+#define UART_GET_INT_STATUS(p)	inl(UART_ISR((p)->membase))
+#define UART_PUT_IES(p, c)      outl(c,UART_IES((p)->membase))
+#define UART_GET_IES(p)         inl(UART_IES((p)->membase))
+#define UART_PUT_IEC(p, c)      outl(c,UART_IEC((p)->membase))
+#define UART_GET_IEC(p)         inl(UART_IEC((p)->membase))
+#define UART_PUT_CHAR(p, c)     outl(c,UART_TD((p)->membase))
+#define UART_GET_CHAR(p)        inl(UART_RD((p)->membase))
+#define UART_GET_RSR(p)         inl(UART_RSR((p)->membase))
+#define UART_GET_RDS(p)         inl(UART_RDS((p)->membase))
+#define UART_GET_MSR(p)         inl(UART_MSR((p)->membase))
+#define UART_GET_MCR(p)         inl(UART_MCR((p)->membase))
+#define UART_PUT_MCR(p, c)      outl(c,UART_MCR((p)->membase))
+#define UART_GET_MC(p)          inl(UART_MC((p)->membase))
+#define UART_PUT_MC(p, c)       outl(c,UART_MC((p)->membase))
+#define UART_GET_TSR(p)         inl(UART_TSR((p)->membase))
+#define UART_GET_DIV_HI(p)	inl(UART_DIV_HI((p)->membase))
+#define UART_PUT_DIV_HI(p,c)	outl(c,UART_DIV_HI((p)->membase))
+#define UART_GET_DIV_LO(p)	inl(UART_DIV_LO((p)->membase))
+#define UART_PUT_DIV_LO(p,c)	outl(c,UART_DIV_LO((p)->membase))
+#define UART_RX_DATA(s)		((s) & UART_RSR_RX_LEVEL_MSK)
+#define UART_TX_READY(s)	(((s) & UART_TSR_TX_LEVEL_MSK) < 15)
+//#define UART_TX_EMPTY(p)	((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0)
+
+static void uart00_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	UART_PUT_IEC(port, UART_IEC_TIE_MSK);
+}
+
+static void uart00_stop_rx(struct uart_port *port)
+{
+	UART_PUT_IEC(port, UART_IEC_RE_MSK);
+}
+
+static void uart00_enable_ms(struct uart_port *port)
+{
+	UART_PUT_IES(port, UART_IES_ME_MSK);
+}
+
+static void
+uart00_rx_chars(struct uart_port *port, struct pt_regs *regs)
+{
+	struct tty_struct *tty = port->info->tty;
+	unsigned int status, ch, rds, flg, ignored = 0;
+
+	status = UART_GET_RSR(port);
+	while (UART_RX_DATA(status)) {
+		/* 
+		 * We need to read rds before reading the 
+		 * character from the fifo
+		 */
+		rds = UART_GET_RDS(port);
+		ch = UART_GET_CHAR(port);
+		port->icount.rx++;
+
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+
+		flg = TTY_NORMAL;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		if (rds & (UART_RDS_BI_MSK |UART_RDS_FE_MSK|
+			   UART_RDS_PE_MSK |UART_RDS_PE_MSK))
+			goto handle_error;
+		if (uart_handle_sysrq_char(port, ch, regs))
+			goto ignore_char;
+
+	error_return:
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+	ignore_char:
+		status = UART_GET_RSR(port);
+	}
+ out:
+	tty_flip_buffer_push(tty);
+	return;
+
+ handle_error:
+	if (rds & UART_RDS_BI_MSK) {
+		status &= ~(UART_RDS_FE_MSK | UART_RDS_PE_MSK);
+		port->icount.brk++;
+		if (uart_handle_break(port))
+			goto ignore_char;
+	} else if (rds & UART_RDS_PE_MSK)
+		port->icount.parity++;
+	else if (rds & UART_RDS_PE_MSK)
+		port->icount.frame++;
+	if (rds & UART_RDS_OE_MSK)
+		port->icount.overrun++;
+
+	if (rds & port->ignore_status_mask) {
+		if (++ignored > 100)
+			goto out;
+		goto ignore_char;
+	}
+	rds &= port->read_status_mask;
+
+	if (rds & UART_RDS_BI_MSK)
+		flg = TTY_BREAK;
+	else if (rds & UART_RDS_PE_MSK)
+		flg = TTY_PARITY;
+	else if (rds & UART_RDS_FE_MSK)
+		flg = TTY_FRAME;
+
+	if (status & UART_RDS_OE_MSK) {
+		/*
+		 * CHECK: does overrun affect the current character?
+		 * ASSUMPTION: it does not.
+		 */
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		ch = 0;
+		flg = TTY_OVERRUN;
+	}
+#ifdef SUPPORT_SYSRQ
+	port->sysrq = 0;
+#endif
+	goto error_return;
+}
+
+static void uart00_tx_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+	int count;
+
+	if (port->x_char) {
+		while ((UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK) == 15);
+		UART_PUT_CHAR(port, port->x_char);
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		uart00_stop_tx(port, 0);
+		return;
+	}
+
+	count = port->fifosize >> 1;
+	do {
+		while ((UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK) == 15);
+		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_event(port, EVT_WRITE_WAKEUP);
+
+	if (uart_circ_empty(xmit))
+		uart00_stop_tx(port, 0);
+}
+
+static void uart00_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	UART_PUT_IES(port, UART_IES_TIE_MSK);
+	uart00_tx_chars(port);
+}
+
+static void uart00_modem_status(struct uart_port *port)
+{
+	unsigned int status;
+
+	status = UART_GET_MSR(port);
+
+	if (!status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK | 
+		       UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK))
+		return;
+
+	if (status & UART_MSR_DDCD_MSK)
+		uart_handle_dcd_change(port, status & UART_MSR_DCD_MSK);
+
+	if (status & UART_MSR_DDSR_MSK)
+		port->icount.dsr++;
+
+	if (status & UART_MSR_DCTS_MSK)
+		uart_handle_cts_change(port, status & UART_MSR_CTS_MSK);
+
+	wake_up_interruptible(&port->info->delta_msr_wait);
+}
+
+static void uart00_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = dev_id;
+	unsigned int status, pass_counter = 0;
+
+	status = UART_GET_INT_STATUS(port);
+	do {
+		if (status & UART_ISR_RI_MSK)
+			uart00_rx_chars(port, regs);
+		if (status & UART_ISR_MI_MSK)
+			uart00_modem_status(port);
+		if (status & (UART_ISR_TI_MSK | UART_ISR_TII_MSK))
+			uart00_tx_chars(port);
+		if (pass_counter++ > UART00_ISR_PASS_LIMIT)
+			break;
+
+		status = UART_GET_INT_STATUS(port);
+	} while (status);
+}
+
+static unsigned int uart00_tx_empty(struct uart_port *port)
+{
+	return UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int uart00_get_mctrl(struct uart_port *port)
+{
+	unsigned int result = 0;
+	unsigned int status;
+
+	status = UART_GET_MSR(port);
+	if (status & UART_MSR_DCD_MSK)
+		result |= TIOCM_CAR;
+	if (status & UART_MSR_DSR_MSK)
+		result |= TIOCM_DSR;
+	if (status & UART_MSR_CTS_MSK)
+		result |= TIOCM_CTS;
+	if (status & UART_MSR_RI_MSK)
+		result |= TIOCM_RI;
+
+	return result;
+}
+
+static void uart00_set_mctrl_null(struct uart_port *port, unsigned int mctrl)
+{
+}
+
+static void uart00_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+	unsigned int mcr;
+
+	spin_lock_irqsave(&port->lock, flags);
+	mcr = UART_GET_MCR(port);
+	if (break_state == -1)
+		mcr |= UART_MCR_BR_MSK;
+	else
+		mcr &= ~UART_MCR_BR_MSK;
+	UART_PUT_MCR(port, mcr);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void
+uart00_change_speed(struct uart_port *port, unsigned int cflag,
+		    unsigned int iflag, unsigned int quot)
+{
+	unsigned int uart_mc, old_ies;
+	unsigned long flags;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5:
+		uart_mc = UART_MC_CLS_CHARLEN_5;
+		break;
+	case CS6:
+		uart_mc = UART_MC_CLS_CHARLEN_6;
+		break;
+	case CS7:
+		uart_mc = UART_MC_CLS_CHARLEN_7;
+		break;
+	default: // CS8
+		uart_mc = UART_MC_CLS_CHARLEN_8;
+		break;
+	}
+	if (cflag & CSTOPB)
+		uart_mc|= UART_MC_ST_TWO;
+	if (cflag & PARENB) {
+		uart_mc |= UART_MC_PE_MSK;
+		if (!(cflag & PARODD))
+			uart_mc |= UART_MC_EP_MSK;
+	}
+
+	port->read_status_mask = UART_RDS_OE_MSK;
+	if (iflag & INPCK)
+		port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
+	if (iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= UART_RDS_BI_MSK;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
+	if (iflag & IGNBRK) {
+		port->ignore_status_mask |= UART_RDS_BI_MSK;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns to (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= UART_RDS_OE_MSK;
+	}
+
+	/* first, disable everything */
+	spin_lock_irqsave(&port->lock, flags);
+	old_ies = UART_GET_IES(port); 
+
+	if (UART_ENABLE_MS(port, cflag))
+		old_ies |= UART_IES_ME_MSK;
+
+	/* Set baud rate */
+	UART_PUT_DIV_LO(port, (quot & 0xff));
+	UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
+
+	UART_PUT_MC(port, uart_mc);
+	UART_PUT_IES(port, old_ies);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int uart00_startup(struct uart_port *port)
+{
+	int result;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	result = request_irq(port->irq, uart00_int, 0, "uart00", port);
+	if (result) {
+		printk(KERN_ERR "Request of irq %d failed\n", port->irq);
+		return result;
+	}
+
+	/*
+	 * Finally, enable interrupts. Use the TII interrupt to minimise 
+	 * the number of interrupts generated. If higher performance is 
+	 * needed, consider using the TI interrupt with a suitable FIFO
+	 * threshold
+	 */
+	UART_PUT_IES(port, UART_IES_RE_MSK | UART_IES_TIE_MSK);
+
+	return 0;
+}
+
+static void uart00_shutdown(struct uart_port *port)
+{
+	/*
+	 * disable all interrupts, disable the port
+	 */
+	UART_PUT_IEC(port, 0xff);
+
+	/* disable break condition and fifos */
+	UART_PUT_MCR(port, UART_GET_MCR(port) &~UART_MCR_BR_MSK);
+
+        /*
+	 * Free the interrupt
+	 */
+	free_irq(port->irq, port);
+}
+
+static const char *uart00_type(struct uart_port *port)
+{
+	return port->type == PORT_UART00 ? "Altera UART00" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void uart00_release_port(struct uart_port *port)
+{
+	release_mem_region(port->mapbase, UART_PORT_SIZE);
+
+#ifdef CONFIG_ARCH_CAMELOT
+	if (port->membase != (void*)IO_ADDRESS(EXC_UART00_BASE)) {
+		iounmap(port->membase);
+	}
+#endif
+}
+
+/*
+ * Request the memory region(s) being used by 'port'
+ */
+static int uart00_request_port(struct uart_port *port)
+{
+	return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_uart00")
+			!= NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void uart00_config_port(struct uart_port *port, int flags)
+{
+
+	/*
+	 * Map the io memory if this is a soft uart
+	 */
+	if (!port->membase)
+		port->membase = ioremap_nocache(port->mapbase,SZ_4K);
+
+	if (!port->membase)
+		printk(KERN_ERR "serial00: cannot map io memory\n");
+	else
+		port->type = PORT_UART00;
+
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int uart00_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
+		ret = -EINVAL;
+	if (ser->irq < 0 || ser->irq >= NR_IRQS)
+		ret = -EINVAL;
+	if (ser->baud_base < 9600)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops uart00_pops = {
+	tx_empty:	uart00_tx_empty,
+	set_mctrl:	uart00_set_mctrl_null,
+	get_mctrl:	uart00_get_mctrl,
+	stop_tx:	uart00_stop_tx,
+	start_tx:	uart00_start_tx,
+	stop_rx:	uart00_stop_rx,
+	enable_ms:	uart00_enable_ms,
+	break_ctl:	uart00_break_ctl,
+	startup:	uart00_startup,
+	shutdown:	uart00_shutdown,
+	change_speed:	uart00_change_speed,
+	type:		uart00_type,
+	release_port:	uart00_release_port,
+	request_port:	uart00_request_port,
+	config_port:	uart00_config_port,
+	verify_port:	uart00_verify_port,
+};
+
+
+#ifdef CONFIG_ARCH_CAMELOT
+static struct uart_port epxa10db_port = {
+	membase:	(void*)IO_ADDRESS(EXC_UART00_BASE),
+	mapbase:         EXC_UART00_BASE,
+	iotype:         SERIAL_IO_MEM,
+	irq:		IRQ_UART,
+	uartclk:	EXC_AHB2_CLK_FREQUENCY,
+	fifosize:	16,
+	ops:		&uart00_pops,
+	flags:          ASYNC_BOOT_AUTOCONF,
+};
+#endif
+
+
+#ifdef CONFIG_SERIAL_UART00_CONSOLE
+static void uart00_console_write(struct console *co, const char *s, unsigned count)
+{
+#ifdef CONFIG_ARCH_CAMELOT
+	struct uart_port *port = &epxa10db_port;
+	unsigned int status, old_ies;
+	int i;
+
+	/*
+	 *	First save the CR then disable the interrupts
+	 */
+	old_ies = UART_GET_IES(port);
+	UART_PUT_IEC(port,0xff);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_TSR(port);
+		} while (!UART_TX_READY(status));
+		UART_PUT_CHAR(port, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_TSR(port);
+			} while (!UART_TX_READY(status));
+			UART_PUT_CHAR(port, '\r');
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the IES
+	 */
+	do {
+		status = UART_GET_TSR(port);
+	} while (status & UART_TSR_TX_LEVEL_MSK);
+	UART_PUT_IES(port, old_ies);
+#endif
+}
+
+static kdev_t uart00_console_device(struct console *co)
+{
+	return mk_kdev(SERIAL_UART00_MAJOR, SERIAL_UART00_MINOR + co->index);
+}
+
+static void __init
+uart00_console_get_options(struct uart_port *port, int *baud,
+			   int *parity, int *bits)
+{
+	unsigned int uart_mc, quot;
+
+	uart_mc = UART_GET_MC(port);
+
+	*parity = 'n';
+	if (uart_mc & UART_MC_PE_MSK) {
+		if (uart_mc & UART_MC_EP_MSK)
+			*parity = 'e';
+		else
+			*parity = 'o';
+	}
+
+	switch (uart_mc & UART_MC_CLS_MSK) {
+	case UART_MC_CLS_CHARLEN_5:
+		*bits = 5;
+		break;
+	case UART_MC_CLS_CHARLEN_6:
+		*bits = 6;
+		break;
+	case UART_MC_CLS_CHARLEN_7:
+		*bits = 7;
+		break;
+	case UART_MC_CLS_CHARLEN_8:
+		*bits = 8;
+		break;
+	}
+	quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8);
+	*baud = port->uartclk / (16 *quot );
+}
+
+static int __init uart00_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 38400;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+#ifdef CONFIG_ARCH_CAMELOT
+	port = &epxa10db_port;             ;
+#else
+	return -ENODEV;
+#endif
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		uart00_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console uart00_console = {
+	name:           SERIAL_UART00_NAME,
+	write:		uart00_console_write,
+	device:		uart00_console_device,
+	setup:		uart00_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		0,
+};
+
+void __init uart00_console_init(void)
+{
+	register_console(&uart00_console);
+}
+
+#define UART00_CONSOLE	&uart00_console
+#else
+#define UART00_CONSOLE	NULL
+#endif
+
+static struct uart_driver uart00_reg = {
+	owner:                  NULL,
+	driver_name:		SERIAL_UART00_NAME,
+	dev_name:		SERIAL_UART00_NAME,
+	major:			SERIAL_UART00_MAJOR,
+	minor:			SERIAL_UART00_MINOR,
+	nr:			UART_NR,
+	cons:			UART00_CONSOLE,
+};
+
+struct dev_port_entry{
+	unsigned int base_addr;
+	struct uart_port *port;
+};
+
+static struct dev_port_entry dev_port_map[UART_NR];
+
+#ifdef CONFIG_PLD_HOTSWAP
+/*
+ * Keep a mapping of dev_info addresses -> port lines to use when
+ * removing ports dev==NULL indicates unused entry
+ */
+
+struct uart00_ps_data{
+	unsigned int clk;
+	unsigned int fifosize;
+};
+
+int uart00_add_device(struct pldhs_dev_info* dev_info, void* dev_ps_data)
+{
+	struct uart00_ps_data* dev_ps=dev_ps_data;
+	struct uart_port * port;
+	int i,result;
+
+	i=0;
+	while(dev_port_map[i].port)
+		i++;
+
+	if(i==UART_NR){
+		printk(KERN_WARNING "uart00: Maximum number of ports reached\n");
+		return 0;
+	}
+
+	port=kmalloc(sizeof(struct uart_port),GFP_KERNEL);
+	if(!port)
+		return -ENOMEM;
+
+	printk("clk=%d fifo=%d\n",dev_ps->clk,dev_ps->fifosize);
+	port->membase=0;
+	port->mapbase=dev_info->base_addr;
+	port->iotype=SERIAL_IO_MEM;
+	port->irq=dev_info->irq;
+	port->uartclk=dev_ps->clk;
+	port->fifosize=dev_ps->fifosize;
+	port->ops=&uart00_pops;
+	port->line=i;
+	port->flags=ASYNC_BOOT_AUTOCONF;
+
+	result=uart_add_one_port(&uart00_reg, port);
+	if(result){
+		printk("uart_add_one_port returned %d\n",result);
+		return result;
+	}
+	dev_port_map[i].base_addr=dev_info->base_addr;
+	dev_port_map[i].port=port;
+	printk("uart00: added device at %x as ttyUA%d\n",dev_port_map[i].base_addr,i);
+	return 0;
+
+}
+
+int uart00_remove_devices(void)
+{
+	int i,result;
+
+
+	result=0;
+	for(i=1;i<UART_NR;i++){
+		if(dev_port_map[i].base_addr){
+			result=uart_remove_one_port(&uart00_reg, dev_port_map[i].port);
+			if(result)
+				return result;
+
+			/* port removed sucessfully, so now tidy up */
+			kfree(dev_port_map[i].port);
+			dev_port_map[i].base_addr=0;
+			dev_port_map[i].port=NULL;
+		}
+	}
+	return 0;
+
+}
+
+struct pld_hotswap_ops uart00_pldhs_ops={
+	name: "uart00",
+	add_device: uart00_add_device,
+	remove_devices:uart00_remove_devices,
+};
+
+#endif
+
+static int __init uart00_init(void)
+{
+	int result;
+
+	printk(KERN_INFO "Serial: UART00 driver $Revision: 1.33 $\n");
+
+	printk(KERN_WARNING "serial_uart00:Using temporary major/minor pairs"
+		" - these WILL change in the future\n");
+
+	result = uart_register_driver(&uart00_reg);
+	if (result)
+		return result;
+#ifdef CONFIG_ARCH_CAMELOT
+	result = uart_add_one_port(&uart00_reg,&epxa10db_port);
+#endif
+	if (result)
+		uart_unregister_driver(&uart00_reg);
+
+#ifdef  CONFIG_PLD_HOTSWAP
+	pldhs_register_driver(&uart00_pldhs_ops);
+#endif
+	return result;
+}
+
+__initcall(uart00_init);
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/usb/core/message.c	Wed Jul 24 14:03:36 2002
@@ -436,17 +436,21 @@
  * Within any given configuration, each interface may have several
  * alternative settings.  These are often used to control levels of
  * bandwidth consumption.  For example, the default setting for a high
- * speed interrupt endpoint may not send more than about 4KBytes per
- * microframe, and isochronous endpoints may never be part of a an
+ * speed interrupt endpoint may not send more than 64 bytes per microframe,
+ * while interrupt transfers of up to 3KBytes per microframe are legal.
+ * Also, isochronous endpoints may never be part of an
  * interface's default setting.  To access such bandwidth, alternate
- * interface setting must be made current.
+ * interface settings must be made current.
  *
  * Note that in the Linux USB subsystem, bandwidth associated with
- * an endpoint in a given alternate setting is not reserved until an
+ * an endpoint in a given alternate setting is not reserved until an URB
  * is submitted that needs that bandwidth.  Some other operating systems
  * allocate bandwidth early, when a configuration is chosen.
  *
  * This call is synchronous, and may not be used in an interrupt context.
+ * Also, drivers must not change altsettings while urbs are scheduled for
+ * endpoints in that interface; all such urbs must first be completed
+ * (perhaps forced by unlinking).
  *
  * Returns zero on success, or else the status code returned by the
  * underlying usb_control_msg() call.
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/usb/core/usb.c	Wed Jul 24 14:03:38 2002
@@ -832,7 +832,7 @@
 
 	if (off)
 		return 0;
-	udev = list_entry (dev, struct usb_device, dev);
+	udev = to_usb_device (dev);
 	return sprintf (buf, "%u\n", udev->actconfig->bConfigurationValue);
 }
 static struct driver_file_entry usb_config_entry = {
@@ -851,7 +851,7 @@
 
 	if (off)
 		return 0;
-	interface = list_entry (dev, struct usb_interface, dev);
+	interface = to_usb_interface (dev);
 	return sprintf (buf, "%u\n", interface->altsetting->bAlternateSetting);
 }
 static struct driver_file_entry usb_altsetting_entry = {
@@ -868,7 +868,7 @@
 
 	if (off)
 		return 0;
-	udev = list_entry (dev, struct usb_device, dev);
+	udev = to_usb_device (dev);
 
 	len = usb_string(udev, udev->descriptor.iProduct, buf, PAGE_SIZE); 
 	buf[len] = '\n';
@@ -890,7 +890,7 @@
 
 	if (off)
 		return 0;
-	udev = list_entry (dev, struct usb_device, dev);
+	udev = to_usb_device (dev);
 
 	len = usb_string(udev, udev->descriptor.iManufacturer, buf, PAGE_SIZE); 
 	buf[len] = '\n';
@@ -912,7 +912,7 @@
 
 	if (off)
 		return 0;
-	udev = list_entry (dev, struct usb_device, dev);
+	udev = to_usb_device (dev);
 
 	len = usb_string(udev, udev->descriptor.iSerialNumber, buf, PAGE_SIZE); 
 	buf[len] = '\n';
@@ -947,8 +947,9 @@
 		/* register this interface with driverfs */
 		interface->dev.parent = &dev->dev;
 		interface->dev.bus = &usb_bus_type;
-		sprintf (&interface->dev.bus_id[0], "if%d",
-			interface->altsetting->bInterfaceNumber);
+		sprintf (&interface->dev.bus_id[0], "%s:%d",
+			 dev->devpath,
+			 interface->altsetting->bInterfaceNumber);
 		if (!desc->iInterface
 				|| usb_string (dev, desc->iInterface,
 					interface->dev.name,
@@ -1288,56 +1289,59 @@
  */
 static void set_device_description (struct usb_device *dev)
 {
-	char	*buf, *here, *end;
+	void    *buf;
 	int	mfgr = dev->descriptor.iManufacturer;
 	int	prod = dev->descriptor.iProduct;
+	int	vendor_id = dev->descriptor.idVendor;
+	int	product_id = dev->descriptor.idProduct;
+	char	*mfgr_str, *prod_str;
 
-	/* set default; keep it if there are no strings */
+	/* set default; keep it if there are no strings, or kmalloc fails */
 	sprintf (dev->dev.name, "USB device %04x:%04x",
-		 dev->descriptor.idVendor,
-		 dev->descriptor.idProduct);
-	if (!mfgr && !prod)
-		return;
+		 vendor_id, product_id);
 
-	if (!(buf = kmalloc(256, GFP_KERNEL)))
+	if (!(buf = kmalloc(256 * 2, GFP_KERNEL)))
 		return;
-	here = dev->dev.name;
-	end = here + sizeof dev->dev.name - 2;
-	*end = 0;
+	
+	prod_str = (char *) buf;
+	mfgr_str = (char *) buf + 256;
 
-	/* much like pci ... describe as either:
-	 * - both strings:   'product descr (vendor descr)'
-	 * - product only:   'product descr (USB device vvvv:pppp)'
-	 * - vendor only:    'USB device vvvv:pppp (vendor descr)'
-	 * - neither string: 'USB device vvvv:pppp'
-	 */
-	if (prod && usb_string (dev, prod, buf, 256) > 0) {
-		strncpy (here, buf, end - here);
+	if (prod && usb_string (dev, prod, prod_str, 256) > 0) {
 #ifdef DEBUG
-		printk (KERN_INFO "Product: %s\n", buf);
+		printk (KERN_INFO "Product: %s\n", prod_str);
 #endif
 	} else {
-		buf [0] = 0;
-		prod = -1;
+		prod_str = 0;
 	}
-	here = strchr (here, 0);
-	if (mfgr && usb_string (dev, mfgr, buf, 256) > 0) {
-		*here++ = ' ';
-		*here++ = '(';
-		strncpy (here, buf, end - here - 1);
-		here = strchr (here, 0);
-		*here++ = ')';
+
+	if (mfgr && usb_string (dev, mfgr, mfgr_str, 256) > 0) {
 #ifdef DEBUG
-		printk (KERN_INFO "Manufacturer: %s\n", buf);
+		printk (KERN_INFO "Manufacturer: %s\n", mfgr_str);
 #endif
 	} else {
-		if (prod != -1)
-			snprintf (here, end - here - 1,
-				" (USB device %04x:%04x)",
-				dev->descriptor.idVendor,
-				dev->descriptor.idProduct);
-		/* both strings unavailable, keep the default */
+		mfgr_str = 0;
+	}
+
+	/* much like pci ... describe as either:
+	 * - both strings:   'product descr (vendor descr)'
+	 * - product only:   'product descr (USB device vvvv:pppp)'
+	 * - vendor only:    'USB device vvvv:pppp (vendor descr)'
+	 * - neither string: 'USB device vvvv:pppp'
+	 */
+
+	if (prod_str && mfgr_str) {
+		snprintf(dev->dev.name, sizeof dev->dev.name,
+			 "%s (%s)", prod_str, mfgr_str);
+	} else if (prod_str) {
+		snprintf(dev->dev.name, sizeof dev->dev.name,
+			 "%s (USB device %04x:%04x)",
+			 prod_str, vendor_id, product_id);
+	} else if (mfgr_str) {
+		snprintf(dev->dev.name, sizeof dev->dev.name,
+			 "USB device %04x:%04x (%s)",
+			 vendor_id, product_id, mfgr_str);
 	}
+
 	kfree(buf);
 }
 
diff -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
--- a/drivers/usb/host/ohci-sa1111.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/usb/host/ohci-sa1111.c	Wed Jul 24 14:03:38 2002
@@ -14,6 +14,7 @@
  */
  
 #include <asm/hardware.h>
+#include <asm/mach-types.h>
 #include <asm/arch/assabet.h>
 #include <asm/arch/badge4.h>
 #include <asm/hardware/sa1111.h>
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/usb/host/uhci-hcd.c	Wed Jul 24 14:03:39 2002
@@ -2053,6 +2053,8 @@
 
 	/* Run and mark it configured with a 64-byte max packet */
 	outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
+
+        uhci->hcd.state = USB_STATE_READY;
 }
 
 #ifdef CONFIG_PROC_FS
@@ -2343,8 +2345,6 @@
 
 	/* disable legacy emulation */
 	pci_write_config_word(dev, USBLEGSUP, USBLEGSUP_DEFAULT);
-
-        hcd->state = USB_STATE_READY;
 
 	usb_connect(uhci->rh_dev);
         uhci->rh_dev->speed = USB_SPEED_FULL;
diff -Nru a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
--- a/drivers/usb/input/hid-ff.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/usb/input/hid-ff.c	Wed Jul 24 14:03:38 2002
@@ -83,7 +83,7 @@
 			       hid->dev->descriptor.idProduct);
 
 	if (!init) {
-		warn("hid_ff_init could not find initializer");
+		dbg("hid_ff_init could not find initializer");
 		return -ENOSYS;
 	}
 	return init->init(hid);
diff -Nru a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
--- a/drivers/usb/misc/rio500.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/usb/misc/rio500.c	Wed Jul 24 14:03:35 2002
@@ -146,7 +146,7 @@
 			retval = -EFAULT;
 			goto err_out;
 		}
-		if (rio_cmd.length > PAGE_SIZE) {
+		if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
 			retval = -EINVAL;
 			goto err_out;
 		}
@@ -216,7 +216,7 @@
 			retval = -EFAULT;
 			goto err_out;
 		}
-		if (rio_cmd.length > PAGE_SIZE) {
+		if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) {
 			retval = -EINVAL;
 			goto err_out;
 		}
diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c
--- a/drivers/usb/misc/tiglusb.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/usb/misc/tiglusb.c	Wed Jul 24 14:03:35 2002
@@ -2,18 +2,29 @@
  *
  * tiglusb -- Texas Instruments' USB GraphLink (aka SilverLink) driver.
  * Target: Texas Instruments graphing calculators (http://lpg.ticalc.org).
- *      
- * Copyright (C) 2001-2002: 
+ *
+ * Copyright (C) 2001-2002:
  *   Romain Lievin <roms@lpg.ticalc.org>
  *   Julien BLACHE <jb@technologeek.org>
  * under the terms of the GNU General Public License.
  *
  * Based on dabusb.c, printer.c & scanner.c
  *
- * Please see the file: linux/Documentation/usb/SilverLink.txt 
+ * Please see the file: linux/Documentation/usb/SilverLink.txt
  * and the website at:  http://lpg.ticalc.org/prj_usb/
  * for more info.
  *
+ * History :
+ *  16/07/2002 : v1.04 -- Julien BLACHE <jb@jblache.org>
+ *    + removed useless usblp_cleanup()
+ *    + removed {un,}lock_kernel() as suggested on lkml
+ *    + inlined clear_pipes() (used once)
+ *    + inlined clear_device() (small, used twice)
+ *    + removed tiglusb_find_struct() (used once, simple code)
+ *    + replaced down() with down_interruptible() wherever possible
+ *    + fixed double unregistering wrt devfs, causing devfs
+ *      to force an oops when the device is deconnected
+ *    + removed unused fields from struct tiglusb_t
  */
 
 #include <linux/module.h>
@@ -30,15 +41,18 @@
 #include <linux/ticable.h>
 #include "tiglusb.h"
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+# define minor(x) MINOR(x)
+#endif
+
 /*
  * Version Information
  */
-#define DRIVER_VERSION "1.03"
+#define DRIVER_VERSION "1.04"
 #define DRIVER_AUTHOR  "Romain Lievin <roms@lpg.ticalc.org> & Julien Blache <jb@jblache.org>"
 #define DRIVER_DESC    "TI-GRAPH LINK USB (aka SilverLink) driver"
 #define DRIVER_LICENSE "GPL"
 
-
 /* ----- global variables --------------------------------------------- */
 
 static tiglusb_t tiglusb[MAXTIGL];
@@ -48,48 +62,47 @@
 
 /*---------- misc functions ------------------------------------------- */
 
-/* Unregister device */
-static void usblp_cleanup (tiglusb_t * s)
-{
-	devfs_unregister (s->devfs);
-	//memset(tiglusb[s->minor], 0, sizeof(tiglusb_t));
-	info ("tiglusb%d removed", s->minor);
-}
-
-/* Re-initialize device */
-static int clear_device (struct usb_device *dev)
+/*
+ * Re-initialize device
+ */
+static inline int
+clear_device (struct usb_device *dev)
 {
 	if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) {
-		err ("tiglusb: clear_device failed");
+		err ("clear_device failed");
 		return -1;
 	}
 
 	return 0;
 }
 
-/* Clear input & output pipes (endpoints) */
-static int clear_pipes (struct usb_device *dev)
+/* 
+ * Clear input & output pipes (endpoints)
+ */
+static inline int
+clear_pipes (struct usb_device *dev)
 {
 	unsigned int pipe;
 
 	pipe = usb_sndbulkpipe (dev, 1);
 	if (usb_clear_halt (dev, usb_pipeendpoint (pipe))) {
-		err("tiglusb: clear_pipe (r), request failed");
+		err ("clear_pipe (r), request failed");
 		return -1;
 	}
 
 	pipe = usb_sndbulkpipe (dev, 2);
 	if (usb_clear_halt (dev, usb_pipeendpoint (pipe))) {
-		err ("tiglusb: clear_pipe (w), request failed");
+		err ("clear_pipe (w), request failed");
 		return -1;
 	}
 
 	return 0;
 }
 
-/* ----- kernel module functions--------------------------------------- */
+/* ----- file operations functions--------------------------------------- */
 
-static int tiglusb_open (struct inode *inode, struct file *file)
+static int
+tiglusb_open (struct inode *inode, struct file *filp)
 {
 	int devnum = minor (inode->i_rdev);
 	ptiglusb_t s;
@@ -99,37 +112,46 @@
 
 	s = &tiglusb[devnum - TIUSB_MINOR];
 
-	down (&s->mutex);
+	if (down_interruptible (&s->mutex)) {
+		return -ERESTARTSYS;
+	}
 
 	while (!s->dev || s->opened) {
 		up (&s->mutex);
 
-		if (file->f_flags & O_NONBLOCK) {
+		if (filp->f_flags & O_NONBLOCK) {
 			return -EBUSY;
 		}
+
 		schedule_timeout (HZ / 2);
 
 		if (signal_pending (current)) {
 			return -EAGAIN;
 		}
-		down (&s->mutex);
+
+		if (down_interruptible (&s->mutex)) {
+			return -ERESTARTSYS;
+		}
 	}
 
 	s->opened = 1;
 	up (&s->mutex);
 
-	file->f_pos = 0;
-	file->private_data = s;
+	filp->f_pos = 0;
+	filp->private_data = s;
 
 	return 0;
 }
 
-static int tiglusb_release (struct inode *inode, struct file *file)
+static int
+tiglusb_release (struct inode *inode, struct file *filp)
 {
-	ptiglusb_t s = (ptiglusb_t) file->private_data;
+	ptiglusb_t s = (ptiglusb_t) filp->private_data;
+
+	if (down_interruptible (&s->mutex)) {
+		return -ERESTARTSYS;
+	}
 
-	lock_kernel ();
-	down (&s->mutex);
 	s->state = _stopped;
 	up (&s->mutex);
 
@@ -139,14 +161,14 @@
 		wake_up (&s->remove_ok);
 
 	s->opened = 0;
-	unlock_kernel ();
 
 	return 0;
 }
 
-static ssize_t tiglusb_read (struct file *file, char *buf, size_t count, loff_t * ppos)
+static ssize_t
+tiglusb_read (struct file *filp, char *buf, size_t count, loff_t * f_pos)
 {
-	ptiglusb_t s = (ptiglusb_t) file->private_data;
+	ptiglusb_t s = (ptiglusb_t) filp->private_data;
 	ssize_t ret = 0;
 	int bytes_to_read = 0;
 	int bytes_read = 0;
@@ -154,7 +176,7 @@
 	char buffer[BULK_RCV_MAX];
 	unsigned int pipe;
 
-	if (*ppos)
+	if (*f_pos)
 		return -ESPIPE;
 
 	if (s->remove_pending)
@@ -171,35 +193,35 @@
 	if (result == -ETIMEDOUT) {	/* NAK */
 		ret = result;
 		if (!bytes_read) {
-			warn ("quirk !");
+			dbg ("quirk !");
 		}
 		warn ("tiglusb_read, NAK received.");
 		goto out;
 	} else if (result == -EPIPE) {	/* STALL -- shouldn't happen */
-		warn ("CLEAR_FEATURE request to remove STALL condition.\n");
+		warn ("clear_halt request to remove STALL condition.");
 		if (usb_clear_halt (s->dev, usb_pipeendpoint (pipe)))
-			warn ("send_packet, request failed\n");
-		//clear_device(s->dev);
+			err ("clear_halt, request failed");
+		clear_device (s->dev);
 		ret = result;
 		goto out;
 	} else if (result < 0) {	/* We should not get any I/O errors */
-		warn ("funky result: %d. Please notify maintainer.", result);
+		err ("funky result: %d. Please notify maintainer.", result);
 		ret = -EIO;
 		goto out;
 	}
 
 	if (copy_to_user (buf, buffer, bytes_read)) {
 		ret = -EFAULT;
-		goto out;
 	}
 
       out:
 	return ret ? ret : bytes_read;
 }
 
-static ssize_t tiglusb_write (struct file *file, const char *buf, size_t count, loff_t * ppos)
+static ssize_t
+tiglusb_write (struct file *filp, const char *buf, size_t count, loff_t * f_pos)
 {
-	ptiglusb_t s = (ptiglusb_t) file->private_data;
+	ptiglusb_t s = (ptiglusb_t) filp->private_data;
 	ssize_t ret = 0;
 	int bytes_to_write = 0;
 	int bytes_written = 0;
@@ -207,7 +229,7 @@
 	char buffer[BULK_SND_MAX];
 	unsigned int pipe;
 
-	if (*ppos)
+	if (*f_pos)
 		return -ESPIPE;
 
 	if (s->remove_pending)
@@ -231,10 +253,10 @@
 		ret = result;
 		goto out;
 	} else if (result == -EPIPE) {	/* STALL -- shouldn't happen */
-		warn ("CLEAR_FEATURE request to remove STALL condition.");
+		warn ("clear_halt request to remove STALL condition.");
 		if (usb_clear_halt (s->dev, usb_pipeendpoint (pipe)))
-			warn ("send_packet, request failed");
-		//clear_device(s->dev);
+			err ("clear_halt, request failed");
+		clear_device (s->dev);
 		ret = result;
 		goto out;
 	} else if (result < 0) {	/* We should not get any I/O errors */
@@ -245,23 +267,25 @@
 
 	if (bytes_written != bytes_to_write) {
 		ret = -EIO;
-		goto out;
 	}
 
       out:
 	return ret ? ret : bytes_written;
 }
 
-static int tiglusb_ioctl (struct inode *inode, struct file *file,
-			  unsigned int cmd, unsigned long arg)
+static int
+tiglusb_ioctl (struct inode *inode, struct file *filp,
+	       unsigned int cmd, unsigned long arg)
 {
-	ptiglusb_t s = (ptiglusb_t) file->private_data;
+	ptiglusb_t s = (ptiglusb_t) filp->private_data;
 	int ret = 0;
 
 	if (s->remove_pending)
 		return -EIO;
 
-	down (&s->mutex);
+	if (down_interruptible (&s->mutex)) {
+		return -ERESTARTSYS;
+	}
 
 	if (!s->dev) {
 		up (&s->mutex);
@@ -304,40 +328,30 @@
 	.release =	tiglusb_release,
 };
 
-static int tiglusb_find_struct (void)
-{
-	int u;
-
-	for (u = 0; u < MAXTIGL; u++) {
-		ptiglusb_t s = &tiglusb[u];
-		if (!s->dev)
-			return u;
-	}
-
-	return -1;
-}
-
 /* --- initialisation code ------------------------------------- */
 
-static void *tiglusb_probe (struct usb_device *dev, unsigned int ifnum,
-			    const struct usb_device_id *id)
+static void *
+tiglusb_probe (struct usb_device *dev, unsigned int ifnum,
+	       const struct usb_device_id *id)
 {
-	int minor;
+	int minor = -1;
+	int i;
 	ptiglusb_t s;
 	char name[8];
 
-	dbg ("tiglusb: probing vendor id 0x%x, device id 0x%x ifnum:%d",
+	dbg ("probing vendor id 0x%x, device id 0x%x ifnum:%d",
 	     dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
 
-	/* 
-	 * We don't handle multiple configurations. As of version 0x0103 of 
-	 * the TIGL hardware, there's only 1 configuration. 
+	/*
+	 * We don't handle multiple configurations. As of version 0x0103 of
+	 * the TIGL hardware, there's only 1 configuration.
 	 */
 
 	if (dev->descriptor.bNumConfigurations != 1)
 		return NULL;
 
-	if ((dev->descriptor.idProduct != 0xe001) && (dev->descriptor.idVendor != 0x451))
+	if ((dev->descriptor.idProduct != 0xe001)
+	    && (dev->descriptor.idVendor != 0x451))
 		return NULL;
 
 	if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) {
@@ -345,7 +359,17 @@
 		return NULL;
 	}
 
-	minor = tiglusb_find_struct ();
+	/*
+	 * Find a tiglusb struct
+	 */
+	for (i = 0; i < MAXTIGL; i++) {
+		ptiglusb_t s = &tiglusb[i];
+		if (!s->dev) {
+			minor = i;
+			break;
+		}
+	}
+
 	if (minor == -1)
 		return NULL;
 
@@ -358,26 +382,28 @@
 	dbg ("bound to interface: %d", ifnum);
 
 	sprintf (name, "%d", s->minor);
-	info ("tiglusb: registering to devfs : major = %d, minor = %d, node = %s", TIUSB_MAJOR,
-		(TIUSB_MINOR + s->minor), name);
+	dbg ("registering to devfs : major = %d, minor = %d, node = %s",
+	     TIUSB_MAJOR, (TIUSB_MINOR + s->minor), name);
 	s->devfs =
 	    devfs_register (devfs_handle, name, DEVFS_FL_DEFAULT, TIUSB_MAJOR,
-			    TIUSB_MINOR + s->minor, S_IFCHR | S_IRUGO | S_IWUGO, &tiglusb_fops,
-			    NULL);
+			    TIUSB_MINOR + s->minor, S_IFCHR | S_IRUGO | S_IWUGO,
+			    &tiglusb_fops, NULL);
 
 	/* Display firmware version */
-	info ("tiglusb: link cable version %i.%02x",
-		dev->descriptor.bcdDevice >> 8, dev->descriptor.bcdDevice & 0xff);
+	info ("link cable version %i.%02x",
+		dev->descriptor.bcdDevice >> 8,
+		dev->descriptor.bcdDevice & 0xff);
 
 	return s;
 }
 
-static void tiglusb_disconnect (struct usb_device *dev, void *drv_context)
+static void
+tiglusb_disconnect (struct usb_device *dev, void *drv_context)
 {
 	ptiglusb_t s = (ptiglusb_t) drv_context;
 
 	if (!s || !s->dev)
-		warn ("bogus disconnect");
+		info ("bogus disconnect");
 
 	s->remove_pending = 1;
 	wake_up (&s->wait);
@@ -387,16 +413,12 @@
 	s->dev = NULL;
 	s->opened = 0;
 
-	/* cleanup now or later, on close */
-	if (!s->opened)
-		usblp_cleanup (s);
-	else
-		up (&s->mutex);
-
-	/* unregister device */
 	devfs_unregister (s->devfs);
 	s->devfs = NULL;
-	info ("tiglusb: device disconnected");
+
+	info ("device %d removed", s->minor);
+
+	up (&s->mutex);
 }
 
 static struct usb_device_id tiglusb_ids[] = {
@@ -417,9 +439,11 @@
 /* --- initialisation code ------------------------------------- */
 
 #ifndef MODULE
-/*      You must set these - there is no sane way to probe for this cable.
- *      You can use 'tipar=timeout,delay' to set these now. */
-static int __init tiglusb_setup (char *str)
+/*
+ * You can use 'tiusb=timeout'
+ */
+static int __init
+tiglusb_setup (char *str)
 {
 	int ints[2];
 
@@ -433,7 +457,8 @@
 }
 #endif
 
-static int __init tiglusb_init (void)
+static int __init
+tiglusb_init (void)
 {
 	unsigned u;
 	int result;
@@ -452,7 +477,7 @@
 
 	/* register device */
 	if (devfs_register_chrdev (TIUSB_MAJOR, "tiglusb", &tiglusb_fops)) {
-		err ("tiglusb: unable to get major %d", TIUSB_MAJOR);
+		err ("unable to get major %d", TIUSB_MAJOR);
 		return -EIO;
 	}
 
@@ -471,7 +496,8 @@
 	return 0;
 }
 
-static void __exit tiglusb_cleanup (void)
+static void __exit
+tiglusb_cleanup (void)
 {
 	usb_deregister (&tiglusb_driver);
 	devfs_unregister (devfs_handle);
diff -Nru a/drivers/usb/misc/tiglusb.h b/drivers/usb/misc/tiglusb.h
--- a/drivers/usb/misc/tiglusb.h	Wed Jul 24 14:03:39 2002
+++ b/drivers/usb/misc/tiglusb.h	Wed Jul 24 14:03:39 2002
@@ -33,7 +33,6 @@
 {
 	struct usb_device	*dev;		/* USB device handle */
 	struct semaphore	mutex;		/* locks this struct */
-	struct semaphore	sem;
 
 	wait_queue_head_t	wait;		/* for timed waits */
 	wait_queue_head_t	remove_ok;
@@ -44,12 +43,6 @@
 	driver_state_t	state;			/* started/stopped */
 	int		opened;			/* tru if open */
 	int	remove_pending;
-
-	char	rd_buf[BULK_RCV_MAX];		/* read  buffer */
-	char	wr_buf[BULK_SND_MAX];		/* write buffer */
-
 } tiglusb_t, *ptiglusb_t;
-
-extern devfs_handle_t usb_devfs_handle;		/* /dev/usb dir. */
 
 #endif
diff -Nru a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
--- a/drivers/usb/net/rtl8150.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/usb/net/rtl8150.c	Wed Jul 24 14:03:38 2002
@@ -21,7 +21,7 @@
 #include <asm/uaccess.h>
 
 /* Version Information */
-#define DRIVER_VERSION "v0.5.4 (2002/04/11)"
+#define DRIVER_VERSION "v0.5.5 (2002/07/22)"
 #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
 #define DRIVER_DESC "rtl8150 based usb-ethernet driver"
 
@@ -68,11 +68,15 @@
 
 /* Define these values to match your device */
 #define VENDOR_ID_REALTEK		0x0bda
+#define	VENDOR_ID_MELCO			0x0411
+
 #define PRODUCT_ID_RTL8150		0x8150
+#define	PRODUCT_ID_LUAKTX		0x0012
 
 /* table of devices that work with this driver */
 static struct usb_device_id rtl8150_table[] = {
 	{USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8150)},
+	{USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)},
 	{}
 };
 
@@ -727,11 +731,6 @@
 
 	if (usb_set_configuration(udev, udev->config[0].bConfigurationValue)) {
 		err("usb_set_configuration() failed");
-		return NULL;
-	}
-	if ((udev->descriptor.idVendor != VENDOR_ID_REALTEK) ||
-	    (udev->descriptor.idProduct != PRODUCT_ID_RTL8150)) {
-		err("Not the one we are interested about");
 		return NULL;
 	}
 	dev = kmalloc(sizeof(rtl8150_t), GFP_KERNEL);
diff -Nru a/drivers/usb/serial/keyspan_pda.S b/drivers/usb/serial/keyspan_pda.S
--- a/drivers/usb/serial/keyspan_pda.S	Wed Jul 24 14:03:38 2002
+++ b/drivers/usb/serial/keyspan_pda.S	Wed Jul 24 14:03:38 2002
@@ -970,9 +970,9 @@
 	mov r1, #1		; INbuf size counter
 start_in__loop:
 	mov a, rx_ring_in
-	cjne a, rx_ring_out, start_in__still_copying
+	cjne a, rx_ring_out, start_inlocal_irq_enablell_copying
 	sjmp start_in__kick
-start_in__still_copying:
+start_inlocal_irq_enablell_copying:
 	inc rx_ring_out
 	mov dpl, rx_ring_out
 	movx a, @dptr
diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
--- a/drivers/usb/serial/pl2303.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/usb/serial/pl2303.c	Wed Jul 24 14:03:38 2002
@@ -71,6 +71,7 @@
 	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
 	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
 	{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
+	{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
 
diff -Nru a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
--- a/drivers/usb/serial/pl2303.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/usb/serial/pl2303.h	Wed Jul 24 14:03:38 2002
@@ -19,3 +19,6 @@
 
 #define ELCOM_VENDOR_ID		0x056e
 #define ELCOM_PRODUCT_ID	0x5003
+
+#define ITEGNO_VENDOR_ID	0x0eba
+#define ITEGNO_PRODUCT_ID	0x1080
diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/usb/serial/usb-serial.h	Wed Jul 24 14:03:38 2002
@@ -67,11 +67,40 @@
 /* parity check flag */
 #define RELEVANT_IFLAG(iflag)	(iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
 
-
+/**
+ * usb_serial_port: structure for the specific ports of a device.
+ * @magic: magic number for internal validity of this pointer.
+ * @serial: pointer back to the struct usb_serial owner of this port.
+ * @tty: pointer to the coresponding tty for this port.
+ * @number: the number of the port (the minor number).
+ * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
+ * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
+ * @interrupt_in_endpointAddress: endpoint address for the interrupt in pipe
+ *	for this port.
+ * @bulk_in_buffer: pointer to the bulk in buffer for this port.
+ * @read_urb: pointer to the bulk in struct urb for this port.
+ * @bulk_in_endpointAddress: endpoint address for the bulk in pipe for this
+ *	port.
+ * @bulk_out_buffer: pointer to the bulk out buffer for this port.
+ * @bulk_out_size: the size of the bulk_out_buffer, in bytes.
+ * @write_urb: pointer to the bulk out struct urb for this port.
+ * @bulk_out_endpointAddress: endpoint address for the bulk out pipe for this
+ *	port.
+ * @write_wait: a wait_queue_head_t used by the port.
+ * @tqueue: task queue for the line discipline waking up.
+ * @open_count: number of times this port has been opened.
+ * @sem: struct semaphore used to lock this structure.
+ * @private: place to put any driver specific information that is needed.  The
+ *	usb-serial driver is required to manage this data, the usb-serial core
+ *	will not touch this.
+ *
+ * This structure is used by the usb-serial core and drivers for the specific
+ * ports of a device.
+ */
 struct usb_serial_port {
 	int			magic;
-	struct usb_serial	*serial;	/* pointer back to the owner of this port */
-	struct tty_struct *	tty;		/* the coresponding tty for this port */
+	struct usb_serial	*serial;
+	struct tty_struct *	tty;
 	unsigned char		number;
 
 	unsigned char *		interrupt_in_buffer;
@@ -88,30 +117,44 @@
 	__u8			bulk_out_endpointAddress;
 
 	wait_queue_head_t	write_wait;
-
-	struct tq_struct	tqueue;		/* task queue for line discipline waking up */
-	int			open_count;	/* number of times this port has been opened */
-	struct semaphore	sem;		/* locks this structure */
-	
-	void *			private;	/* data private to the specific port */
+	struct tq_struct	tqueue;
+	int			open_count;
+	struct semaphore	sem;
+	void *			private;
 };
 
+/**
+ * usb_serial - structure used by the usb-serial core for a device
+ * @magic: magic number for internal validity of this pointer.
+ * @dev: pointer to the struct usb_device for this device
+ * @type: pointer to the struct usb_serial_device_type for this device
+ * @interface: pointer to the struct usb_interface for this device
+ * @minor: the starting minor number for this device
+ * @num_ports: the number of ports this device has
+ * @num_interrupt_in: number of interrupt in endpoints we have
+ * @num_bulk_in: number of bulk in endpoints we have
+ * @num_bulk_out: number of bulk out endpoints we have
+ * @vendor: vendor id of this device
+ * @product: product id of this device
+ * @port: array of struct usb_serial_port structures for the different ports.
+ * @private: place to put any driver specific information that is needed.  The
+ *	usb-serial driver is required to manage this data, the usb-serial core
+ *	will not touch this.
+ */
 struct usb_serial {
 	int				magic;
 	struct usb_device *		dev;
-	struct usb_serial_device_type *	type;			/* the type of usb serial device this is */
-	struct usb_interface *		interface;		/* the interface for this device */
-	struct tty_driver *		tty_driver;		/* the tty_driver for this device */
-	unsigned char			minor;			/* the starting minor number for this device */
-	unsigned char			num_ports;		/* the number of ports this device has */
-	char				num_interrupt_in;	/* number of interrupt in endpoints we have */
-	char				num_bulk_in;		/* number of bulk in endpoints we have */
-	char				num_bulk_out;		/* number of bulk out endpoints we have */
-	__u16				vendor;			/* vendor id of this device */
-	__u16				product;		/* product id of this device */
+	struct usb_serial_device_type *	type;
+	struct usb_interface *		interface;
+	unsigned char			minor;
+	unsigned char			num_ports;
+	char				num_interrupt_in;
+	char				num_bulk_in;
+	char				num_bulk_out;
+	__u16				vendor;
+	__u16				product;
 	struct usb_serial_port		port[MAX_NUM_PORTS];
-
-	void *			private;		/* data private to the specific driver */
+	void *				private;
 };
 
 
diff -Nru a/drivers/usb/serial/xircom_pgs.S b/drivers/usb/serial/xircom_pgs.S
--- a/drivers/usb/serial/xircom_pgs.S	Wed Jul 24 14:03:35 2002
+++ b/drivers/usb/serial/xircom_pgs.S	Wed Jul 24 14:03:35 2002
@@ -1035,9 +1035,9 @@
 	mov r1, #1		; INbuf size counter
 start_in__loop:
 	mov a, rx_ring_in
-	cjne a, rx_ring_out, start_in__still_copying
+	cjne a, rx_ring_out, start_inlocal_irq_enablell_copying
 	sjmp start_in__kick
-start_in__still_copying:
+start_inlocal_irq_enablell_copying:
 	inc rx_ring_out
 	mov dpl, rx_ring_out
 	movx a, @dptr
diff -Nru a/drivers/video/Config.help b/drivers/video/Config.help
--- a/drivers/video/Config.help	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/Config.help	Wed Jul 24 14:03:36 2002
@@ -77,6 +77,12 @@
   module will be called amifb.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
+CONFIG_FB_PM3
+  This is the frame buffer device driver for the 3DLabs Permedia3
+  chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
+  similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
+  and maybe other boards.
+
 CONFIG_FB_AMIGA_OCS
   This enables support for the original Agnus and Denise video chips,
   found in the Amiga 1000 and most A500's and A2000's. If you intend
@@ -587,6 +593,12 @@
   The IMS Twin Turbo is a PCI-based frame buffer card bundled with
   many Macintosh and compatible computers.
 
+CONFIG_FB_TX3912
+  The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core
+  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
+
+  Say Y here to enable kernel support for the on-board framebuffer.
+
 CONFIG_FB_VIRTUAL
   This is a `virtual' frame buffer device. It operates on a chunk of
   unswappable kernel memory instead of on the memory of a graphics
@@ -704,17 +716,7 @@
   This is the low level frame buffer console driver for 8 interleaved
   bitplanes (256 colors) on Atari.
 
-CONFIG_FBCON_MAC
-  This is the low level frame buffer console driver for 1/2/4/8/16/32
-  bits per pixel packed pixels on Mac. It supports variable font
-  widths for low resolution screens.
-
 CONFIG_FBCON_HGA
   This is the low level frame buffer console driver for Hercules mono
   graphics cards.
-
-CONFIG_FBCON_VGA
-  This is the low level frame buffer console driver for VGA text mode;
-  it is used by frame buffer device drivers that support VGA text
-  mode.
 
diff -Nru a/drivers/video/Config.in b/drivers/video/Config.in
--- a/drivers/video/Config.in	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/Config.in	Wed Jul 24 14:03:38 2002
@@ -108,6 +108,7 @@
       bool '  Sun3 framebuffer support' CONFIG_FB_SUN3
       if [ "$CONFIG_FB_SUN3" != "n" ]; then
          bool '    BWtwo support' CONFIG_FB_BWTWO
+         bool '    CGthree support' CONFIG_FB_CGTHREE
          bool '    CGsix (GX,TurboGX) support' CONFIG_FB_CGSIX
       fi
    fi
@@ -227,41 +228,35 @@
       tristate '    Atari interleaved bitplanes (4 planes) support' CONFIG_FBCON_IPLAN2P4
       tristate '    Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8
 #      tristate '    Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16
-      tristate '    Mac variable bpp packed pixels support' CONFIG_FBCON_MAC
       tristate '    VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES
-      tristate '    VGA characters/attributes support' CONFIG_FBCON_VGA
       tristate '    HGA monochrome support (EXPERIMENTAL)' CONFIG_FBCON_HGA
    else
       # Guess what we need
       if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_AMIGA" = "y" -o \
 	   "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \
-	   "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \
-	   "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
-	   "$CONFIG_FB_BWTWO" = "y" ]; then 
+	   "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \
+	   "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CLGEN" = "y" ]; then
 	 define_tristate CONFIG_FBCON_MFB y
       else
 	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \
 	      "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
-	      "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \
-	      "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
-	      "$CONFIG_FB_BWTWO" = "m" ]; then 
+	      "$CONFIG_FB_BWTWO" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \
+	      "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CLGEN" = "m" ]; then 
 	    define_tristate CONFIG_FBCON_MFB m
 	 fi
       fi
-      if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
-	   "$CONFIG_FB_SA1100" = "y" ]; then 
+      if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then 
 	 define_tristate CONFIG_FBCON_CFB2 y
 	 define_tristate CONFIG_FBCON_CFB4 y
       else
-	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
-	      "$CONFIG_FB_SA1100" = "m" ]; then 
+	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_SA1100" = "m"]; then 
 	    define_tristate CONFIG_FBCON_CFB2 m
 	    define_tristate CONFIG_FBCON_CFB4 m
 	 fi
       fi
       if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
-	   "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
-	   "$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \
+	   "$CONFIG_FB_P9100" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
+	   "$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_TGA" = "y" -o \
 	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
 	   "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
 	   "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
@@ -270,15 +265,12 @@
 	   "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
            "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
 	   "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
-	   "$CONFIG_FB_P9100" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
-	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
-	   "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
-	   "$CONFIG_FB_SA1100" = "y" ]; then 
+	   "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then 
 	 define_tristate CONFIG_FBCON_CFB8 y
       else
 	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
-	      "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
-	      "$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \
+	      "$CONFIG_FB_P9100" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
+	      "$CONFIG_FB_RADEON" = "m" -o "$CONFIG_FB_TGA" = "m" -o \
 	      "$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
 	      "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
 	      "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
@@ -286,40 +278,33 @@
 	      "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
 	      "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
               "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
-	      "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
-	      "$CONFIG_FB_P9100" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
-	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
-	      "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
-	      "$CONFIG_FB_SA1100" = "m" ]; then 
+	      "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m"-o \
+	      "$CONFIG_FB_SA1100" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB8 m
 	 fi
       fi
-      if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
-	   "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
+      if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
+	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
 	   "$CONFIG_FB_TRIDENT" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
 	   "$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
 	   "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
 	   "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \
 	   "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
 	   "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
-	   "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
-	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
-	   "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_PM3" = "y"  -o \
-	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then 
+	   "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
+	   "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then 
 	 define_tristate CONFIG_FBCON_CFB16 y
       else
-	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
-	      "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
+	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
+	      "$CONFIG_FB_RADEON" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
 	      "$CONFIG_FB_TRIDENT" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
 	      "$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
 	      "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
 	      "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
 	      "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
 	      "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
-	      "$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \
-	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
-	      "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
-	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" ]; then 
+	      "$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
+	      "$CONFIG_FB_SA1100" = "y" ]; then 
 	    define_tristate CONFIG_FBCON_CFB16 m
 	 fi
       fi
@@ -340,26 +325,22 @@
 	    define_tristate CONFIG_FBCON_CFB24 m
 	 fi
       fi
-      if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
+      if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
 	   "$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_TRIDENT" = "y" -o \
 	   "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
 	   "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
 	   "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
-	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
-	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
-	   "$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
-	   "$CONFIG_FB_PM3" = "y" ]; then
+	   "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
+	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_ATY" = "y" ]; then 
 	 define_tristate CONFIG_FBCON_CFB32 y
       else
-	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
+	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
 	      "$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_TRIDENT" = "m" -o \
 	      "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
 	      "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
 	      "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
-	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
-	      "$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
-	      "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
-	      "$CONFIG_FB_PVR2" = "m" ]; then
+	      "$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
+	      "$CONFIG_FB_PM3" = "m" ]; then 
 	    define_tristate CONFIG_FBCON_CFB32 m
 	 fi
       fi
@@ -370,12 +351,16 @@
 	   "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_CLPS711X" = "y" -o \
 	   "$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \
 	   "$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \
-	   "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" ]; then
+	   "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \
+	   "$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
+	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_OF" = "y" -o \
+	   "$CONFIG_FB_SGIVW" = "y" ]; then
 	 define_tristate CONFIG_FBCON_ACCEL y
       else
 	 if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \
 	      "$CONFIG_FB_G364" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
-	      "$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" ]; then 
+	      "$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
+	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_SGIVW" = "m" ]; then 
 	    define_tristate CONFIG_FBCON_ACCEL m
          fi       
       fi
@@ -392,20 +377,11 @@
 	 define_tristate CONFIG_FBCON_IPLAN2P2 y
 	 define_tristate CONFIG_FBCON_IPLAN2P4 y
 	 define_tristate CONFIG_FBCON_IPLAN2P8 y
-#	 define_tristate CONFIG_FBCON_IPLAN2P16 y
       else
 	 if [ "$CONFIG_FB_ATARI" = "m" ]; then
 	    define_tristate CONFIG_FBCON_IPLAN2P2 m
 	    define_tristate CONFIG_FBCON_IPLAN2P4 m
 	    define_tristate CONFIG_FBCON_IPLAN2P8 m
-#	    define_tristate CONFIG_FBCON_IPLAN2P16 m
-	 fi
-      fi
-      if [ "$CONFIG_FB_MAC" = "y" ]; then
-	 define_tristate CONFIG_FBCON_MAC  y
-      else
-	 if [ "$CONFIG_FB_MAC" = "m" ]; then
-	    define_tristate CONFIG_FBCON_MAC  m
 	 fi
       fi
       if [ "$CONFIG_FB_VGA16" = "y" ]; then
diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/Makefile	Wed Jul 24 14:03:36 2002
@@ -10,8 +10,8 @@
 		   fbcon-vga.o fbcon-iplan2p2.o fbcon-iplan2p4.o \
 		   fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
 		   fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
-		   fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o \
-		   cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o
+		   fbcon-cfb8.o fbcon-mfb.o fbcon-hga.o \
+		   cyber2000fb.o sa1100fb.o fbgen.o
 
 # Each configuration option enables a list of files.
 
@@ -56,9 +56,9 @@
 obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_CYBER)            += cyberfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
-obj-$(CONFIG_FB_SGIVW)            += sgivwfb.o
+obj-$(CONFIG_FB_SGIVW)            += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_3DFX)             += tdfxfb.o
-obj-$(CONFIG_FB_MAC)              += macfb.o macmodes.o
+obj-$(CONFIG_FB_MAC)              += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_HP300)            += hpfb.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_OF)               += offb.o
 obj-$(CONFIG_FB_IMSTT)            += imsttfb.o
@@ -114,10 +114,7 @@
 obj-$(CONFIG_FBCON_IPLAN2P2)      += fbcon-iplan2p2.o
 obj-$(CONFIG_FBCON_IPLAN2P4)      += fbcon-iplan2p4.o
 obj-$(CONFIG_FBCON_IPLAN2P8)      += fbcon-iplan2p8.o
-obj-$(CONFIG_FBCON_IPLAN2P16)     += fbcon-iplan2p16.o
-obj-$(CONFIG_FBCON_MAC)           += fbcon-mac.o
 obj-$(CONFIG_FBCON_MFB)           += fbcon-mfb.o
-obj-$(CONFIG_FBCON_VGA)           += fbcon-vga.o
 obj-$(CONFIG_FBCON_HGA)           += fbcon-hga.o
 obj-$(CONFIG_FBCON_STI)           += fbcon-sti.o
 obj-$(CONFIG_FBCON_ACCEL)	  += fbcon-accel.o
diff -Nru a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
--- a/drivers/video/S3triofb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/S3triofb.c	Wed Jul 24 14:03:38 2002
@@ -41,9 +41,6 @@
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <linux/pci.h>
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-#endif
 
 #include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
@@ -539,22 +536,6 @@
 #if 0
     fb_info.setcmap = &s3triofbcon_setcmap;
 #endif
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-    if (!console_fb_info) {
-	display_info.height = fb_var.yres;
-	display_info.width = fb_var.xres;
-	display_info.depth = 8;
-	display_info.pitch = fb_fix.line_length;
-	display_info.mode = 0;
-	strncpy(display_info.name, dp->name, sizeof(display_info.name));
-	display_info.fb_address = (unsigned long)fb_fix.smem_start;
-	display_info.disp_reg_address = address + 0x1008000;
-	display_info.cmap_adr_address = address + 0x1008000 + 0x3c8;
-	display_info.cmap_data_address = address + 0x1008000 + 0x3c9;
-	console_fb_info = &fb_info;
-    }
-#endif /* CONFIG_FB_COMPAT_XPMAC) */
 
     fb_info.flags = FBINFO_FLAG_DEFAULT;
     if (register_framebuffer(&fb_info) < 0)
diff -Nru a/drivers/video/amifb.c b/drivers/video/amifb.c
--- a/drivers/video/amifb.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/video/amifb.c	Wed Jul 24 14:03:39 2002
@@ -61,7 +61,6 @@
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
 #include <asm/setup.h>
-#include <asm/io.h>
 
 #include <video/fbcon.h>
 #include <video/fbcon-afb.h>
@@ -1173,16 +1172,51 @@
 	fb_set_cmap:	gen_set_cmap,
 	fb_setcolreg:	amifb_setcolreg,
 	fb_pan_display:	amifb_pan_display,
-	fb_blankL:	amifb_blank,
+	fb_blank:	amifb_blank,
 	fb_ioctl:	amifb_ioctl,
 };
 
+static void __init amifb_setup_mcap(char *spec)
+{
+	char *p;
+	int vmin, vmax, hmin, hmax;
+
+	/* Format for monitor capabilities is: <Vmin>;<Vmax>;<Hmin>;<Hmax>
+	 * <V*> vertical freq. in Hz
+	 * <H*> horizontal freq. in kHz
+	 */
+
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
+	vmin = simple_strtoul(p, NULL, 10);
+	if (vmin <= 0)
+		return;
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
+	vmax = simple_strtoul(p, NULL, 10);
+	if (vmax <= 0 || vmax <= vmin)
+		return;
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
+	hmin = 1000 * simple_strtoul(p, NULL, 10);
+	if (hmin <= 0)
+		return;
+	if (!(p = strsep(&spec, "")) || !*p)
+		return;
+	hmax = 1000 * simple_strtoul(p, NULL, 10);
+	if (hmax <= 0 || hmax <= hmin)
+		return;
+
+	fb_info.monspecs.vfmin = vmin;
+	fb_info.monspecs.vfmax = vmax;
+	fb_info.monspecs.hfmin = hmin;
+	fb_info.monspecs.hfmax = hmax;
+}
+
 int __init amifb_setup(char *options)
 {
 	char *this_opt;
-	char mcap_spec[80];
 
-	mcap_spec[0] = '\0';
 	fb_info.fontname[0] = '\0';
 
 	if (!options || !*options)
@@ -1199,7 +1233,7 @@
 		} else if (!strcmp(this_opt, "ilbm"))
 			amifb_ilbm = 1;
 		else if (!strncmp(this_opt, "monitorcap:", 11))
-			strcpy(mcap_spec, this_opt+11);
+			amifb_setup_mcap(this_opt+11);
 		else if (!strncmp(this_opt, "font:", 5))
 			strcpy(fb_info.fontname, this_opt+5);
 		else if (!strncmp(this_opt, "fstart:", 7))
@@ -1211,43 +1245,6 @@
 	if (min_fstrt < 48)
 		min_fstrt = 48;
 
-	if (*mcap_spec) {
-		char *p;
-		int vmin, vmax, hmin, hmax;
-
-	/* Format for monitor capabilities is: <Vmin>;<Vmax>;<Hmin>;<Hmax>
-	 * <V*> vertical freq. in Hz
-	 * <H*> horizontal freq. in kHz
-	 */
-
-		if (!(p = strsep(&mcap_spec, ";")) || !*p)
-			goto cap_invalid;
-		vmin = simple_strtoul(p, NULL, 10);
-		if (vmin <= 0)
-			goto cap_invalid;
-		if (!(p = strsep(&mcap_spec, ";")) || !*p)
-			goto cap_invalid;
-		vmax = simple_strtoul(p, NULL, 10);
-		if (vmax <= 0 || vmax <= vmin)
-			goto cap_invalid;
-		if (!(p = strsep(&mcap_spec, ";")) || !*p)
-			goto cap_invalid;
-		hmin = 1000 * simple_strtoul(p, NULL, 10);
-		if (hmin <= 0)
-			goto cap_invalid;
-		if (!(p = strsep(&mcap_spec, "")) || !*p)
-			goto cap_invalid;
-		hmax = 1000 * simple_strtoul(p, NULL, 10);
-		if (hmax <= 0 || hmax <= hmin)
-			goto cap_invalid;
-
-		fb_info.monspecs.vfmin = vmin;
-		fb_info.monspecs.vfmax = vmax;
-		fb_info.monspecs.hfmin = hmin;
-		fb_info.monspecs.hfmax = hmax;
-cap_invalid:
-		;
-	}
 	return 0;
 }
 
diff -Nru a/drivers/video/atafb.c b/drivers/video/atafb.c
--- a/drivers/video/atafb.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/atafb.c	Wed Jul 24 14:03:36 2002
@@ -2593,6 +2593,35 @@
 	return -EINVAL;
 }
 
+/* (un)blank/poweroff
+ * 0 = unblank
+ * 1 = blank
+ * 2 = suspend vsync
+ * 3 = suspend hsync
+ * 4 = off
+ */
+static int 
+atafb_blank(int blank, struct fb_info *info)
+{
+	unsigned short black[16];
+	struct fb_cmap cmap;
+	if (fbhw->blank && !fbhw->blank(blank))
+		return 1;
+	if (blank) {
+		memset(black, 0, 16*sizeof(unsigned short));
+		cmap.red=black;
+		cmap.green=black;
+		cmap.blue=black;
+		cmap.transp=NULL;
+		cmap.start=0;
+		cmap.len=16;
+		fb_set_cmap(&cmap, 1, info);
+	}
+	else
+		do_install_cmap(info->currcon, info);
+	return 0;
+}
+
 static struct fb_ops atafb_ops = {
 	owner:		THIS_MODULE,
 	fb_get_fix:	atafb_get_fix,
@@ -2660,35 +2689,6 @@
 	return 0;
 }
 
-/* (un)blank/poweroff
- * 0 = unblank
- * 1 = blank
- * 2 = suspend vsync
- * 3 = suspend hsync
- * 4 = off
- */
-static int 
-atafb_blank(int blank, struct fb_info *info)
-{
-	unsigned short black[16];
-	struct fb_cmap cmap;
-	if (fbhw->blank && !fbhw->blank(blank))
-		return 1;
-	if (blank) {
-		memset(black, 0, 16*sizeof(unsigned short));
-		cmap.red=black;
-		cmap.green=black;
-		cmap.blue=black;
-		cmap.transp=NULL;
-		cmap.start=0;
-		cmap.len=16;
-		fb_set_cmap(&cmap, 1, info);
-	}
-	else
-		do_install_cmap(info->currcon, info);
-	return 0;
-}
-
 int __init atafb_init(void)
 {
 	int pad;
@@ -2702,21 +2702,21 @@
 #ifdef ATAFB_EXT
 		if (external_addr) {
 			fbhw = &ext_switch;
-			fb_info.fb_setcolreg = &ext_setcolreg;
+			atafb_ops.fb_setcolreg = &ext_setcolreg;
 			break;
 		}
 #endif
 #ifdef ATAFB_TT
 		if (ATARIHW_PRESENT(TT_SHIFTER)) {
 			fbhw = &tt_switch;
-			fb_info.fb_setcolreg = &tt_setcolreg;
+			atafb_ops.fb_setcolreg = &tt_setcolreg;
 			break;
 		}
 #endif
 #ifdef ATAFB_FALCON
 		if (ATARIHW_PRESENT(VIDEL_SHIFTER)) {
 			fbhw = &falcon_switch;
-			fb_info.fb_setcolreg = &falcon_setcolreg;
+			atafb_ops.fb_setcolreg = &falcon_setcolreg;
 			request_irq(IRQ_AUTO_4, falcon_vbl_switcher, IRQ_TYPE_PRIO,
 			            "framebuffer/modeswitch", falcon_vbl_switcher);
 			break;
@@ -2726,11 +2726,11 @@
 		if (ATARIHW_PRESENT(STND_SHIFTER) ||
 		    ATARIHW_PRESENT(EXTD_SHIFTER)) {
 			fbhw = &st_switch;
-			fb_info.fb_setcolreg = &stste_setcolreg;
+			atafb_ops.fb_setcolreg = &stste_setcolreg;
 			break;
 		}
 		fbhw = &st_switch;
-		fb_info.fb_setcolreg = &stste_setcolreg;
+		atafb_ops.fb_setcolreg = &stste_setcolreg;
 		printk("Cannot determine video hardware; defaulting to ST(e)\n");
 #else /* ATAFB_STE */
 		/* no default driver included */
@@ -2824,103 +2824,10 @@
 	return 0;
 }
 
-int __init atafb_setup( char *options )
-{
-    char *this_opt;
-    int temp;
-    char ext_str[80], int_str[100];
-    char mcap_spec[80];
-    char user_mode[80];
-
-	ext_str[0]          =
-	int_str[0]          =
-	mcap_spec[0]        =
-	user_mode[0]        =
-	fb_info.fontname[0] = '\0';
-
-    if (!options || !*options)
-		return 0;
-    
-    while ((this_opt = strsep(options, ",")) != NULL) {	 
-	if (!*this_opt) continue;
-	if ((temp=get_video_mode(this_opt)))
-		default_par=temp;
-	else if (! strcmp(this_opt, "inverse"))
-		inverse=1;
-	else if (!strncmp(this_opt, "font:", 5))
-	   strcpy(fb_info.fontname, this_opt+5);
-	else if (! strncmp(this_opt, "hwscroll_",9)) {
-		hwscroll=simple_strtoul(this_opt+9, NULL, 10);
-		if (hwscroll < 0)
-			hwscroll = 0;
-		if (hwscroll > 200)
-			hwscroll = 200;
-	}
-#ifdef ATAFB_EXT
-	else if (!strcmp(this_opt,"mv300")) {
-		external_bitspercol = 8;
-		external_card_type = IS_MV300;
-	}
-	else if (!strncmp(this_opt,"external:",9))
-		strcpy(ext_str, this_opt+9);
-#endif
-	else if (!strncmp(this_opt,"internal:",9))
-		strcpy(int_str, this_opt+9);
-#ifdef ATAFB_FALCON
-	else if (!strncmp(this_opt, "eclock:", 7)) {
-		fext.f = simple_strtoul(this_opt+7, NULL, 10);
-		/* external pixelclock in kHz --> ps */
-		fext.t = 1000000000/fext.f;
-		fext.f *= 1000;
-	}
-	else if (!strncmp(this_opt, "monitorcap:", 11))
-		strcpy(mcap_spec, this_opt+11);
-#endif
-	else if (!strcmp(this_opt, "keep"))
-		DontCalcRes = 1;
-	else if (!strncmp(this_opt, "R", 1))
-		strcpy(user_mode, this_opt+1);
-    }
-
-    if (*int_str) {
-	/* Format to config extended internal video hardware like OverScan:
-	"internal:<xres>;<yres>;<xres_max>;<yres_max>;<offset>"
-	Explanation:
-	<xres>: x-resolution 
-	<yres>: y-resolution
-	The following are only needed if you have an overscan which
-	needs a black border:
-	<xres_max>: max. length of a line in pixels your OverScan hardware would allow
-	<yres_max>: max. number of lines your OverScan hardware would allow
-	<offset>: Offset from physical beginning to visible beginning
-		  of screen in bytes
-	*/
-	int xres;
-	char *p;
-
-	if (!(p = strsep(&int_str, ";")) || !*p) goto int_invalid;
-	xres = simple_strtoul(p, NULL, 10);
-	if (!(p = strsep(&int_str, ";")) || !*p) goto int_invalid;
-	sttt_xres=xres;
-	tt_yres=st_yres=simple_strtoul(p, NULL, 10);
-	if ((p=strsep(&int_str, ";")) && *p) {
-		sttt_xres_virtual=simple_strtoul(p, NULL, 10);
-	}
-	if ((p=strsep(&int_str, ";")) && *p) {
-		sttt_yres_virtual=simple_strtoul(p, NULL, 0);
-	}
-	if ((p=strsep(&int_str, ";")) && *p) {
-		ovsc_offset=simple_strtoul(p, NULL, 0);
-	}
-
-	if (ovsc_offset || (sttt_yres_virtual != st_yres))
-		use_hwscroll=0;
-      int_invalid:
-	;
-    }
 
 #ifdef ATAFB_EXT
-    if (*ext_str) {
+static void __init atafb_setup_ext(char *spec)
+{
 	int		xres, xres_virtual, yres, depth, planes;
 	unsigned long addr, len;
 	char *p;
@@ -2935,20 +2842,27 @@
 	 *
 	 * Even xres_virtual is available, we neither support panning nor hw-scrolling!
 	 */
-	if (!(p = strsep(&ext_str, ";")) || !*p) goto ext_invalid;
+	if (!(p = strsep(&spec, ";")) || !*p)
+	    return;
 	xres_virtual = xres = simple_strtoul(p, NULL, 10);
-	if (xres <= 0) goto ext_invalid;
+	if (xres <= 0)
+	    return;
 
-	if (!(p = strsep(&ext_str, ";")) || !*p) goto ext_invalid;
+	if (!(p = strsep(&spec, ";")) || !*p)
+	    return;
 	yres = simple_strtoul(p, NULL, 10);
-	if (yres <= 0) goto ext_invalid;
+	if (yres <= 0)
+	    return;
 
-	if (!(p = strsep(&ext_str, ";")) || !*p) goto ext_invalid;
+	if (!(p = strsep(&spec, ";")) || !*p)
+	    return;
 	depth = simple_strtoul(p, NULL, 10);
 	if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
-		depth != 16 && depth != 24) goto ext_invalid;
+		depth != 16 && depth != 24)
+	    return;
 
-	if (!(p = strsep(&ext_str, ";")) || !*p) goto ext_invalid;
+	if (!(p = strsep(&spec, ";")) || !*p)
+	    return;
 	if (*p == 'i')
 		planes = FB_TYPE_INTERLEAVED_PLANES;
 	else if (*p == 'p')
@@ -2958,37 +2872,38 @@
 	else if (*p == 't')
 		planes = -1; /* true color */
 	else
-		goto ext_invalid;
+		return;
 
 
-	if (!(p = strsep(&ext_str, ";")) || !*p) goto ext_invalid;
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
 	addr = simple_strtoul(p, NULL, 0);
 
-	if (!(p = strsep(&ext_str, ";")) || !*p)
+	if (!(p = strsep(&spec, ";")) || !*p)
 		len = xres*yres*depth/8;
 	else
 		len = simple_strtoul(p, NULL, 0);
 
-	if ((p = strsep(&ext_str, ";")) && *p) {
+	if ((p = strsep(&spec, ";")) && *p) {
 		external_vgaiobase=simple_strtoul(p, NULL, 0);
 	}
 
-	if ((p = strsep(&ext_str, ";")) && *p) {
+	if ((p = strsep(&spec, ";")) && *p) {
 		external_bitspercol = simple_strtoul(p, NULL, 0);
 		if (external_bitspercol > 8)
 			external_bitspercol = 8;
 		else if (external_bitspercol < 1)
 			external_bitspercol = 1;
 	}
-	
-	if ((p = strsep(&ext_str, ";")) && *p) {
+
+	if ((p = strsep(&spec, ";")) && *p) {
 		if (!strcmp(p, "vga"))
 			external_card_type = IS_VGA;
 		if (!strcmp(p, "mv300"))
 			external_card_type = IS_MV300;
 	}
 
-	if ((p = strsep(&ext_str, ";")) && *p) {
+	if ((p = strsep(&spec, ";")) && *p) {
 		xres_virtual = simple_strtoul(p, NULL, 10);
 		if (xres_virtual < xres)
 			xres_virtual = xres;
@@ -3003,7 +2918,7 @@
 	external_pmode = planes;
 	external_addr  = (void *)addr;
 	external_len   = len;
-		
+
 	if (external_card_type == IS_MV300)
 	  switch (external_depth) {
 	    case 1:
@@ -3016,14 +2931,52 @@
 	      MV300_reg = MV300_reg_8bit;
 	      break;
 	    }
-
-      ext_invalid:
-	;
-    }
+}
 #endif /* ATAFB_EXT */
 
+
+static void __init atafb_setup_int(char *spec)
+{
+	/* Format to config extended internal video hardware like OverScan:
+	"internal:<xres>;<yres>;<xres_max>;<yres_max>;<offset>"
+	Explanation:
+	<xres>: x-resolution 
+	<yres>: y-resolution
+	The following are only needed if you have an overscan which
+	needs a black border:
+	<xres_max>: max. length of a line in pixels your OverScan hardware would allow
+	<yres_max>: max. number of lines your OverScan hardware would allow
+	<offset>: Offset from physical beginning to visible beginning
+		  of screen in bytes
+	*/
+	int xres;
+	char *p;
+
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
+	xres = simple_strtoul(p, NULL, 10);
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
+	sttt_xres=xres;
+	tt_yres=st_yres=simple_strtoul(p, NULL, 10);
+	if ((p=strsep(&spec, ";")) && *p) {
+		sttt_xres_virtual=simple_strtoul(p, NULL, 10);
+	}
+	if ((p=strsep(&spec, ";")) && *p) {
+		sttt_yres_virtual=simple_strtoul(p, NULL, 0);
+	}
+	if ((p=strsep(&spec, ";")) && *p) {
+		ovsc_offset=simple_strtoul(p, NULL, 0);
+	}
+
+	if (ovsc_offset || (sttt_yres_virtual != st_yres))
+		use_hwscroll=0;
+}
+
+
 #ifdef ATAFB_FALCON
-    if (*mcap_spec) {
+static void __init atafb_setup_mcap(char *spec)
+{
 	char *p;
 	int vmin, vmax, hmin, hmax;
 
@@ -3031,51 +2984,110 @@
 	 * <V*> vertical freq. in Hz
 	 * <H*> horizontal freq. in kHz
 	 */
-	if (!(p = strsep(&mcap_spec, ";")) || !*p) goto cap_invalid;
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
 	vmin = simple_strtoul(p, NULL, 10);
-	if (vmin <= 0) goto cap_invalid;
-	if (!(p = strsep(&mcap_spec, ";")) || !*p) goto cap_invalid;
+	if (vmin <= 0)
+		return;
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
 	vmax = simple_strtoul(p, NULL, 10);
-	if (vmax <= 0 || vmax <= vmin) goto cap_invalid;
-	if (!(p = strsep(&mcap_spec, ";")) || !*p) goto cap_invalid;
+	if (vmax <= 0 || vmax <= vmin)
+		return;
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
 	hmin = 1000 * simple_strtoul(p, NULL, 10);
-	if (hmin <= 0) goto cap_invalid;
-	if (!(p = strsep(&mcap_spec, "")) || !*p) goto cap_invalid;
+	if (hmin <= 0)
+		return;
+	if (!(p = strsep(&spec, "")) || !*p)
+		return;
 	hmax = 1000 * simple_strtoul(p, NULL, 10);
-	if (hmax <= 0 || hmax <= hmin) goto cap_invalid;
+	if (hmax <= 0 || hmax <= hmin)
+		return;
 
 	fb_info.monspecs.vfmin = vmin;
 	fb_info.monspecs.vfmax = vmax;
 	fb_info.monspecs.hfmin = hmin;
 	fb_info.monspecs.hfmax = hmax;
-      cap_invalid:
-	;
-    }
-#endif
+}
+#endif /* ATAFB_FALCON */
 
-	if (*user_mode) {
-		/* Format of user defined video mode is: <xres>;<yres>;<depth>
-		 */
-		char *p;
-		int xres, yres, depth, temp;
 
-		if (!(p = strsep(&user_mode, ";")) || !*p) goto user_invalid;
-		xres = simple_strtoul(p, NULL, 10);
-		if (!(p = strsep(&user_mode, ";")) || !*p) goto user_invalid;
-		yres = simple_strtoul(p, NULL, 10);
-		if (!(p = strsep(&user_mode, "")) || !*p) goto user_invalid;
-		depth = simple_strtoul(p, NULL, 10);
-		if ((temp=get_video_mode("user0"))) {
-			default_par=temp;
-			atafb_predefined[default_par-1].xres = xres;
-			atafb_predefined[default_par-1].yres = yres;
-			atafb_predefined[default_par-1].bits_per_pixel = depth;
-		}
+static void __init atafb_setup_user(char *spec)
+{
+	/* Format of user defined video mode is: <xres>;<yres>;<depth>
+	 */
+	char *p;
+	int xres, yres, depth, temp;
 
-	  user_invalid:
-		;
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
+	xres = simple_strtoul(p, NULL, 10);
+	if (!(p = strsep(&spec, ";")) || !*p)
+		return;
+	yres = simple_strtoul(p, NULL, 10);
+	if (!(p = strsep(&spec, "")) || !*p)
+		return;
+	depth = simple_strtoul(p, NULL, 10);
+	if ((temp=get_video_mode("user0"))) {
+		default_par=temp;
+		atafb_predefined[default_par-1].xres = xres;
+		atafb_predefined[default_par-1].yres = yres;
+		atafb_predefined[default_par-1].bits_per_pixel = depth;
 	}
-	return 0;
+}
+
+int __init atafb_setup( char *options )
+{
+    char *this_opt;
+    int temp;
+
+    fb_info.fontname[0] = '\0';
+
+    if (!options || !*options)
+		return 0;
+    
+    while ((this_opt = strsep(&options, ",")) != NULL) {	 
+	if (!*this_opt) continue;
+	if ((temp=get_video_mode(this_opt)))
+		default_par=temp;
+	else if (! strcmp(this_opt, "inverse"))
+		inverse=1;
+	else if (!strncmp(this_opt, "font:", 5))
+	   strcpy(fb_info.fontname, this_opt+5);
+	else if (! strncmp(this_opt, "hwscroll_",9)) {
+		hwscroll=simple_strtoul(this_opt+9, NULL, 10);
+		if (hwscroll < 0)
+			hwscroll = 0;
+		if (hwscroll > 200)
+			hwscroll = 200;
+	}
+#ifdef ATAFB_EXT
+	else if (!strcmp(this_opt,"mv300")) {
+		external_bitspercol = 8;
+		external_card_type = IS_MV300;
+	}
+	else if (!strncmp(this_opt,"external:",9))
+		atafb_setup_ext(this_opt+9);
+#endif
+	else if (!strncmp(this_opt,"internal:",9))
+		atafb_setup_int(this_opt+9);
+#ifdef ATAFB_FALCON
+	else if (!strncmp(this_opt, "eclock:", 7)) {
+		fext.f = simple_strtoul(this_opt+7, NULL, 10);
+		/* external pixelclock in kHz --> ps */
+		fext.t = 1000000000/fext.f;
+		fext.f *= 1000;
+	}
+	else if (!strncmp(this_opt, "monitorcap:", 11))
+		atafb_setup_mcap(this_opt+11);
+#endif
+	else if (!strcmp(this_opt, "keep"))
+		DontCalcRes = 1;
+	else if (!strncmp(this_opt, "R", 1))
+		atafb_setup_user(this_opt+1);
+    }
+    return 0;
 }
 
 #ifdef MODULE
diff -Nru a/drivers/video/aty/Makefile b/drivers/video/aty/Makefile
--- a/drivers/video/aty/Makefile	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/aty/Makefile	Wed Jul 24 14:03:37 2002
@@ -3,7 +3,7 @@
 
 obj-$(CONFIG_FB_ATY) += atyfb.o
 
-atyfb-y				:= atyfb_base.o mach64_accel.o
+atyfb-y				:= atyfb_base.o mach64_accel.o ../cfbimgblt.o
 atyfb-$(CONFIG_FB_ATY_GX)	+= mach64_gx.o
 atyfb-$(CONFIG_FB_ATY_CT)	+= mach64_ct.o mach64_cursor.o
 atyfb-objs			:= $(atyfb-y)
diff -Nru a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
--- a/drivers/video/aty/atyfb.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/aty/atyfb.h	Wed Jul 24 14:03:38 2002
@@ -1,4 +1,3 @@
-
 /*
  *  ATI Frame Buffer Device Driver Core Definitions
  */
@@ -11,137 +10,109 @@
      */
 
 struct crtc {
-    u32 vxres;
-    u32 vyres;
-    u32 xoffset;
-    u32 yoffset;
-    u32 bpp;
-    u32 h_tot_disp;
-    u32 h_sync_strt_wid;
-    u32 v_tot_disp;
-    u32 v_sync_strt_wid;
-    u32 off_pitch;
-    u32 gen_cntl;
-    u32 dp_pix_width;	/* acceleration */
-    u32 dp_chain_mask;	/* acceleration */
+	u32 vxres;
+	u32 vyres;
+	u32 xoffset;
+	u32 yoffset;
+	u32 bpp;
+	u32 h_tot_disp;
+	u32 h_sync_strt_wid;
+	u32 v_tot_disp;
+	u32 v_sync_strt_wid;
+	u32 off_pitch;
+	u32 gen_cntl;
+	u32 dp_pix_width;	/* acceleration */
+	u32 dp_chain_mask;	/* acceleration */
 };
 
 struct pll_514 {
-    u8 m;
-    u8 n;
+	u8 m;
+	u8 n;
 };
 
-struct pll_18818
-{
-    u32 program_bits;
-    u32 locationAddr;
-    u32 period_in_ps;
-    u32 post_divider;
+struct pll_18818 {
+	u32 program_bits;
+	u32 locationAddr;
+	u32 period_in_ps;
+	u32 post_divider;
 };
 
 struct pll_ct {
-    u8 pll_ref_div;
-    u8 pll_gen_cntl;
-    u8 mclk_fb_div;
-    u8 pll_vclk_cntl;
-    u8 vclk_post_div;
-    u8 vclk_fb_div;
-    u8 pll_ext_cntl;
-    u32 dsp_config;	/* Mach64 GTB DSP */
-    u32 dsp_on_off;	/* Mach64 GTB DSP */
-    u8 mclk_post_div_real;
-    u8 vclk_post_div_real;
+	u8 pll_ref_div;
+	u8 pll_gen_cntl;
+	u8 mclk_fb_div;
+	u8 pll_vclk_cntl;
+	u8 vclk_post_div;
+	u8 vclk_fb_div;
+	u8 pll_ext_cntl;
+	u32 dsp_config;		/* Mach64 GTB DSP */
+	u32 dsp_on_off;		/* Mach64 GTB DSP */
+	u8 mclk_post_div_real;
+	u8 vclk_post_div_real;
 };
 
 union aty_pll {
-    struct pll_ct ct;
-    struct pll_514 ibm514;
-    struct pll_18818 ics2595;
+	struct pll_ct ct;
+	struct pll_514 ibm514;
+	struct pll_18818 ics2595;
 };
 
-
     /*
      *  The hardware parameters for each card
      */
 
-struct atyfb_par {
-    struct crtc crtc;
-    union aty_pll pll;
-    u32 accel_flags;
-};
-
 struct aty_cursor {
-    int	enable;
-    int on;
-    int vbl_cnt;
-    int blink_rate;
-    u32 offset;
-    struct {
-        u16 x, y;
-    } pos, hot, size;
-    u32 color[2];
-    u8 bits[8][64];
-    u8 mask[8][64];
-    u8 *ram;
-    struct timer_list *timer;
+	int enable;
+	int on;
+	int vbl_cnt;
+	int blink_rate;
+	u32 offset;
+	struct {
+		u16 x, y;
+	} pos, hot, size;
+	u32 color[2];
+	u8 bits[8][64];
+	u8 mask[8][64];
+	u8 *ram;
+	struct timer_list *timer;
 };
 
-struct fb_info_aty {
-    struct fb_info fb_info;
-    struct fb_info_aty *next;
-    unsigned long ati_regbase_phys;
-    unsigned long ati_regbase;
-    unsigned long frame_buffer_phys;
-    unsigned long frame_buffer;
-    unsigned long clk_wr_offset;
-    struct pci_mmap_map *mmap_map;
-    struct aty_cursor *cursor;
-    struct aty_cmap_regs *aty_cmap_regs;
-    struct { u8 red, green, blue, pad; } palette[256];
-    struct atyfb_par default_par;
-    struct atyfb_par current_par;
-    u32 features;
-    u32 total_vram;
-    u32 ref_clk_per;
-    u32 pll_per;
-    u32 mclk_per;
-    u8 bus_type;
-    u8 ram_type;
-    u8 mem_refresh_rate;
-    const struct aty_dac_ops *dac_ops;
-    const struct aty_pll_ops *pll_ops;
-    struct display disp;
-    struct display_switch dispsw;
-    union {
-#ifdef FBCON_HAS_CFB16
-	u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB24
-	u32 cfb24[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-	u32 cfb32[16];
-#endif
-    } fbcon_cmap;
-    u8 blitter_may_be_busy;
+struct atyfb_par {
+	struct aty_cmap_regs *aty_cmap_regs;
+	const struct aty_dac_ops *dac_ops;
+	const struct aty_pll_ops *pll_ops;
+	struct aty_cursor *cursor;
+	unsigned long ati_regbase;
+	unsigned long clk_wr_offset;
+	struct crtc crtc;
+	union aty_pll pll;
+	u32 features;
+	u32 ref_clk_per;
+	u32 pll_per;
+	u32 mclk_per;
+	u8 bus_type;
+	u8 ram_type;
+	u8 mem_refresh_rate;
+	u8 blitter_may_be_busy;
+	u32 accel_flags;
 #ifdef __sparc__
-    u8 mmaped;
-    int open;
-    int vtconsole;
-    int consolecnt;
+	struct pci_mmap_map *mmap_map;
+	int consolecnt;
+	int vtconsole;
+	u8 mmaped;
+	int open;
 #endif
 #ifdef CONFIG_PMAC_PBOOK
-    unsigned char *save_framebuffer;
-    unsigned long save_pll[64];
+	unsigned char *save_framebuffer;
+	unsigned long save_pll[64];
 #endif
 };
-
-
+    
     /*
      *  ATI Mach64 features
      */
 
-#define M64_HAS(feature)	((info)->features & (M64F_##feature))
+#define M64_HAS(feature)	((par)->features & (M64F_##feature))
 
 #define M64F_RESET_3D		0x00000001
 #define M64F_MAGIC_FIFO		0x00000002
@@ -169,63 +140,68 @@
      *  Register access
      */
 
-static inline u32 aty_ld_le32(int regindex,
-			      const struct fb_info_aty *info)
+static inline u32 aty_ld_le32(int regindex, const struct atyfb_par *par)
 {
-    /* Hack for bloc 1, should be cleanly optimized by compiler */
-    if (regindex >= 0x400)
-    	regindex -= 0x800;
+	/* Hack for bloc 1, should be cleanly optimized by compiler */
+	if (regindex >= 0x400)
+		regindex -= 0x800;
 
-#if defined(__mc68000__)
-    return le32_to_cpu(*((volatile u32 *)(info->ati_regbase+regindex)));
+#ifdef CONFIG_ATARI
+	return in_le32((volatile u32 *)(par->ati_regbase + regindex));
 #else
-    return readl (info->ati_regbase + regindex);
+	return readl(par->ati_regbase + regindex);
 #endif
 }
 
 static inline void aty_st_le32(int regindex, u32 val,
-			       const struct fb_info_aty *info)
+			       const struct atyfb_par *par)
 {
-    /* Hack for bloc 1, should be cleanly optimized by compiler */
-    if (regindex >= 0x400)
-    	regindex -= 0x800;
+	/* Hack for bloc 1, should be cleanly optimized by compiler */
+	if (regindex >= 0x400)
+		regindex -= 0x800;
 
-#if defined(__mc68000__)
-    *((volatile u32 *)(info->ati_regbase+regindex)) = cpu_to_le32(val);
+#ifdef CONFIG_ATARI
+	out_le32((volatile u32 *)(par->ati_regbase + regindex));
 #else
-    writel (val, info->ati_regbase + regindex);
+	writel(val, par->ati_regbase + regindex);
 #endif
 }
 
-static inline u8 aty_ld_8(int regindex,
-			  const struct fb_info_aty *info)
+static inline u8 aty_ld_8(int regindex, const struct atyfb_par *par)
 {
-    /* Hack for bloc 1, should be cleanly optimized by compiler */
-    if (regindex >= 0x400)
-    	regindex -= 0x800;
-
-    return readb (info->ati_regbase + regindex);
+	/* Hack for bloc 1, should be cleanly optimized by compiler */
+	if (regindex >= 0x400)
+		regindex -= 0x800;
+#ifdef CONFIG_ATARI
+	return in_8(par->ati_regbase + regindex);
+#else
+	return readb(par->ati_regbase + regindex);
+#endif
 }
 
 static inline void aty_st_8(int regindex, u8 val,
-			    const struct fb_info_aty *info)
+			    const struct atyfb_par *par)
 {
-    /* Hack for bloc 1, should be cleanly optimized by compiler */
-    if (regindex >= 0x400)
-    	regindex -= 0x800;
+	/* Hack for bloc 1, should be cleanly optimized by compiler */
+	if (regindex >= 0x400)
+		regindex -= 0x800;
 
-    writeb (val, info->ati_regbase + regindex);
+#ifdef CONFIG_ATARI
+	out_8(par->ati_regbase + regindex, val);
+#else
+	writeb(val, par->ati_regbase + regindex);
+#endif
 }
 
-static inline u8 aty_ld_pll(int offset, const struct fb_info_aty *info)
+static inline u8 aty_ld_pll(int offset, const struct atyfb_par *par)
 {
-    u8 res;
+	u8 res;
 
-    /* write addr byte */
-    aty_st_8(CLOCK_CNTL + 1, (offset << 2), info);
-    /* read the register value */
-    res = aty_ld_8(CLOCK_CNTL + 2, info);
-    return res;
+	/* write addr byte */
+	aty_st_8(CLOCK_CNTL + 1, (offset << 2), par);
+	/* read the register value */
+	res = aty_ld_8(CLOCK_CNTL + 2, par);
+	return res;
 }
 
 
@@ -234,15 +210,15 @@
      */
 
 struct aty_dac_ops {
-    int (*set_dac)(const struct fb_info_aty *info, const union aty_pll *pll,
-		   u32 bpp, u32 accel);
+	int (*set_dac) (const struct fb_info * info,
+			const union aty_pll * pll, u32 bpp, u32 accel);
 };
 
-extern const struct aty_dac_ops aty_dac_ibm514;		/* IBM RGB514 */
+extern const struct aty_dac_ops aty_dac_ibm514;	/* IBM RGB514 */
 extern const struct aty_dac_ops aty_dac_ati68860b;	/* ATI 68860-B */
 extern const struct aty_dac_ops aty_dac_att21c498;	/* AT&T 21C498 */
 extern const struct aty_dac_ops aty_dac_unsupported;	/* unsupported */
-extern const struct aty_dac_ops aty_dac_ct;		/* Integrated */
+extern const struct aty_dac_ops aty_dac_ct;	/* Integrated */
 
 
     /*
@@ -250,25 +226,26 @@
      */
 
 struct aty_pll_ops {
-    int (*var_to_pll)(const struct fb_info_aty *info, u32 vclk_per, u8 bpp,
-		      union aty_pll *pll);
-    u32 (*pll_to_var)(const struct fb_info_aty *info,
-	    	      const union aty_pll *pll);
-    void (*set_pll)(const struct fb_info_aty *info, const union aty_pll *pll);
+	int (*var_to_pll) (const struct fb_info * info, u32 vclk_per,
+			   u8 bpp, union aty_pll * pll);
+	 u32(*pll_to_var) (const struct fb_info * info,
+			   const union aty_pll * pll);
+	void (*set_pll) (const struct fb_info * info,
+			 const union aty_pll * pll);
 };
 
 extern const struct aty_pll_ops aty_pll_ati18818_1;	/* ATI 18818 */
 extern const struct aty_pll_ops aty_pll_stg1703;	/* STG 1703 */
-extern const struct aty_pll_ops aty_pll_ch8398;		/* Chrontel 8398 */
+extern const struct aty_pll_ops aty_pll_ch8398;	/* Chrontel 8398 */
 extern const struct aty_pll_ops aty_pll_att20c408;	/* AT&T 20C408 */
-extern const struct aty_pll_ops aty_pll_ibm514;		/* IBM RGB514 */
+extern const struct aty_pll_ops aty_pll_ibm514;	/* IBM RGB514 */
 extern const struct aty_pll_ops aty_pll_unsupported;	/* unsupported */
-extern const struct aty_pll_ops aty_pll_ct;		/* Integrated */
+extern const struct aty_pll_ops aty_pll_ct;	/* Integrated */
 
 
-extern void aty_set_pll_ct(const struct fb_info_aty *info,
+extern void aty_set_pll_ct(const struct fb_info *info,
 			   const union aty_pll *pll);
-extern void aty_calc_pll_ct(const struct fb_info_aty *info,
+extern void aty_calc_pll_ct(const struct fb_info *info,
 			    struct pll_ct *pll);
 
 
@@ -276,10 +253,10 @@
      *  Hardware cursor support
      */
 
-extern struct aty_cursor *aty_init_cursor(struct fb_info_aty *fb);
+extern struct aty_cursor *aty_init_cursor(struct fb_info *info);
 extern void atyfb_cursor(struct display *p, int mode, int x, int y);
-extern void aty_set_cursor_color(struct fb_info_aty *fb);
-extern void aty_set_cursor_shape(struct fb_info_aty *fb);
+extern void aty_set_cursor_color(struct fb_info *info);
+extern void aty_set_cursor_shape(struct fb_info *info);
 extern int atyfb_set_font(struct display *d, int width, int height);
 
 
@@ -287,25 +264,23 @@
      *  Hardware acceleration
      */
 
-static inline void wait_for_fifo(u16 entries, const struct fb_info_aty *info)
+static inline void wait_for_fifo(u16 entries, const struct atyfb_par *par)
 {
-    while ((aty_ld_le32(FIFO_STAT, info) & 0xffff) >
-	   ((u32)(0x8000 >> entries)));
+	while ((aty_ld_le32(FIFO_STAT, par) & 0xffff) >
+	       ((u32) (0x8000 >> entries)));
 }
 
-static inline void wait_for_idle(struct fb_info_aty *info)
+static inline void wait_for_idle(struct atyfb_par *par)
 {
-    wait_for_fifo(16, info);
-    while ((aty_ld_le32(GUI_STAT, info) & 1)!= 0);
-    info->blitter_may_be_busy = 0;
+	wait_for_fifo(16, par);
+	while ((aty_ld_le32(GUI_STAT, par) & 1) != 0);
+	par->blitter_may_be_busy = 0;
 }
 
-extern void aty_reset_engine(const struct fb_info_aty *info);
-extern void aty_init_engine(const struct atyfb_par *par,
-			    struct fb_info_aty *info);
-extern void aty_rectfill(int dstx, int dsty, u_int width, u_int height,
-			 u_int color, struct fb_info_aty *info);
-
+extern void aty_reset_engine(const struct atyfb_par *par);
+extern void aty_init_engine(struct atyfb_par *par,
+			    struct fb_info *info);
+extern void atyfb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
 
     /*
      *  Text console acceleration
@@ -315,4 +290,3 @@
 extern const struct display_switch fbcon_aty16;
 extern const struct display_switch fbcon_aty24;
 extern const struct display_switch fbcon_aty32;
-
diff -Nru a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
--- a/drivers/video/aty/atyfb_base.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/aty/atyfb_base.c	Wed Jul 24 14:03:36 2002
@@ -71,7 +71,7 @@
 #include <video/fbcon-cfb24.h>
 #include <video/fbcon-cfb32.h>
 
-#include "mach64.h"
+#include <video/mach64.h>
 #include "atyfb.h"
 
 #ifdef __powerpc__
@@ -93,9 +93,6 @@
 #ifdef CONFIG_NVRAM
 #include <linux/nvram.h>
 #endif
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-#endif
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
 #endif
@@ -121,21 +118,28 @@
      */
 
 struct aty_cmap_regs {
-    u8 windex;
-    u8 lut;
-    u8 mask;
-    u8 rindex;
-    u8 cntl;
+	u8 windex;
+	u8 lut;
+	u8 mask;
+	u8 rindex;
+	u8 cntl;
 };
 
 struct pci_mmap_map {
-    unsigned long voff;
-    unsigned long poff;
-    unsigned long size;
-    unsigned long prot_flag;
-    unsigned long prot_mask;
+	unsigned long voff;
+	unsigned long poff;
+	unsigned long size;
+	unsigned long prot_flag;
+	unsigned long prot_mask;
 };
 
+static struct fb_fix_screeninfo atyfb_fix __initdata = {
+	id:		"ATY Mach64",
+	type:		FB_TYPE_PACKED_PIXELS,
+	visual:		FB_VISUAL_PSEUDOCOLOR,
+	xpanstep:	8,
+	ypanstep:	1,
+};
 
     /*
      *  Frame buffer device API
@@ -144,20 +148,16 @@
 static int atyfb_open(struct fb_info *info, int user);
 static int atyfb_release(struct fb_info *info, int user);
 static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *fb);
+			 struct fb_info *info);
 static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *fb);
+			 struct fb_info *info);
 static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *fb);
+			 struct fb_info *info);
 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			 u_int transp, struct fb_info *fb);
+			   u_int transp, struct fb_info *info);
 static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
-			     struct fb_info *fb);
-static int atyfb_blank(int blank, struct fb_info *fb);
-static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info);
-static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info);
+			     struct fb_info *info);
+static int atyfb_blank(int blank, struct fb_info *info);
 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
 		       u_long arg, int con, struct fb_info *info);
 #ifdef __sparc__
@@ -171,45 +171,42 @@
      *  Interface to the low level console driver
      */
 
-static int atyfbcon_switch(int con, struct fb_info *fb);
-static int atyfbcon_updatevar(int con, struct fb_info *fb);
+static int atyfbcon_updatevar(int con, struct fb_info *info);
 
     /*
      *  Internal routines
      */
 
-static int aty_init(struct fb_info_aty *info, const char *name);
+static int aty_init(struct fb_info *info, const char *name);
 #ifdef CONFIG_ATARI
 static int store_video_par(char *videopar, unsigned char m64_num);
 #endif
 
-static void aty_set_crtc(const struct fb_info_aty *info,
+static void aty_set_crtc(const struct atyfb_par *par,
 			 const struct crtc *crtc);
-static int aty_var_to_crtc(const struct fb_info_aty *info,
+static int aty_var_to_crtc(const struct fb_info *info,
 			   const struct fb_var_screeninfo *var,
 			   struct crtc *crtc);
 static int aty_crtc_to_var(const struct crtc *crtc,
 			   struct fb_var_screeninfo *var);
 
-static void atyfb_set_par(const struct atyfb_par *par,
-			  struct fb_info_aty *info);
+static void atyfb_set_par(struct atyfb_par *par,
+			  struct fb_info *info);
 static int atyfb_decode_var(const struct fb_var_screeninfo *var,
 			    struct atyfb_par *par,
-			    const struct fb_info_aty *info);
+			    const struct fb_info *info);
 static int atyfb_encode_var(struct fb_var_screeninfo *var,
 			    const struct atyfb_par *par,
-			    const struct fb_info_aty *info);
+			    const struct fb_info *info);
 static void set_off_pitch(struct atyfb_par *par,
-			  const struct fb_info_aty *info);
+			  const struct fb_info *info);
 static int encode_fix(struct fb_fix_screeninfo *fix,
 		      const struct atyfb_par *par,
-		      const struct fb_info_aty *info);
-static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
-			     int bpp, int accel);
-static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			 u_int *transp, struct fb_info *fb);
+		      const struct fb_info *info);
+static void atyfb_set_dispsw(struct display *disp,
+			     struct fb_info *info);
 #ifdef CONFIG_PPC
-static int read_aty_sense(const struct fb_info_aty *info);
+static int read_aty_sense(const struct fb_info *info);
 #endif
 
 
@@ -219,26 +216,26 @@
 
 int atyfb_init(void);
 #ifndef MODULE
-int atyfb_setup(char*);
+int atyfb_setup(char *);
 #endif
 
 static struct fb_ops atyfb_ops = {
-	owner:		THIS_MODULE,
-	fb_open:	atyfb_open,
-	fb_release:	atyfb_release,
-	fb_get_fix:	atyfb_get_fix,
-	fb_get_var:	atyfb_get_var,
-	fb_set_var:	atyfb_set_var,
-	fb_get_cmap:	atyfb_get_cmap,
-	fb_set_cmap:	atyfb_set_cmap,
-	fb_setcolreg:	atyfb_setcolreg,
-	fb_pan_display:	atyfb_pan_display,
-	fb_blank:	atyfb_blank,
-	fb_ioctl:	atyfb_ioctl,
+	owner:THIS_MODULE,
+	fb_open:atyfb_open,
+	fb_release:atyfb_release,
+	fb_get_fix:atyfb_get_fix,
+	fb_get_var:atyfb_get_var,
+	fb_set_var:atyfb_set_var,
+	fb_get_cmap:gen_get_cmap,
+	fb_set_cmap:gen_set_cmap,
+	fb_setcolreg:atyfb_setcolreg,
+	fb_pan_display:atyfb_pan_display,
+	fb_blank:atyfb_blank,
+	fb_ioctl:atyfb_ioctl,
 #ifdef __sparc__
-	fb_mmap:	atyfb_mmap,
+	fb_mmap:atyfb_mmap,
 #endif
-	fb_rasterimg:	atyfb_rasterimg,
+	fb_rasterimg:atyfb_rasterimg,
 };
 
 static char atyfb_name[16] = "ATY Mach64";
@@ -270,8 +267,11 @@
 static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
 #endif
 
+#ifdef CONFIG_FB_ATY_GX
 static char m64n_gx[] __initdata = "mach64GX (ATI888GX00)";
 static char m64n_cx[] __initdata = "mach64CX (ATI888CX00)";
+#endif /* CONFIG_FB_ATY_GX */
+#ifdef CONFIG_FB_ATY_CT
 static char m64n_ct[] __initdata = "mach64CT (ATI264CT)";
 static char m64n_et[] __initdata = "mach64ET (ATI264ET)";
 static char m64n_vta3[] __initdata = "mach64VTA3 (ATI264VT)";
@@ -288,96 +288,172 @@
 static char m64n_gtc_ba1[] __initdata = "3D RAGE PRO (BGA, AGP, 1x only)";
 static char m64n_gtc_bp[] __initdata = "3D RAGE PRO (BGA, PCI)";
 static char m64n_gtc_pp[] __initdata = "3D RAGE PRO (PQFP, PCI)";
-static char m64n_gtc_ppl[] __initdata = "3D RAGE PRO (PQFP, PCI, limited 3D)";
+static char m64n_gtc_ppl[] __initdata =
+    "3D RAGE PRO (PQFP, PCI, limited 3D)";
 static char m64n_xl[] __initdata = "3D RAGE (XL)";
 static char m64n_ltp_a[] __initdata = "3D RAGE LT PRO (AGP)";
 static char m64n_ltp_p[] __initdata = "3D RAGE LT PRO (PCI)";
 static char m64n_mob_p[] __initdata = "3D RAGE Mobility (PCI)";
 static char m64n_mob_a[] __initdata = "3D RAGE Mobility (AGP)";
-
+#endif /* CONFIG_FB_ATY_CT */
 
 static struct {
-    u16 pci_id, chip_type;
-    u8 rev_mask, rev_val;
-    const char *name;
-    int pll, mclk;
-    u32 features;
+	u16 pci_id, chip_type;
+	u8 rev_mask, rev_val;
+	const char *name;
+	int pll, mclk;
+	u32 features;
 } aty_chips[] __initdata = {
 #ifdef CONFIG_FB_ATY_GX
-    /* Mach64 GX */
-    { 0x4758, 0x00d7, 0x00, 0x00, m64n_gx,      135,  50, M64F_GX },
-    { 0x4358, 0x0057, 0x00, 0x00, m64n_cx,      135,  50, M64F_GX },
-#endif /* CONFIG_FB_ATY_GX */
-
+	/* Mach64 GX */
+	{
+	0x4758, 0x00d7, 0x00, 0x00, m64n_gx, 135, 50, M64F_GX}, {
+	0x4358, 0x0057, 0x00, 0x00, m64n_cx, 135, 50, M64F_GX},
+#endif				/* CONFIG_FB_ATY_GX */
 #ifdef CONFIG_FB_ATY_CT
-    /* Mach64 CT */
-    { 0x4354, 0x4354, 0x00, 0x00, m64n_ct,      135,  60, M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO },
-    { 0x4554, 0x4554, 0x00, 0x00, m64n_et,      135,  60, M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO },
-
-    /* Mach64 VT */
-    { 0x5654, 0x5654, 0xc7, 0x00, m64n_vta3,    170,  67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO | M64F_FIFO_24 },
-    { 0x5654, 0x5654, 0xc7, 0x40, m64n_vta4,    200,  67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_MAGIC_POSTDIV },
-    { 0x5654, 0x5654, 0x00, 0x00, m64n_vtb,     200,  67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_FIFO_24 },
-    { 0x5655, 0x5655, 0x00, 0x00, m64n_vtb,     200,  67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL },
-    { 0x5656, 0x5656, 0x00, 0x00, m64n_vt4,     230,  83, M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP },
-
-    /* Mach64 GT (3D RAGE) */
-    { 0x4754, 0x4754, 0x07, 0x00, m64n_gt,      135,  63, M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_EXTRA_BRIGHT },
-    { 0x4754, 0x4754, 0x07, 0x01, m64n_gt,      170,  67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4754, 0x4754, 0x07, 0x02, m64n_gt,      200,  67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4755, 0x4755, 0x00, 0x00, m64n_gtb,     200,  67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4756, 0x4756, 0x00, 0x00, m64n_iic_p,   230,  83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4757, 0x4757, 0x00, 0x00, m64n_iic_a,   230,  83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x475a, 0x475a, 0x00, 0x00, m64n_iic_a,   230,  83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-
-    /* Mach64 LT */
-    { 0x4c54, 0x4c54, 0x00, 0x00, m64n_lt,      135,  63, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP },
-    { 0x4c47, 0x4c47, 0x00, 0x00, m64n_ltg,     230,  63, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_LT_SLEEP | M64F_G3_PB_1024x768 },
-
-    /* Mach64 GTC (3D RAGE PRO) */
-    { 0x4742, 0x4742, 0x00, 0x00, m64n_gtc_ba,  230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4744, 0x4744, 0x00, 0x00, m64n_gtc_ba1, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4749, 0x4749, 0x00, 0x00, m64n_gtc_bp,  230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_MAGIC_VRAM_SIZE },
-    { 0x4750, 0x4750, 0x00, 0x00, m64n_gtc_pp,  230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4751, 0x4751, 0x00, 0x00, m64n_gtc_ppl, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-
-    /* 3D RAGE XL */
-    { 0x4752, 0x4752, 0x00, 0x00, m64n_xl, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_XL_DLL },
-
-    /* Mach64 LT PRO */
-    { 0x4c42, 0x4c42, 0x00, 0x00, m64n_ltp_a,   230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
-    { 0x4c44, 0x4c44, 0x00, 0x00, m64n_ltp_p,   230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
-    { 0x4c49, 0x4c49, 0x00, 0x00, m64n_ltp_p,   230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_EXTRA_BRIGHT | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
-    { 0x4c50, 0x4c50, 0x00, 0x00, m64n_ltp_p,   230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
-
-    /* 3D RAGE Mobility */
-    { 0x4c4d, 0x4c4d, 0x00, 0x00, m64n_mob_p,   230,  50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS },
-    { 0x4c4e, 0x4c4e, 0x00, 0x00, m64n_mob_a,   230,  50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS },
-#endif /* CONFIG_FB_ATY_CT */
+	    /* Mach64 CT */
+	{
+	0x4354, 0x4354, 0x00, 0x00, m64n_ct, 135, 60,
+		    M64F_CT | M64F_INTEGRATED | M64F_CT_BUS |
+		    M64F_MAGIC_FIFO}, {
+	0x4554, 0x4554, 0x00, 0x00, m64n_et, 135, 60,
+		    M64F_CT | M64F_INTEGRATED | M64F_CT_BUS |
+		    M64F_MAGIC_FIFO},
+	    /* Mach64 VT */
+	{
+	0x5654, 0x5654, 0xc7, 0x00, m64n_vta3, 170, 67,
+		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
+		    M64F_MAGIC_FIFO | M64F_FIFO_24}, {
+	0x5654, 0x5654, 0xc7, 0x40, m64n_vta4, 200, 67,
+		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
+		    M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_MAGIC_POSTDIV}, {
+	0x5654, 0x5654, 0x00, 0x00, m64n_vtb, 200, 67,
+		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
+		    M64F_GTB_DSP | M64F_FIFO_24}, {
+	0x5655, 0x5655, 0x00, 0x00, m64n_vtb, 200, 67,
+		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
+		    M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL}, {
+	0x5656, 0x5656, 0x00, 0x00, m64n_vt4, 230, 83,
+		    M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP},
+	    /* Mach64 GT (3D RAGE) */
+	{
+	0x4754, 0x4754, 0x07, 0x00, m64n_gt, 135, 63,
+		    M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO |
+		    M64F_FIFO_24 | M64F_EXTRA_BRIGHT}, {
+	0x4754, 0x4754, 0x07, 0x01, m64n_gt, 170, 67,
+		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
+		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT}, {
+	0x4754, 0x4754, 0x07, 0x02, m64n_gt, 200, 67,
+		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
+		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT}, {
+	0x4755, 0x4755, 0x00, 0x00, m64n_gtb, 200, 67,
+		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
+		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT}, {
+	0x4756, 0x4756, 0x00, 0x00, m64n_iic_p, 230, 83,
+		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
+		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT}, {
+	0x4757, 0x4757, 0x00, 0x00, m64n_iic_a, 230, 83,
+		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
+		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT}, {
+	0x475a, 0x475a, 0x00, 0x00, m64n_iic_a, 230, 83,
+		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
+		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT},
+	    /* Mach64 LT */
+	{
+	0x4c54, 0x4c54, 0x00, 0x00, m64n_lt, 135, 63,
+		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP}, {
+	0x4c47, 0x4c47, 0x00, 0x00, m64n_ltg, 230, 63,
+		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
+		    M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT |
+		    M64F_LT_SLEEP | M64F_G3_PB_1024x768},
+	    /* Mach64 GTC (3D RAGE PRO) */
+	{
+	0x4742, 0x4742, 0x00, 0x00, m64n_gtc_ba, 230, 100,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT}, {
+	0x4744, 0x4744, 0x00, 0x00, m64n_gtc_ba1, 230, 100,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT}, {
+	0x4749, 0x4749, 0x00, 0x00, m64n_gtc_bp, 230, 100,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT | M64F_MAGIC_VRAM_SIZE}, {
+	0x4750, 0x4750, 0x00, 0x00, m64n_gtc_pp, 230, 100,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT}, {
+	0x4751, 0x4751, 0x00, 0x00, m64n_gtc_ppl, 230, 100,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT},
+	    /* 3D RAGE XL */
+	{
+	0x4752, 0x4752, 0x00, 0x00, m64n_xl, 230, 100,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
+		    M64F_EXTRA_BRIGHT | M64F_XL_DLL},
+	    /* Mach64 LT PRO */
+	{
+	0x4c42, 0x4c42, 0x00, 0x00, m64n_ltp_a, 230, 100,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP}, {
+	0x4c44, 0x4c44, 0x00, 0x00, m64n_ltp_p, 230, 100,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP}, {
+	0x4c49, 0x4c49, 0x00, 0x00, m64n_ltp_p, 230, 100,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP | M64F_EXTRA_BRIGHT |
+		    M64F_G3_PB_1_1 | M64F_G3_PB_1024x768}, {
+	0x4c50, 0x4c50, 0x00, 0x00, m64n_ltp_p, 230, 100,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP},
+	    /* 3D RAGE Mobility */
+	{
+	0x4c4d, 0x4c4d, 0x00, 0x00, m64n_mob_p, 230, 50,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP | M64F_MOBIL_BUS}, {
+	0x4c4e, 0x4c4e, 0x00, 0x00, m64n_mob_a, 230, 50,
+		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
+		    M64F_GTB_DSP | M64F_MOBIL_BUS},
+#endif				/* CONFIG_FB_ATY_CT */
 };
 
 static char ram_dram[] __initdata = "DRAM";
+#ifdef CONFIG_FB_ATY_GX
 static char ram_vram[] __initdata = "VRAM";
+#endif /* CONFIG_FB_ATY_GX */
+#ifdef CONFIG_FB_ATY_CT
 static char ram_edo[] __initdata = "EDO";
 static char ram_sdram[] __initdata = "SDRAM";
 static char ram_sgram[] __initdata = "SGRAM";
 static char ram_wram[] __initdata = "WRAM";
 static char ram_off[] __initdata = "OFF";
+#endif /* CONFIG_FB_ATY_CT */
 static char ram_resv[] __initdata = "RESV";
 
+static u32 pseudo_palette[17];
+
 #ifdef CONFIG_FB_ATY_GX
 static char *aty_gx_ram[8] __initdata = {
-    ram_dram, ram_vram, ram_vram, ram_dram,
-    ram_dram, ram_vram, ram_vram, ram_resv
+	ram_dram, ram_vram, ram_vram, ram_dram,
+	ram_dram, ram_vram, ram_vram, ram_resv
 };
-#endif /* CONFIG_FB_ATY_GX */
+#endif				/* CONFIG_FB_ATY_GX */
 
 #ifdef CONFIG_FB_ATY_CT
 static char *aty_ct_ram[8] __initdata = {
-    ram_off, ram_dram, ram_edo, ram_edo,
-    ram_sdram, ram_sgram, ram_wram, ram_resv
+	ram_off, ram_dram, ram_edo, ram_edo,
+	ram_sdram, ram_sgram, ram_wram, ram_resv
 };
-#endif /* CONFIG_FB_ATY_CT */
+#endif				/* CONFIG_FB_ATY_CT */
 
 
 #if defined(CONFIG_PPC)
@@ -386,65 +462,65 @@
      *  Apple monitor sense
      */
 
-static int __init read_aty_sense(const struct fb_info_aty *info)
+static int __init read_aty_sense(const struct fb_info *info)
 {
-    int sense, i;
+	int sense, i;
 
-    aty_st_le32(GP_IO, 0x31003100, info);	/* drive outputs high */
-    __delay(200);
-    aty_st_le32(GP_IO, 0, info);		/* turn off outputs */
-    __delay(2000);
-    i = aty_ld_le32(GP_IO, info);		/* get primary sense value */
-    sense = ((i & 0x3000) >> 3) | (i & 0x100);
-
-    /* drive each sense line low in turn and collect the other 2 */
-    aty_st_le32(GP_IO, 0x20000000, info);	/* drive A low */
-    __delay(2000);
-    i = aty_ld_le32(GP_IO, info);
-    sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
-    aty_st_le32(GP_IO, 0x20002000, info);	/* drive A high again */
-    __delay(200);
-
-    aty_st_le32(GP_IO, 0x10000000, info);	/* drive B low */
-    __delay(2000);
-    i = aty_ld_le32(GP_IO, info);
-    sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
-    aty_st_le32(GP_IO, 0x10001000, info);	/* drive B high again */
-    __delay(200);
-
-    aty_st_le32(GP_IO, 0x01000000, info);	/* drive C low */
-    __delay(2000);
-    sense |= (aty_ld_le32(GP_IO, info) & 0x3000) >> 12;
-    aty_st_le32(GP_IO, 0, info);		/* turn off outputs */
+	aty_st_le32(GP_IO, 0x31003100, info);	/* drive outputs high */
+	__delay(200);
+	aty_st_le32(GP_IO, 0, info);	/* turn off outputs */
+	__delay(2000);
+	i = aty_ld_le32(GP_IO, info);	/* get primary sense value */
+	sense = ((i & 0x3000) >> 3) | (i & 0x100);
+
+	/* drive each sense line low in turn and collect the other 2 */
+	aty_st_le32(GP_IO, 0x20000000, info);	/* drive A low */
+	__delay(2000);
+	i = aty_ld_le32(GP_IO, info);
+	sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
+	aty_st_le32(GP_IO, 0x20002000, info);	/* drive A high again */
+	__delay(200);
+
+	aty_st_le32(GP_IO, 0x10000000, info);	/* drive B low */
+	__delay(2000);
+	i = aty_ld_le32(GP_IO, info);
+	sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
+	aty_st_le32(GP_IO, 0x10001000, info);	/* drive B high again */
+	__delay(200);
+
+	aty_st_le32(GP_IO, 0x01000000, info);	/* drive C low */
+	__delay(2000);
+	sense |= (aty_ld_le32(GP_IO, info) & 0x3000) >> 12;
+	aty_st_le32(GP_IO, 0, info);	/* turn off outputs */
 
-    return sense;
+	return sense;
 }
 
-#endif /* defined(CONFIG_PPC) */
+#endif				/* defined(CONFIG_PPC) */
 
 #if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_PMAC_BACKLIGHT)
-static void aty_st_lcd(int index, u32 val, const struct fb_info_aty *info)
+static void aty_st_lcd(int index, u32 val, const struct fb_info *info)
 {
-    unsigned long temp;
+	unsigned long temp;
 
-    /* write addr byte */
-    temp = aty_ld_le32(LCD_INDEX, info);
-    aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
-    /* write the register value */
-    aty_st_le32(LCD_DATA, val, info);
+	/* write addr byte */
+	temp = aty_ld_le32(LCD_INDEX, info);
+	aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
+	/* write the register value */
+	aty_st_le32(LCD_DATA, val, info);
 }
 
-static u32 aty_ld_lcd(int index, const struct fb_info_aty *info)
+static u32 aty_ld_lcd(int index, const struct fb_info *info)
 {
-    unsigned long temp;
+	unsigned long temp;
 
-    /* write addr byte */
-    temp = aty_ld_le32(LCD_INDEX, info);
-    aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
-    /* read the register value */
-    return aty_ld_le32(LCD_DATA, info);
+	/* write addr byte */
+	temp = aty_ld_le32(LCD_INDEX, info);
+	aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
+	/* read the register value */
+	return aty_ld_le32(LCD_DATA, info);
 }
-#endif /* CONFIG_PMAC_PBOOK || CONFIG_PMAC_BACKLIGHT */
+#endif				/* CONFIG_PMAC_PBOOK || CONFIG_PMAC_BACKLIGHT */
 
 /* ------------------------------------------------------------------------- */
 
@@ -452,436 +528,429 @@
      *  CRTC programming
      */
 
-static void aty_set_crtc(const struct fb_info_aty *info,
+static void aty_set_crtc(const struct atyfb_par *par,
 			 const struct crtc *crtc)
 {
-    aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, info);
-    aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, info);
-    aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, info);
-    aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, info);
-    aty_st_le32(CRTC_VLINE_CRNT_VLINE, 0, info);
-    aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, info);
-    aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, info);
+	aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
+	aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
+	aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par);
+	aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par);
+	aty_st_le32(CRTC_VLINE_CRNT_VLINE, 0, par);
+	aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par);
+	aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par);
 }
 
-static int aty_var_to_crtc(const struct fb_info_aty *info,
+static int aty_var_to_crtc(const struct fb_info *info,
 			   const struct fb_var_screeninfo *var,
 			   struct crtc *crtc)
 {
-    u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
-    u32 left, right, upper, lower, hslen, vslen, sync, vmode;
-    u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
-    u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
-    u32 pix_width, dp_pix_width, dp_chain_mask;
-
-    /* input */
-    xres = var->xres;
-    yres = var->yres;
-    vxres = var->xres_virtual;
-    vyres = var->yres_virtual;
-    xoffset = var->xoffset;
-    yoffset = var->yoffset;
-    bpp = var->bits_per_pixel;
-    left = var->left_margin;
-    right = var->right_margin;
-    upper = var->upper_margin;
-    lower = var->lower_margin;
-    hslen = var->hsync_len;
-    vslen = var->vsync_len;
-    sync = var->sync;
-    vmode = var->vmode;
-
-    /* convert (and round up) and validate */
-    xres = (xres+7) & ~7;
-    xoffset = (xoffset+7) & ~7;
-    vxres = (vxres+7) & ~7;
-    if (vxres < xres+xoffset)
-	vxres = xres+xoffset;
-    h_disp = xres/8-1;
-    if (h_disp > 0xff)
-	FAIL("h_disp too large");
-    h_sync_strt = h_disp+(right/8);
-    if (h_sync_strt > 0x1ff)
-	FAIL("h_sync_start too large");
-    h_sync_dly = right & 7;
-    h_sync_wid = (hslen+7)/8;
-    if (h_sync_wid > 0x1f)
-	FAIL("h_sync_wid too large");
-    h_total = h_sync_strt+h_sync_wid+(h_sync_dly+left+7)/8;
-    if (h_total > 0x1ff)
-	FAIL("h_total too large");
-    h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
-
-    if (vyres < yres+yoffset)
-	vyres = yres+yoffset;
-    v_disp = yres-1;
-    if (v_disp > 0x7ff)
-	FAIL("v_disp too large");
-    v_sync_strt = v_disp+lower;
-    if (v_sync_strt > 0x7ff)
-	FAIL("v_sync_strt too large");
-    v_sync_wid = vslen;
-    if (v_sync_wid > 0x1f)
-	FAIL("v_sync_wid too large");
-    v_total = v_sync_strt+v_sync_wid+upper;
-    if (v_total > 0x7ff)
-	FAIL("v_total too large");
-    v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
-
-    c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
-
-    if (bpp <= 8) {
-	bpp = 8;
-	pix_width = CRTC_PIX_WIDTH_8BPP;
-	dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | BYTE_ORDER_LSB_TO_MSB;
-	dp_chain_mask = 0x8080;
-    } else if (bpp <= 16) {
-	bpp = 16;
-	pix_width = CRTC_PIX_WIDTH_15BPP;
-	dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
-		       BYTE_ORDER_LSB_TO_MSB;
-	dp_chain_mask = 0x4210;
-    } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
-	bpp = 24;
-	pix_width = CRTC_PIX_WIDTH_24BPP;
-	dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | BYTE_ORDER_LSB_TO_MSB;
-	dp_chain_mask = 0x8080;
-    } else if (bpp <= 32) {
-	bpp = 32;
-	pix_width = CRTC_PIX_WIDTH_32BPP;
-	dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
-		       BYTE_ORDER_LSB_TO_MSB;
-	dp_chain_mask = 0x8080;
-    } else
-	FAIL("invalid bpp");
-
-    if (vxres*vyres*bpp/8 > info->total_vram)
-	FAIL("not enough video RAM");
-
-    if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-	FAIL("invalid vmode");
-
-    /* output */
-    crtc->vxres = vxres;
-    crtc->vyres = vyres;
-    crtc->xoffset = xoffset;
-    crtc->yoffset = yoffset;
-    crtc->bpp = bpp;
-    crtc->h_tot_disp = h_total | (h_disp<<16);
-    crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) |
-			    ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) |
-			    (h_sync_pol<<21);
-    crtc->v_tot_disp = v_total | (v_disp<<16);
-    crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);
-    crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
-    crtc->gen_cntl = pix_width | c_sync | CRTC_EXT_DISP_EN | CRTC_ENABLE;
-    if (M64_HAS(MAGIC_FIFO)) {
-	/* Not VTB/GTB */
-	/* FIXME: magic FIFO values */
-	crtc->gen_cntl |= aty_ld_le32(CRTC_GEN_CNTL, info) & 0x000e0000;
-    }
-    crtc->dp_pix_width = dp_pix_width;
-    crtc->dp_chain_mask = dp_chain_mask;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
+	u32 left, right, upper, lower, hslen, vslen, sync, vmode;
+	u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid,
+	    h_sync_pol;
+	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
+	u32 pix_width, dp_pix_width, dp_chain_mask;
+
+	/* input */
+	xres = var->xres;
+	yres = var->yres;
+	vxres = var->xres_virtual;
+	vyres = var->yres_virtual;
+	xoffset = var->xoffset;
+	yoffset = var->yoffset;
+	bpp = var->bits_per_pixel;
+	left = var->left_margin;
+	right = var->right_margin;
+	upper = var->upper_margin;
+	lower = var->lower_margin;
+	hslen = var->hsync_len;
+	vslen = var->vsync_len;
+	sync = var->sync;
+	vmode = var->vmode;
+
+	/* convert (and round up) and validate */
+	xres = (xres + 7) & ~7;
+	xoffset = (xoffset + 7) & ~7;
+	vxres = (vxres + 7) & ~7;
+	if (vxres < xres + xoffset)
+		vxres = xres + xoffset;
+	h_disp = xres / 8 - 1;
+	if (h_disp > 0xff)
+		FAIL("h_disp too large");
+	h_sync_strt = h_disp + (right / 8);
+	if (h_sync_strt > 0x1ff)
+		FAIL("h_sync_start too large");
+	h_sync_dly = right & 7;
+	h_sync_wid = (hslen + 7) / 8;
+	if (h_sync_wid > 0x1f)
+		FAIL("h_sync_wid too large");
+	h_total = h_sync_strt + h_sync_wid + (h_sync_dly + left + 7) / 8;
+	if (h_total > 0x1ff)
+		FAIL("h_total too large");
+	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+
+	if (vyres < yres + yoffset)
+		vyres = yres + yoffset;
+	v_disp = yres - 1;
+	if (v_disp > 0x7ff)
+		FAIL("v_disp too large");
+	v_sync_strt = v_disp + lower;
+	if (v_sync_strt > 0x7ff)
+		FAIL("v_sync_strt too large");
+	v_sync_wid = vslen;
+	if (v_sync_wid > 0x1f)
+		FAIL("v_sync_wid too large");
+	v_total = v_sync_strt + v_sync_wid + upper;
+	if (v_total > 0x7ff)
+		FAIL("v_total too large");
+	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+
+	c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
+
+	if (bpp <= 8) {
+		bpp = 8;
+		pix_width = CRTC_PIX_WIDTH_8BPP;
+		dp_pix_width =
+		    HOST_8BPP | SRC_8BPP | DST_8BPP |
+		    BYTE_ORDER_LSB_TO_MSB;
+		dp_chain_mask = 0x8080;
+	} else if (bpp <= 16) {
+		bpp = 16;
+		pix_width = CRTC_PIX_WIDTH_15BPP;
+		dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
+		    BYTE_ORDER_LSB_TO_MSB;
+		dp_chain_mask = 0x4210;
+	} else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
+		bpp = 24;
+		pix_width = CRTC_PIX_WIDTH_24BPP;
+		dp_pix_width =
+		    HOST_8BPP | SRC_8BPP | DST_8BPP |
+		    BYTE_ORDER_LSB_TO_MSB;
+		dp_chain_mask = 0x8080;
+	} else if (bpp <= 32) {
+		bpp = 32;
+		pix_width = CRTC_PIX_WIDTH_32BPP;
+		dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
+		    BYTE_ORDER_LSB_TO_MSB;
+		dp_chain_mask = 0x8080;
+	} else
+		FAIL("invalid bpp");
+
+	if (vxres * vyres * bpp / 8 > info->fix.smem_len)
+		FAIL("not enough video RAM");
 
-    return 0;
+	if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+		FAIL("invalid vmode");
+
+	/* output */
+	crtc->vxres = vxres;
+	crtc->vyres = vyres;
+	crtc->xoffset = xoffset;
+	crtc->yoffset = yoffset;
+	crtc->bpp = bpp;
+	crtc->h_tot_disp = h_total | (h_disp << 16);
+	crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly << 8) |
+	    ((h_sync_strt & 0x100) << 4) | (h_sync_wid << 16) |
+	    (h_sync_pol << 21);
+	crtc->v_tot_disp = v_total | (v_disp << 16);
+	crtc->v_sync_strt_wid =
+	    v_sync_strt | (v_sync_wid << 16) | (v_sync_pol << 21);
+	crtc->off_pitch =
+	    ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
+	crtc->gen_cntl =
+	    pix_width | c_sync | CRTC_EXT_DISP_EN | CRTC_ENABLE;
+	if (M64_HAS(MAGIC_FIFO)) {
+		/* Not VTB/GTB */
+		/* FIXME: magic FIFO values */
+		crtc->gen_cntl |=
+		    aty_ld_le32(CRTC_GEN_CNTL, par) & 0x000e0000;
+	}
+	crtc->dp_pix_width = dp_pix_width;
+	crtc->dp_chain_mask = dp_chain_mask;
+
+	return 0;
 }
 
 
 static int aty_crtc_to_var(const struct crtc *crtc,
 			   struct fb_var_screeninfo *var)
 {
-    u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
-    u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
-    u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
-    u32 pix_width;
-
-    /* input */
-    h_total = crtc->h_tot_disp & 0x1ff;
-    h_disp = (crtc->h_tot_disp>>16) & 0xff;
-    h_sync_strt = (crtc->h_sync_strt_wid & 0xff) |
-		  ((crtc->h_sync_strt_wid>>4) & 0x100);
-    h_sync_dly = (crtc->h_sync_strt_wid>>8) & 0x7;
-    h_sync_wid = (crtc->h_sync_strt_wid>>16) & 0x1f;
-    h_sync_pol = (crtc->h_sync_strt_wid>>21) & 0x1;
-    v_total = crtc->v_tot_disp & 0x7ff;
-    v_disp = (crtc->v_tot_disp>>16) & 0x7ff;
-    v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
-    v_sync_wid = (crtc->v_sync_strt_wid>>16) & 0x1f;
-    v_sync_pol = (crtc->v_sync_strt_wid>>21) & 0x1;
-    c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
-    pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
-
-    /* convert */
-    xres = (h_disp+1)*8;
-    yres = v_disp+1;
-    left = (h_total-h_sync_strt-h_sync_wid)*8-h_sync_dly;
-    right = (h_sync_strt-h_disp)*8+h_sync_dly;
-    hslen = h_sync_wid*8;
-    upper = v_total-v_sync_strt-v_sync_wid;
-    lower = v_sync_strt-v_disp;
-    vslen = v_sync_wid;
-    sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
-	   (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
-	   (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
+	u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
+	u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid,
+	    h_sync_pol;
+	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
+	u32 pix_width;
+
+	/* input */
+	h_total = crtc->h_tot_disp & 0x1ff;
+	h_disp = (crtc->h_tot_disp >> 16) & 0xff;
+	h_sync_strt = (crtc->h_sync_strt_wid & 0xff) |
+	    ((crtc->h_sync_strt_wid >> 4) & 0x100);
+	h_sync_dly = (crtc->h_sync_strt_wid >> 8) & 0x7;
+	h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x1f;
+	h_sync_pol = (crtc->h_sync_strt_wid >> 21) & 0x1;
+	v_total = crtc->v_tot_disp & 0x7ff;
+	v_disp = (crtc->v_tot_disp >> 16) & 0x7ff;
+	v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
+	v_sync_wid = (crtc->v_sync_strt_wid >> 16) & 0x1f;
+	v_sync_pol = (crtc->v_sync_strt_wid >> 21) & 0x1;
+	c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
+	pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
+
+	/* convert */
+	xres = (h_disp + 1) * 8;
+	yres = v_disp + 1;
+	left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly;
+	right = (h_sync_strt - h_disp) * 8 + h_sync_dly;
+	hslen = h_sync_wid * 8;
+	upper = v_total - v_sync_strt - v_sync_wid;
+	lower = v_sync_strt - v_disp;
+	vslen = v_sync_wid;
+	sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
+	    (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
+	    (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
 
-    switch (pix_width) {
+	switch (pix_width) {
 #if 0
 	case CRTC_PIX_WIDTH_4BPP:
-	    bpp = 4;
-	    var->red.offset = 0;
-	    var->red.length = 8;
-	    var->green.offset = 0;
-	    var->green.length = 8;
-	    var->blue.offset = 0;
-	    var->blue.length = 8;
-	    var->transp.offset = 0;
-	    var->transp.length = 0;
-	    break;
+		bpp = 4;
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
 #endif
 	case CRTC_PIX_WIDTH_8BPP:
-	    bpp = 8;
-	    var->red.offset = 0;
-	    var->red.length = 8;
-	    var->green.offset = 0;
-	    var->green.length = 8;
-	    var->blue.offset = 0;
-	    var->blue.length = 8;
-	    var->transp.offset = 0;
-	    var->transp.length = 0;
-	    break;
+		bpp = 8;
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
 	case CRTC_PIX_WIDTH_15BPP:	/* RGB 555 */
-	    bpp = 16;
-	    var->red.offset = 10;
-	    var->red.length = 5;
-	    var->green.offset = 5;
-	    var->green.length = 5;
-	    var->blue.offset = 0;
-	    var->blue.length = 5;
-	    var->transp.offset = 0;
-	    var->transp.length = 0;
-	    break;
+		bpp = 16;
+		var->red.offset = 10;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 5;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
 #if 0
 	case CRTC_PIX_WIDTH_16BPP:	/* RGB 565 */
-	    bpp = 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;
-	    var->transp.offset = 0;
-	    var->transp.length = 0;
-	    break;
+		bpp = 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;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
 #endif
 	case CRTC_PIX_WIDTH_24BPP:	/* RGB 888 */
-	    bpp = 24;
-	    var->red.offset = 16;
-	    var->red.length = 8;
-	    var->green.offset = 8;
-	    var->green.length = 8;
-	    var->blue.offset = 0;
-	    var->blue.length = 8;
-	    var->transp.offset = 0;
-	    var->transp.length = 0;
-	    break;
+		bpp = 24;
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
 	case CRTC_PIX_WIDTH_32BPP:	/* ARGB 8888 */
-	    bpp = 32;
-	    var->red.offset = 16;
-	    var->red.length = 8;
-	    var->green.offset = 8;
-	    var->green.length = 8;
-	    var->blue.offset = 0;
-	    var->blue.length = 8;
-	    var->transp.offset = 24;
-	    var->transp.length = 8;
-	    break;
+		bpp = 32;
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		break;
 	default:
-	    FAIL("Invalid pixel width");
-    }
+		FAIL("Invalid pixel width");
+	}
 
-    /* output */
-    var->xres = xres;
-    var->yres = yres;
-    var->xres_virtual = crtc->vxres;
-    var->yres_virtual = crtc->vyres;
-    var->bits_per_pixel = bpp;
-    var->xoffset = crtc->xoffset;
-    var->yoffset = crtc->yoffset;
-    var->left_margin = left;
-    var->right_margin = right;
-    var->upper_margin = upper;
-    var->lower_margin = lower;
-    var->hsync_len = hslen;
-    var->vsync_len = vslen;
-    var->sync = sync;
-    var->vmode = FB_VMODE_NONINTERLACED;
+	/* output */
+	var->xres = xres;
+	var->yres = yres;
+	var->xres_virtual = crtc->vxres;
+	var->yres_virtual = crtc->vyres;
+	var->bits_per_pixel = bpp;
+	var->xoffset = crtc->xoffset;
+	var->yoffset = crtc->yoffset;
+	var->left_margin = left;
+	var->right_margin = right;
+	var->upper_margin = upper;
+	var->lower_margin = lower;
+	var->hsync_len = hslen;
+	var->vsync_len = vslen;
+	var->sync = sync;
+	var->vmode = FB_VMODE_NONINTERLACED;
 
-    return 0;
+	return 0;
 }
 
 /* ------------------------------------------------------------------------- */
 
-static void atyfb_set_par(const struct atyfb_par *par,
-			  struct fb_info_aty *info)
+static void atyfb_set_par(struct atyfb_par *par,
+			  struct fb_info *info)
 {
-    u32 i;
-    int accelmode;
-    u8 tmp;
-
-    accelmode = par->accel_flags;  /* hack */
-
-    info->current_par = *par;
-
-    if (info->blitter_may_be_busy)
-	wait_for_idle(info);
-    tmp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
-    aty_set_crtc(info, &par->crtc);
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);
-					/* better call aty_StrobeClock ?? */
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, CLOCK_STROBE, info);
-
-    info->dac_ops->set_dac(info, &par->pll, par->crtc.bpp, accelmode);
-    info->pll_ops->set_pll(info, &par->pll);
-
-    if (!M64_HAS(INTEGRATED)) {
-	/* Don't forget MEM_CNTL */
-	i = aty_ld_le32(MEM_CNTL, info) & 0xf0ffffff;
-	switch (par->crtc.bpp) {
-	    case 8:
-		i |= 0x02000000;
-		break;
-	    case 16:
-		i |= 0x03000000;
-		break;
-	    case 32:
-		i |= 0x06000000;
-		break;
-	}
-	aty_st_le32(MEM_CNTL, i, info);
-    } else {
-	i = aty_ld_le32(MEM_CNTL, info) & 0xf00fffff;
-	if (!M64_HAS(MAGIC_POSTDIV))
-	    i |= info->mem_refresh_rate << 20;
-	switch (par->crtc.bpp) {
-	    case 8:
-	    case 24:
-		i |= 0x00000000;
-		break;
-	    case 16:
-		i |= 0x04000000;
-		break;
-	    case 32:
-		i |= 0x08000000;
-		break;
-	}
-	if (M64_HAS(CT_BUS)) {
-	    aty_st_le32(DAC_CNTL, 0x87010184, info);
-	    aty_st_le32(BUS_CNTL, 0x680000f9, info);
-	} else if (M64_HAS(VT_BUS)) {
-	    aty_st_le32(DAC_CNTL, 0x87010184, info);
-	    aty_st_le32(BUS_CNTL, 0x680000f9, info);
-	}  else if (M64_HAS(MOBIL_BUS)) {
-	    aty_st_le32(DAC_CNTL, 0x80010102, info);
-	    aty_st_le32(BUS_CNTL, 0x7b33a040, info);
+	u32 i;
+	int accelmode;
+	u8 tmp;
+
+	accelmode = par->accel_flags;	/* hack */
+
+	if (par->blitter_may_be_busy)
+		wait_for_idle(par);
+	tmp = aty_ld_8(CRTC_GEN_CNTL + 3, par);
+	aty_set_crtc(par, &par->crtc);
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset, 0, par);
+	/* better call aty_StrobeClock ?? */
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset, CLOCK_STROBE, par);
+
+	par->dac_ops->set_dac(info, &par->pll, par->crtc.bpp, accelmode);
+	par->pll_ops->set_pll(info, &par->pll);
+
+	if (!M64_HAS(INTEGRATED)) {
+		/* Don't forget MEM_CNTL */
+		i = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
+		switch (par->crtc.bpp) {
+		case 8:
+			i |= 0x02000000;
+			break;
+		case 16:
+			i |= 0x03000000;
+			break;
+		case 32:
+			i |= 0x06000000;
+			break;
+		}
+		aty_st_le32(MEM_CNTL, i, par);
 	} else {
-	    /* GT */
-	    aty_st_le32(DAC_CNTL, 0x86010102, info);
-	    aty_st_le32(BUS_CNTL, 0x7b23a040, info);
-	    aty_st_le32(EXT_MEM_CNTL,
-			aty_ld_le32(EXT_MEM_CNTL, info) | 0x5000001, info);
+		i = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
+		if (!M64_HAS(MAGIC_POSTDIV))
+			i |= par->mem_refresh_rate << 20;
+		switch (par->crtc.bpp) {
+		case 8:
+		case 24:
+			i |= 0x00000000;
+			break;
+		case 16:
+			i |= 0x04000000;
+			break;
+		case 32:
+			i |= 0x08000000;
+			break;
+		}
+		if (M64_HAS(CT_BUS)) {
+			aty_st_le32(DAC_CNTL, 0x87010184, par);
+			aty_st_le32(BUS_CNTL, 0x680000f9, par);
+		} else if (M64_HAS(VT_BUS)) {
+			aty_st_le32(DAC_CNTL, 0x87010184, par);
+			aty_st_le32(BUS_CNTL, 0x680000f9, par);
+		} else if (M64_HAS(MOBIL_BUS)) {
+			aty_st_le32(DAC_CNTL, 0x80010102, par);
+			aty_st_le32(BUS_CNTL, 0x7b33a040, par);
+		} else {
+			/* GT */
+			aty_st_le32(DAC_CNTL, 0x86010102, par);
+			aty_st_le32(BUS_CNTL, 0x7b23a040, par);
+			aty_st_le32(EXT_MEM_CNTL,
+				    aty_ld_le32(EXT_MEM_CNTL,
+						par) | 0x5000001, par);
+		}
+		aty_st_le32(MEM_CNTL, i, par);
 	}
-	aty_st_le32(MEM_CNTL, i, info);
-    }
-    aty_st_8(DAC_MASK, 0xff, info);
+	aty_st_8(DAC_MASK, 0xff, par);
 
-    /* Initialize the graphics engine */
-    if (par->accel_flags & FB_ACCELF_TEXT)
-	aty_init_engine(par, info);
+	/* Initialize the graphics engine */
+	if (par->accel_flags & FB_ACCELF_TEXT)
+		aty_init_engine(par, info);
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-    if (!console_fb_info || console_fb_info == &info->fb_info) {
-	struct fb_var_screeninfo var;
-	int vmode, cmode;
-	display_info.height = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
-	display_info.width = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;
-	display_info.depth = par->crtc.bpp;
-	display_info.pitch = par->crtc.vxres*par->crtc.bpp/8;
-	atyfb_encode_var(&var, par, info);
-	if (mac_var_to_vmode(&var, &vmode, &cmode))
-	    display_info.mode = 0;
-	else
-	    display_info.mode = vmode;
-	strcpy(display_info.name, atyfb_name);
-	display_info.fb_address = info->frame_buffer_phys;
-	display_info.cmap_adr_address = info->ati_regbase_phys+0xc0;
-	display_info.cmap_data_address = info->ati_regbase_phys+0xc1;
-	display_info.disp_reg_address = info->ati_regbase_phys;
-    }
-#endif /* CONFIG_FB_COMPAT_XPMAC */
 #ifdef CONFIG_BOOTX_TEXT
-	btext_update_display(info->frame_buffer_phys,
-			(((par->crtc.h_tot_disp>>16) & 0xff)+1)*8,
-			((par->crtc.v_tot_disp>>16) & 0x7ff)+1,
-			par->crtc.bpp,
-			par->crtc.vxres*par->crtc.bpp/8);
-#endif /* CONFIG_BOOTX_TEXT */
+	btext_update_display(info->fix.smem_start,
+			     (((par->crtc.h_tot_disp >> 16) & 0xff) +
+			      1) * 8,
+			     ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
+			     par->crtc.bpp,
+			     par->crtc.vxres * par->crtc.bpp / 8);
+#endif				/* CONFIG_BOOTX_TEXT */
 }
 
 static int atyfb_decode_var(const struct fb_var_screeninfo *var,
 			    struct atyfb_par *par,
-			    const struct fb_info_aty *info)
+			    const struct fb_info *info)
 {
-    int err;
+	int err;
 
-    if ((err = aty_var_to_crtc(info, var, &par->crtc)) ||
-	(err = info->pll_ops->var_to_pll(info, var->pixclock, par->crtc.bpp,
-		    			 &par->pll)))
-	return err;
+	if ((err = aty_var_to_crtc(info, var, &par->crtc)) ||
+	    (err =
+	     par->pll_ops->var_to_pll(info, var->pixclock, par->crtc.bpp,
+				       &par->pll)))
+		return err;
 
-    if (var->accel_flags & FB_ACCELF_TEXT)
-	par->accel_flags = FB_ACCELF_TEXT;
-    else
-	par->accel_flags = 0;
+	if (var->accel_flags & FB_ACCELF_TEXT)
+		par->accel_flags = FB_ACCELF_TEXT;
+	else
+		par->accel_flags = 0;
 
-#if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
-    if (!fbmon_valid_timings(var->pixclock, htotal, vtotal, info))
-	return -EINVAL;
+#if 0				/* fbmon is not done. uncomment for 2.5.x -brad */
+	if (!fbmon_valid_timings(var->pixclock, htotal, vtotal, info))
+		return -EINVAL;
 #endif
 
-    return 0;
+	return 0;
 }
 
 static int atyfb_encode_var(struct fb_var_screeninfo *var,
 			    const struct atyfb_par *par,
-			    const struct fb_info_aty *info)
+			    const struct fb_info *info)
 {
-    int err;
+	int err;
 
-    memset(var, 0, sizeof(struct fb_var_screeninfo));
+	memset(var, 0, sizeof(struct fb_var_screeninfo));
 
-    if ((err = aty_crtc_to_var(&par->crtc, var)))
-	return err;
-    var->pixclock = info->pll_ops->pll_to_var(info, &par->pll);
+	if ((err = aty_crtc_to_var(&par->crtc, var)))
+		return err;
+	var->pixclock = par->pll_ops->pll_to_var(info, &par->pll);
 
-    var->height = -1;
-    var->width = -1;
-    var->accel_flags = par->accel_flags;
+	var->height = -1;
+	var->width = -1;
+	var->accel_flags = par->accel_flags;
 
-    return 0;
+	return 0;
 }
 
 
 
 static void set_off_pitch(struct atyfb_par *par,
-			  const struct fb_info_aty *info)
+			  const struct fb_info *info)
 {
-    u32 xoffset = par->crtc.xoffset;
-    u32 yoffset = par->crtc.yoffset;
-    u32 vxres = par->crtc.vxres;
-    u32 bpp = par->crtc.bpp;
-
-    par->crtc.off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
-    aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, info);
+	u32 xoffset = par->crtc.xoffset;
+	u32 yoffset = par->crtc.yoffset;
+	u32 vxres = par->crtc.vxres;
+	u32 bpp = par->crtc.bpp;
+
+	par->crtc.off_pitch =
+	    ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
+	aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
 }
 
 
@@ -890,138 +959,117 @@
      */
 
 static int atyfb_open(struct fb_info *info, int user)
-
 {
 #ifdef __sparc__
-    struct fb_info_aty *fb = (struct fb_info_aty *)info;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
 
-    if (user) {
-	fb->open++;
-	fb->mmaped = 0;
-	fb->vtconsole = -1;
-    } else {
-	fb->consolecnt++;
-    }
+	if (user) {
+		par->open++;
+		par->mmaped = 0;
+		par->vtconsole = -1;
+	} else {
+		par->consolecnt++;
+	}
 #endif
-    return(0);
+	return (0);
 }
 
 struct fb_var_screeninfo default_var = {
-    /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
-    640, 480, 640, 480, 0, 0, 8, 0,
-    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-    0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
-    0, FB_VMODE_NONINTERLACED
+	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
+	640, 480, 640, 480, 0, 0, 8, 0,
+	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
+	0, FB_VMODE_NONINTERLACED
 };
 
 static int atyfb_release(struct fb_info *info, int user)
 {
 #ifdef __sparc__
-    struct fb_info_aty *fb = (struct fb_info_aty *)info;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;	
 
-    if (user) {
-	fb->open--;
-	mdelay(1);
-	wait_for_idle(fb);
-	if (!fb->open) {
-		int was_mmaped = fb->mmaped;
-
-		fb->mmaped = 0;
-		if (fb->vtconsole != -1)
-			vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
-		fb->vtconsole = -1;
-
-		if (was_mmaped) {
-			struct fb_var_screeninfo var;
-
-			/* Now reset the default display config, we have no
-			 * idea what the program(s) which mmap'd the chip did
-			 * to the configuration, nor whether it restored it
-			 * correctly.
-			 */
-			var = default_var;
-			if (noaccel)
-				var.accel_flags &= ~FB_ACCELF_TEXT;
-			else
-				var.accel_flags |= FB_ACCELF_TEXT;
-			if (var.yres == var.yres_virtual) {
-				u32 vram = (fb->total_vram - (PAGE_SIZE << 2));
-				var.yres_virtual = ((vram * 8) / var.bits_per_pixel) /
-					var.xres_virtual;
-				if (var.yres_virtual < var.yres)
-					var.yres_virtual = var.yres;
+	if (user) {
+		par->open--;
+		mdelay(1);
+		wait_for_idle(par);
+		if (!par->open) {
+			int was_mmaped = par->mmaped;
+
+			par->mmaped = 0;
+			if (par->vtconsole != -1)
+				vt_cons[par->vtconsole]->vc_mode = KD_TEXT;
+			par->vtconsole = -1;
+
+			if (was_mmaped) {
+				struct fb_var_screeninfo var;
+
+				/* Now reset the default display config, we have no
+				 * idea what the program(s) which mmap'd the chip did
+				 * to the configuration, nor whether it restored it
+				 * correctly.
+				 */
+				var = default_var;
+				if (noaccel)
+					var.accel_flags &= ~FB_ACCELF_TEXT;
+				else
+					var.accel_flags |= FB_ACCELF_TEXT;
+				if (var.yres == var.yres_virtual) {
+					u32 vram =
+					    (info->fix.smem_len -
+					     (PAGE_SIZE << 2));
+					var.yres_virtual =
+					    ((vram * 8) /
+					     var.bits_per_pixel) /
+					    var.xres_virtual;
+					if (var.yres_virtual < var.yres)
+						var.yres_virtual =
+						    var.yres;
+				}
+				atyfb_set_var(&var, -1, info);
 			}
-			atyfb_set_var(&var, -1, &fb->fb_info);
 		}
+	} else {
+		par->consolecnt--;
 	}
-    } else {
-	fb->consolecnt--;
-    }
 #endif
-    return(0);
+	return (0);
 }
 
 
 static int encode_fix(struct fb_fix_screeninfo *fix,
 		      const struct atyfb_par *par,
-		      const struct fb_info_aty *info)
+		      const struct fb_info *info)
 {
-    memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-
-    strcpy(fix->id, atyfb_name);
-    fix->smem_start = info->frame_buffer_phys;
-    fix->smem_len = (u32)info->total_vram;
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 
-    /*
-     *  Reg Block 0 (CT-compatible block) is at ati_regbase_phys
-     *  Reg Block 1 (multimedia extensions) is at ati_regbase_phys-0x400
-     */
-    if (M64_HAS(GX)) {
-	fix->mmio_start = info->ati_regbase_phys;
-	fix->mmio_len = 0x400;
-	fix->accel = FB_ACCEL_ATI_MACH64GX;
-    } else if (M64_HAS(CT)) {
-	fix->mmio_start = info->ati_regbase_phys;
-	fix->mmio_len = 0x400;
-	fix->accel = FB_ACCEL_ATI_MACH64CT;
-    } else if (M64_HAS(VT)) {
-	fix->mmio_start = info->ati_regbase_phys-0x400;
-	fix->mmio_len = 0x800;
-	fix->accel = FB_ACCEL_ATI_MACH64VT;
-    } else /* if (M64_HAS(GT)) */ {
-	fix->mmio_start = info->ati_regbase_phys-0x400;
-	fix->mmio_len = 0x800;
-	fix->accel = FB_ACCEL_ATI_MACH64GT;
-    }
-    fix->type = FB_TYPE_PACKED_PIXELS;
-    fix->type_aux = 0;
-    fix->line_length = par->crtc.vxres*par->crtc.bpp/8;
-    fix->visual = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR
-				     : FB_VISUAL_DIRECTCOLOR;
-    fix->ywrapstep = 0;
-    fix->xpanstep = 8;
-    fix->ypanstep = 1;
-
-    return 0;
+	strcpy(fix->id, atyfb_name);
+	fix->smem_start = info->fix.smem_start;
+	fix->smem_len = info->fix.smem_len;
+	fix->mmio_start = info->fix.mmio_start;
+	fix->mmio_len = info->fix.mmio_len;
+	fix->accel = info->fix.accel;
+	fix->type = info->fix.type;
+	fix->type_aux = info->fix.type_aux;
+	fix->line_length = par->crtc.vxres * par->crtc.bpp / 8;
+	fix->visual = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR
+	    : FB_VISUAL_DIRECTCOLOR;
+	fix->ywrapstep = info->fix.ywrapstep;
+	fix->xpanstep = info->fix.xpanstep;
+	fix->ypanstep = info->fix.ypanstep;
+	return 0;
 }
 
-
     /*
      *  Get the Fixed Part of the Display
      */
 
 static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *fb)
+			 struct fb_info *info)
 {
-    const struct fb_info_aty *info = (struct fb_info_aty *)fb;
-    struct atyfb_par par;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
 
-    if (con == -1)
-	par = info->default_par;
-    else
-	atyfb_decode_var(&fb_display[con].var, &par, info);
-    encode_fix(fix, &par, info);
-    return 0;
+	atyfb_decode_var(&fb_display[con].var, par, info);
+	encode_fix(fix, par, info);
+	return 0;
 }
 
 
@@ -1030,58 +1078,48 @@
      */
 
 static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *fb)
+			 struct fb_info *info)
 {
-    const struct fb_info_aty *info = (struct fb_info_aty *)fb;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
 
-    if (con == -1)
-	atyfb_encode_var(var, &info->default_par, info);
-    else
-	*var = fb_display[con].var;
-    return 0;
+	if (con == -1)
+		atyfb_encode_var(var, par, info);
+	else
+		*var = fb_display[con].var;
+	return 0;
 }
 
 
-static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
-			     int bpp, int accel)
+static void atyfb_set_dispsw(struct display *disp,
+			     struct fb_info *info)
 {
-	    switch (bpp) {
-#ifdef FBCON_HAS_CFB8
-		case 8:
-		    info->dispsw = accel ? fbcon_aty8 : fbcon_cfb8;
-		    disp->dispsw = &info->dispsw;
-		    break;
-#endif
-#ifdef FBCON_HAS_CFB16
-		case 16:
-		    info->dispsw = accel ? fbcon_aty16 : fbcon_cfb16;
-		    disp->dispsw = &info->dispsw;
-		    disp->dispsw_data = info->fbcon_cmap.cfb16;
-		    break;
-#endif
-#ifdef FBCON_HAS_CFB24
-		case 24:
-		    info->dispsw = accel ? fbcon_aty24 : fbcon_cfb24;
-		    disp->dispsw = &info->dispsw;
-		    disp->dispsw_data = info->fbcon_cmap.cfb24;
-		    break;
-#endif
-#ifdef FBCON_HAS_CFB32
-		case 32:
-		    info->dispsw = accel ? fbcon_aty32 : fbcon_cfb32;
-		    disp->dispsw = &info->dispsw;
-		    disp->dispsw_data = info->fbcon_cmap.cfb32;
-		    break;
-#endif
-		default:
-		    disp->dispsw = &fbcon_dummy;
-	    }
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		disp->dispsw = &fbcon_aty8;
+		break;
+	case 16:
+		disp->dispsw = &fbcon_aty16;
+		disp->dispsw_data = info->pseudo_palette;
+		break;
+	case 24:
+		disp->dispsw = &fbcon_aty24;
+		disp->dispsw_data = info->pseudo_palette;
+		break;
+	case 32:
+		disp->dispsw = &fbcon_aty32;
+		disp->dispsw_data = info->pseudo_palette;
+		break;
+	default:
+		disp->dispsw = &fbcon_dummy;
+	}
 #ifdef CONFIG_FB_ATY_CT
-	    if (info->cursor) {
-		info->dispsw.cursor = atyfb_cursor;
-		info->dispsw.set_font = atyfb_set_font;
-	    }
-#endif /* CONFIG_FB_ATY_CT */
+/*
+	if (info->cursor) {
+		&disp->dispsw.cursor = atyfb_cursor;
+		&disp->dispsw.set_font = atyfb_set_font;
+	}
+*/
+#endif			/* CONFIG_FB_ATY_CT */
 }
 
 
@@ -1090,68 +1128,70 @@
      */
 
 static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *fb)
+			 struct fb_info *info)
 {
-    struct fb_info_aty *info = (struct fb_info_aty *)fb;
-    struct atyfb_par par;
-    struct display *display;
-    int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;
-    int activate = var->activate;
-
-    if (con >= 0)
-	display = &fb_display[con];
-    else
-	display = fb->disp;	/* used during initialization */
-
-    if ((err = atyfb_decode_var(var, &par, info)))
-	return err;
-
-    atyfb_encode_var(var, &par, (struct fb_info_aty *)info);
-
-    if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-	oldxres = display->var.xres;
-	oldyres = display->var.yres;
-	oldvxres = display->var.xres_virtual;
-	oldvyres = display->var.yres_virtual;
-	oldbpp = display->var.bits_per_pixel;
-	oldaccel = display->var.accel_flags;
-	display->var = *var;
-	accel = var->accel_flags & FB_ACCELF_TEXT;
-	if (oldxres != var->xres || oldyres != var->yres ||
-	    oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
-	    oldbpp != var->bits_per_pixel || oldaccel != var->accel_flags) {
-	    struct fb_fix_screeninfo fix;
-
-	    encode_fix(&fix, &par, info);
-	    fb->screen_base = (char *)info->frame_buffer;
-	    display->visual = fix.visual;
-	    display->type = fix.type;
-	    display->type_aux = fix.type_aux;
-	    display->ypanstep = fix.ypanstep;
-	    display->ywrapstep = fix.ywrapstep;
-	    display->line_length = fix.line_length;
-	    display->can_soft_blank = 1;
-	    display->inverse = 0;
-	    if (accel)
-	    	display->scrollmode = (info->bus_type == PCI) ? SCROLL_YNOMOVE : 0;
-	    else
-	    	display->scrollmode = SCROLL_YREDRAW;
-	    if (info->fb_info.changevar)
-		(*info->fb_info.changevar)(con);
-	}
-	if (!info->fb_info.display_fg ||
-	    info->fb_info.display_fg->vc_num == con) {
-	    atyfb_set_par(&par, info);
-	    atyfb_set_dispsw(display, info, par.crtc.bpp, accel);
-	}
-	if (oldbpp != var->bits_per_pixel) {
-	    if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct display *display;
+	int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel,
+	    err;
+	int activate = var->activate;
+
+	if (con >= 0)
+		display = &fb_display[con];
+	else
+		display = info->disp;	/* used during initialization */
+
+	if ((err = atyfb_decode_var(var, par, info)))
 		return err;
-	    do_install_cmap(con, &info->fb_info);
-	}
-    }
 
-    return 0;
+	atyfb_encode_var(var, par, info);
+
+	if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+		oldxres = display->var.xres;
+		oldyres = display->var.yres;
+		oldvxres = display->var.xres_virtual;
+		oldvyres = display->var.yres_virtual;
+		oldbpp = display->var.bits_per_pixel;
+		oldaccel = display->var.accel_flags;
+		display->var = *var;
+		accel = var->accel_flags & FB_ACCELF_TEXT;
+		if (oldxres != var->xres || oldyres != var->yres ||
+		    oldvxres != var->xres_virtual
+		    || oldvyres != var->yres_virtual
+		    || oldbpp != var->bits_per_pixel
+		    || oldaccel != var->accel_flags) {
+			struct fb_fix_screeninfo fix;
+
+			encode_fix(&fix, par, info);
+			display->visual = fix.visual;
+			display->type = fix.type;
+			display->type_aux = fix.type_aux;
+			display->ypanstep = fix.ypanstep;
+			display->ywrapstep = fix.ywrapstep;
+			display->line_length = fix.line_length;
+			display->can_soft_blank = 1;
+			display->inverse = 0;
+			if (accel)
+				display->scrollmode =
+				    (par->bus_type ==
+				     PCI) ? SCROLL_YNOMOVE : 0;
+			else
+				display->scrollmode = SCROLL_YREDRAW;
+			if (info->changevar)
+				(*info->changevar) (con);
+		}
+		if (!info->display_fg ||
+		    info->display_fg->vc_num == con) {
+			atyfb_set_par(par, info);
+			atyfb_set_dispsw(display, info);
+		}
+		if (oldbpp != var->bits_per_pixel) {
+			if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+				return err;
+			do_install_cmap(con, info);
+		}
+	}
+	return 0;
 }
 
 
@@ -1162,85 +1202,40 @@
      */
 
 static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
-			     struct fb_info *fb)
-{
-    struct fb_info_aty *info = (struct fb_info_aty *)fb;
-    u32 xres, yres, xoffset, yoffset;
-    struct atyfb_par *par = &info->current_par;
-
-    xres = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;
-    yres = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
-    xoffset = (var->xoffset+7) & ~7;
-    yoffset = var->yoffset;
-    if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
-	return -EINVAL;
-    par->crtc.xoffset = xoffset;
-    par->crtc.yoffset = yoffset;
-    set_off_pitch(par, info);
-    return 0;
-}
-
-    /*
-     *  Get the Colormap
-     */
-
-static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info)
-{
-    if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
-	return fb_get_cmap(cmap, kspc, atyfb_getcolreg, info);
-    else if (fb_display[con].cmap.len) /* non default colormap? */
-	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-    else {
-	int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
-	fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
-    }
-    return 0;
-}
-
-    /*
-     *  Set the Colormap
-     */
-
-static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info)
+			     struct fb_info *info)
 {
-    int err;
-    struct display *disp;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 xres, yres, xoffset, yoffset;
 
-    if (con >= 0)
-    	disp = &fb_display[con];
-    else
-        disp = info->disp;
-    if (!disp->cmap.len) {	/* no colormap allocated? */
-	int size = disp->var.bits_per_pixel == 16 ? 32 : 256;
-	if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))
-	    return err;
-    }
-    if (!info->display_fg || con == info->display_fg->vc_num)			/* current console? */
-	return fb_set_cmap(cmap, kspc, info);
-    else
-	fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
-    return 0;
+	xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
+	yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
+	xoffset = (var->xoffset + 7) & ~7;
+	yoffset = var->yoffset;
+	if (xoffset + xres > par->crtc.vxres
+	    || yoffset + yres > par->crtc.vyres)
+		return -EINVAL;
+	par->crtc.xoffset = xoffset;
+	par->crtc.yoffset = yoffset;
+	set_off_pitch(par, info);
+	return 0;
 }
 
-
 #ifdef DEBUG
 #define ATYIO_CLKR		0x41545900	/* ATY\00 */
 #define ATYIO_CLKW		0x41545901	/* ATY\01 */
 
 struct atyclk {
-    u32 ref_clk_per;
-    u8 pll_ref_div;
-    u8 mclk_fb_div;
-    u8 mclk_post_div;		/* 1,2,3,4,8 */
-    u8 vclk_fb_div;
-    u8 vclk_post_div;		/* 1,2,3,4,6,8,12 */
-    u32 dsp_xclks_per_row;	/* 0-16383 */
-    u32 dsp_loop_latency;	/* 0-15 */
-    u32 dsp_precision;		/* 0-7 */
-    u32 dsp_on;			/* 0-2047 */
-    u32 dsp_off;		/* 0-2047 */
+	u32 ref_clk_per;
+	u8 pll_ref_div;
+	u8 mclk_fb_div;
+	u8 mclk_post_div;	/* 1,2,3,4,8 */
+	u8 vclk_fb_div;
+	u8 vclk_post_div;	/* 1,2,3,4,6,8,12 */
+	u32 dsp_xclks_per_row;	/* 0-16383 */
+	u32 dsp_loop_latency;	/* 0-15 */
+	u32 dsp_precision;	/* 0-7 */
+	u32 dsp_on;		/* 0-2047 */
+	u32 dsp_off;		/* 0-2047 */
 };
 
 #define ATYIO_FEATR		0x41545902	/* ATY\02 */
@@ -1248,114 +1243,122 @@
 #endif
 
 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-		       u_long arg, int con, struct fb_info *info2)
+		       u_long arg, int con, struct fb_info *info)
 {
 #if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT))
-    struct fb_info_aty *info = (struct fb_info_aty *)info2;
-#endif /* __sparc__ || DEBUG */
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+#endif				/* __sparc__ || DEBUG */
 #ifdef __sparc__
-    struct fbtype fbtyp;
-    struct display *disp;
+	struct fbtype fbtyp;
+	struct display *disp;
 
-    if (con >= 0)
-    	disp = &fb_display[con];
-    else
-        disp = info2->disp;
+	if (con >= 0)
+		disp = &fb_display[con];
+	else
+		disp = info2->disp;
 #endif
 
-    switch (cmd) {
+	switch (cmd) {
 #ifdef __sparc__
-    case FBIOGTYPE:
-	fbtyp.fb_type = FBTYPE_PCI_GENERIC;
-	fbtyp.fb_width = info->current_par.crtc.vxres;
-	fbtyp.fb_height = info->current_par.crtc.vyres;
-	fbtyp.fb_depth = info->current_par.crtc.bpp;
-	fbtyp.fb_cmsize = disp->cmap.len;
-	fbtyp.fb_size = info->total_vram;
-	if (copy_to_user((struct fbtype *)arg, &fbtyp, sizeof(fbtyp)))
-		return -EFAULT;
-	break;
-#endif /* __sparc__ */
+	case FBIOGTYPE:
+		fbtyp.fb_type = FBTYPE_PCI_GENERIC;
+		fbtyp.fb_width = par->crtc.vxres;
+		fbtyp.fb_height = par->crtc.vyres;
+		fbtyp.fb_depth = par->crtc.bpp;
+		fbtyp.fb_cmsize = disp->cmap.len;
+		fbtyp.fb_size = info->fix.smem_len;
+		if (copy_to_user
+		    ((struct fbtype *) arg, &fbtyp, sizeof(fbtyp)))
+			return -EFAULT;
+		break;
+#endif				/* __sparc__ */
 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
-    case ATYIO_CLKR:
-	if (M64_HAS(INTEGRATED)) {
-	    struct atyclk clk;
-	    union aty_pll *pll = &info->current_par.pll;
-	    u32 dsp_config = pll->ct.dsp_config;
-	    u32 dsp_on_off = pll->ct.dsp_on_off;
-	    clk.ref_clk_per = info->ref_clk_per;
-	    clk.pll_ref_div = pll->ct.pll_ref_div;
-	    clk.mclk_fb_div = pll->ct.mclk_fb_div;
-	    clk.mclk_post_div = pll->ct.mclk_post_div_real;
-	    clk.vclk_fb_div = pll->ct.vclk_fb_div;
-	    clk.vclk_post_div = pll->ct.vclk_post_div_real;
-	    clk.dsp_xclks_per_row = dsp_config & 0x3fff;
-	    clk.dsp_loop_latency = (dsp_config>>16) & 0xf;
-	    clk.dsp_precision = (dsp_config>>20) & 7;
-	    clk.dsp_on = dsp_on_off & 0x7ff;
-	    clk.dsp_off = (dsp_on_off>>16) & 0x7ff;
-	    if (copy_to_user((struct atyclk *)arg, &clk, sizeof(clk)))
-		    return -EFAULT;
-	} else
-	    return -EINVAL;
-	break;
-    case ATYIO_CLKW:
-	if (M64_HAS(INTEGRATED)) {
-	    struct atyclk clk;
-	    union aty_pll *pll = &info->current_par.pll;
-	    if (copy_from_user(&clk, (struct atyclk *)arg, sizeof(clk)))
-		    return -EFAULT;
-	    info->ref_clk_per = clk.ref_clk_per;
-	    pll->ct.pll_ref_div = clk.pll_ref_div;
-	    pll->ct.mclk_fb_div = clk.mclk_fb_div;
-	    pll->ct.mclk_post_div_real = clk.mclk_post_div;
-	    pll->ct.vclk_fb_div = clk.vclk_fb_div;
-	    pll->ct.vclk_post_div_real = clk.vclk_post_div;
-	    pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
-				 ((clk.dsp_loop_latency & 0xf)<<16) |
-				 ((clk.dsp_precision & 7)<<20);
-	    pll->ct.dsp_on_off = (clk.dsp_on & 0x7ff) |
-				 ((clk.dsp_off & 0x7ff)<<16);
-	    aty_calc_pll_ct(info, &pll->ct);
-	    aty_set_pll_ct(info, pll);
-	} else
-	    return -EINVAL;
-	break;
-    case ATYIO_FEATR:
-	if (get_user(info->features, (u32 *)arg))
-	    return -EFAULT;
-	break;
-    case ATYIO_FEATW:
-	if (put_user(info->features, (u32 *)arg))
-	    return -EFAULT;
-	break;
-#endif /* DEBUG && CONFIG_FB_ATY_CT */
-    default:
-	return -EINVAL;
-    }
-    return 0;
+	case ATYIO_CLKR:
+		if (M64_HAS(INTEGRATED)) {
+			struct atyclk clk;
+			union aty_pll *pll = par->pll;
+			u32 dsp_config = pll->ct.dsp_config;
+			u32 dsp_on_off = pll->ct.dsp_on_off;
+			clk.ref_clk_per = par->ref_clk_per;
+			clk.pll_ref_div = pll->ct.pll_ref_div;
+			clk.mclk_fb_div = pll->ct.mclk_fb_div;
+			clk.mclk_post_div = pll->ct.mclk_post_div_real;
+			clk.vclk_fb_div = pll->ct.vclk_fb_div;
+			clk.vclk_post_div = pll->ct.vclk_post_div_real;
+			clk.dsp_xclks_per_row = dsp_config & 0x3fff;
+			clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
+			clk.dsp_precision = (dsp_config >> 20) & 7;
+			clk.dsp_on = dsp_on_off & 0x7ff;
+			clk.dsp_off = (dsp_on_off >> 16) & 0x7ff;
+			if (copy_to_user
+			    ((struct atyclk *) arg, &clk, sizeof(clk)))
+				return -EFAULT;
+		} else
+			return -EINVAL;
+		break;
+	case ATYIO_CLKW:
+		if (M64_HAS(INTEGRATED)) {
+			struct atyclk clk;
+			union aty_pll *pll = par->pll;
+			if (copy_from_user
+			    (&clk, (struct atyclk *) arg, sizeof(clk)))
+				return -EFAULT;
+			par->ref_clk_per = clk.ref_clk_per;
+			pll->ct.pll_ref_div = clk.pll_ref_div;
+			pll->ct.mclk_fb_div = clk.mclk_fb_div;
+			pll->ct.mclk_post_div_real = clk.mclk_post_div;
+			pll->ct.vclk_fb_div = clk.vclk_fb_div;
+			pll->ct.vclk_post_div_real = clk.vclk_post_div;
+			pll->ct.dsp_config =
+			    (clk.
+			     dsp_xclks_per_row & 0x3fff) | ((clk.
+							     dsp_loop_latency
+							     & 0xf) << 16)
+			    | ((clk.dsp_precision & 7) << 20);
+			pll->ct.dsp_on_off =
+			    (clk.
+			     dsp_on & 0x7ff) | ((clk.
+						 dsp_off & 0x7ff) << 16);
+			aty_calc_pll_ct(info, &pll->ct);
+			aty_set_pll_ct(info, pll);
+		} else
+			return -EINVAL;
+		break;
+	case ATYIO_FEATR:
+		if (get_user(par->features, (u32 *) arg))
+			return -EFAULT;
+		break;
+	case ATYIO_FEATW:
+		if (put_user(par->features, (u32 *) arg))
+			return -EFAULT;
+		break;
+#endif				/* DEBUG && CONFIG_FB_ATY_CT */
+	default:
+		return -EINVAL;
+	}
+	return 0;
 }
 
 static int atyfb_rasterimg(struct fb_info *info, int start)
 {
-    struct fb_info_aty *fb = (struct fb_info_aty *)info;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
 
-    if (fb->blitter_may_be_busy)
-	wait_for_idle(fb);
-    return 0;
+	if (par->blitter_may_be_busy)
+		wait_for_idle(par);
+	return 0;
 }
 
 #ifdef __sparc__
 static int atyfb_mmap(struct fb_info *info, struct file *file,
 		      struct vm_area_struct *vma)
 {
-	struct fb_info_aty *fb = (struct fb_info_aty *)info;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
 	unsigned int size, page, map_size = 0;
 	unsigned long map_offset = 0;
 	unsigned long off;
 	int i;
 
-	if (!fb->mmap_map)
+	if (!par->mmap_map)
 		return -ENXIO;
 
 	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
@@ -1367,18 +1370,18 @@
 	/* To stop the swapper from even considering these pages. */
 	vma->vm_flags |= (VM_SHM | VM_LOCKED);
 
-	if (((vma->vm_pgoff == 0) && (size == fb->total_vram)) ||
-	    ((off == fb->total_vram) && (size == PAGE_SIZE)))
+	if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
+	    ((off == info->fix.smem_len) && (size == PAGE_SIZE)))
 		off += 0x8000000000000000UL;
 
 	vma->vm_pgoff = off >> PAGE_SHIFT;	/* propagate off changes */
 
 	/* Each page, see which map applies */
-	for (page = 0; page < size; ) {
+	for (page = 0; page < size;) {
 		map_size = 0;
-		for (i = 0; fb->mmap_map[i].size; i++) {
-			unsigned long start = fb->mmap_map[i].voff;
-			unsigned long end = start + fb->mmap_map[i].size;
+		for (i = 0; par->mmap_map[i].size; i++) {
+			unsigned long start = par->mmap_map[i].voff;
+			unsigned long end = start + par->mmap_map[i].size;
 			unsigned long offset = off + page;
 
 			if (start > offset)
@@ -1386,8 +1389,9 @@
 			if (offset >= end)
 				continue;
 
-			map_size = fb->mmap_map[i].size - (offset - start);
-			map_offset = fb->mmap_map[i].poff + (offset - start);
+			map_size = par->mmap_map[i].size - (offset - start);
+			map_offset =
+			    par->mmap_map[i].poff + (offset - start);
 			break;
 		}
 		if (!map_size) {
@@ -1397,8 +1401,9 @@
 		if (page + map_size > size)
 			map_size = size - page;
 
-		pgprot_val(vma->vm_page_prot) &= ~(fb->mmap_map[i].prot_mask);
-		pgprot_val(vma->vm_page_prot) |= fb->mmap_map[i].prot_flag;
+		pgprot_val(vma->vm_page_prot) &=
+		    ~(par->mmap_map[i].prot_mask);
+		pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
 
 		if (remap_page_range(vma, vma->vm_start + page, map_offset,
 				     map_size, vma->vm_page_prot))
@@ -1412,14 +1417,15 @@
 
 	vma->vm_flags |= VM_IO;
 
-	if (!fb->mmaped) {
+	if (!par->mmaped) {
 		int lastconsole = 0;
 
 		if (info->display_fg)
 			lastconsole = info->display_fg->vc_num;
-		fb->mmaped = 1;
-		if (fb->consolecnt && fb_display[lastconsole].fb_info == info) {
-			fb->vtconsole = lastconsole;
+		par->mmaped = 1;
+		if (par->consolecnt
+		    && fb_display[lastconsole].fb_info == info) {
+			par->vtconsole = lastconsole;
 			vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
 		}
 	}
@@ -1427,15 +1433,14 @@
 }
 
 static struct {
-	u32	yoffset;
-	u8	r[2][256];
-	u8	g[2][256];
-	u8	b[2][256];
+	u32 yoffset;
+	u8 r[2][256];
+	u8 g[2][256];
+	u8 b[2][256];
 } atyfb_save;
 
-static void atyfb_save_palette(struct fb_info *fb, int enter)
+static void atyfb_save_palette(struct fb_info *info, int enter)
 {
-	struct fb_info_aty *info = (struct fb_info_aty *)fb;
 	int i, tmp;
 
 	for (i = 0; i < 256; i++) {
@@ -1445,20 +1450,23 @@
 		aty_st_8(DAC_CNTL, tmp, info);
 		aty_st_8(DAC_MASK, 0xff, info);
 
-		writeb(i, &info->aty_cmap_regs->rindex);
-		atyfb_save.r[enter][i] = readb(&info->aty_cmap_regs->lut);
-		atyfb_save.g[enter][i] = readb(&info->aty_cmap_regs->lut);
-		atyfb_save.b[enter][i] = readb(&info->aty_cmap_regs->lut);
-		writeb(i, &info->aty_cmap_regs->windex);
-		writeb(atyfb_save.r[1-enter][i], &info->aty_cmap_regs->lut);
-		writeb(atyfb_save.g[1-enter][i], &info->aty_cmap_regs->lut);
-		writeb(atyfb_save.b[1-enter][i], &info->aty_cmap_regs->lut);
+		writeb(i, &par->aty_cmap_regs->rindex);
+		atyfb_save.r[enter][i] = readb(&par->aty_cmap_regs->lut);
+		atyfb_save.g[enter][i] = readb(&par->aty_cmap_regs->lut);
+		atyfb_save.b[enter][i] = readb(&par->aty_cmap_regs->lut);
+		writeb(i, &par->aty_cmap_regs->windex);
+		writeb(atyfb_save.r[1 - enter][i],
+		       &par->aty_cmap_regs->lut);
+		writeb(atyfb_save.g[1 - enter][i],
+		       &par->aty_cmap_regs->lut);
+		writeb(atyfb_save.b[1 - enter][i],
+		       &par->aty_cmap_regs->lut);
 	}
 }
 
 static void atyfb_palette(int enter)
 {
-	struct fb_info_aty *info;
+	struct fb_info *info;
 	struct atyfb_par *par;
 	struct display *d;
 	int i;
@@ -1470,8 +1478,8 @@
 		    d->fb_info->display_fg &&
 		    d->fb_info->display_fg->vc_num == i) {
 			atyfb_save_palette(d->fb_info, enter);
-			info = (struct fb_info_aty *)d->fb_info;
-			par = &info->current_par;
+			info = d->fb_info;
+			par = (struct atyfb_par *) info->par;
 			if (enter) {
 				atyfb_save.yoffset = par->crtc.yoffset;
 				par->crtc.yoffset = 0;
@@ -1484,13 +1492,13 @@
 		}
 	}
 }
-#endif /* __sparc__ */
+#endif				/* __sparc__ */
 
 
 
 #ifdef CONFIG_PMAC_PBOOK
 
-static struct fb_info_aty* first_display = NULL;
+static struct fb_info *first_display = NULL;
 
 /* Power management routines. Those are used for PowerBook sleep.
  *
@@ -1498,16 +1506,16 @@
  * management registers. There's is some confusion about which
  * chipID is a Rage LT or LT pro :(
  */
-static int aty_power_mgmt_LT(int sleep, struct fb_info_aty *info)
+static int aty_power_mgmt_LT(int sleep, struct fb_info *info)
 {
- 	unsigned int pm;
+	unsigned int pm;
 	int timeout;
-	
+
 	pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
 	pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
 	aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
 	pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
-	
+
 	timeout = 200000;
 	if (sleep) {
 		/* Sleep */
@@ -1527,14 +1535,15 @@
 			udelay(10);
 			if ((--timeout) == 0)
 				break;
-		} while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
+		} while ((pm & PWR_MGT_STATUS_MASK) !=
+			 PWR_MGT_STATUS_SUSPEND);
 	} else {
 		/* Wakeup */
 		pm &= ~PWR_MGT_ON;
 		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
 		pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
 		udelay(10);
-		pm |=  (PWR_BLON | AUTO_PWR_UP);
+		pm |= (PWR_BLON | AUTO_PWR_UP);
 		pm &= ~SUSPEND_NOW;
 		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
 		pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
@@ -1553,11 +1562,11 @@
 	return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
 }
 
-static int aty_power_mgmt_LTPro(int sleep, struct fb_info_aty *info)
+static int aty_power_mgmt_LTPro(int sleep, struct fb_info *info)
 {
- 	unsigned int pm;
+	unsigned int pm;
 	int timeout;
-	
+
 	pm = aty_ld_lcd(POWER_MANAGEMENT, info);
 	pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
 	aty_st_lcd(POWER_MANAGEMENT, pm, info);
@@ -1582,7 +1591,8 @@
 			mdelay(1);
 			if ((--timeout) == 0)
 				break;
-		} while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
+		} while ((pm & PWR_MGT_STATUS_MASK) !=
+			 PWR_MGT_STATUS_SUSPEND);
 	} else {
 		/* Wakeup */
 		pm &= ~PWR_MGT_ON;
@@ -1597,7 +1607,7 @@
 		pm |= PWR_MGT_ON;
 		aty_st_lcd(POWER_MANAGEMENT, pm, info);
 		do {
-			pm = aty_ld_lcd(POWER_MANAGEMENT, info);			
+			pm = aty_ld_lcd(POWER_MANAGEMENT, info);
 			mdelay(1);
 			if ((--timeout) == 0)
 				break;
@@ -1607,10 +1617,10 @@
 	return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
 }
 
-static int aty_power_mgmt(int sleep, struct fb_info_aty *info)
+static int aty_power_mgmt(int sleep, struct fb_info *info)
 {
-    return M64_HAS(LT_SLEEP) ? aty_power_mgmt_LT(sleep, info)
-			     : aty_power_mgmt_LTPro(sleep, info);
+	return M64_HAS(LT_SLEEP) ? aty_power_mgmt_LT(sleep, info)
+	    : aty_power_mgmt_LTPro(sleep, info);
 }
 
 /*
@@ -1619,8 +1629,9 @@
  */
 static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
-	struct fb_info_aty *info;
- 	int result;
+	struct fb_info *info;
+	struct atyfb_par *par = (struct atyfb_par *) info->fb.par;
+	int result;
 
 	result = PBOOK_SLEEP_OK;
 
@@ -1628,35 +1639,35 @@
 		struct fb_fix_screeninfo fix;
 		int nb;
 
-		atyfb_get_fix(&fix, fg_console, (struct fb_info *)info);
+		atyfb_get_fix(&fix, fg_console, info);
 		nb = fb_display[fg_console].var.yres * fix.line_length;
 
 		switch (when) {
 		case PBOOK_SLEEP_REQUEST:
-			info->save_framebuffer = vmalloc(nb);
-			if (info->save_framebuffer == NULL)
+			par->save_framebuffer = vmalloc(nb);
+			if (par->save_framebuffer == NULL)
 				return PBOOK_SLEEP_REFUSE;
 			break;
 		case PBOOK_SLEEP_REJECT:
-			if (info->save_framebuffer) {
-				vfree(info->save_framebuffer);
-				info->save_framebuffer = 0;
+			if (par->save_framebuffer) {
+				vfree(par->save_framebuffer);
+				par->save_framebuffer = 0;
 			}
 			break;
 		case PBOOK_SLEEP_NOW:
-			if (info->blitter_may_be_busy)
-				wait_for_idle(info);
+			if (par->blitter_may_be_busy)
+				wait_for_idle(par);
 			/* Stop accel engine (stop bus mastering) */
-			if (info->current_par.accel_flags & FB_ACCELF_TEXT)
+			if (par->accel_flags & FB_ACCELF_TEXT)
 				aty_reset_engine(info);
 
-			/* Backup fb content */	
-			if (info->save_framebuffer)
-				memcpy_fromio(info->save_framebuffer,
-				       (void *)info->frame_buffer, nb);
+			/* Backup fb content */
+			if (par->save_framebuffer)
+				memcpy_fromio(par->save_framebuffer,
+					      (void *) info->screen_base, nb);
 
 			/* Blank display and LCD */
-			atyfb_blank(VESA_POWERDOWN+1, (struct fb_info *)info);
+			atyfb_blank(VESA_POWERDOWN + 1, info);
 
 			/* Set chip to "suspend" mode */
 			result = aty_power_mgmt(1, info);
@@ -1665,16 +1676,16 @@
 			/* Wakeup chip */
 			result = aty_power_mgmt(0, info);
 
-			/* Restore fb content */			
-			if (info->save_framebuffer) {
-				memcpy_toio((void *)info->frame_buffer,
-				       info->save_framebuffer, nb);
-				vfree(info->save_framebuffer);
-				info->save_framebuffer = 0;
+			/* Restore fb content */
+			if (par->save_framebuffer) {
+				memcpy_toio((void *) info->screen_base,
+					    par->save_framebuffer, nb);
+				vfree(par->save_framebuffer);
+				par->save_framebuffer = 0;
 			}
 			/* Restore display */
-			atyfb_set_par(&info->current_par, info);
-			atyfb_blank(0, (struct fb_info *)info);
+			atyfb_set_par(par->par, info);
+			atyfb_blank(0, info);
 			break;
 		}
 	}
@@ -1682,9 +1693,9 @@
 }
 
 static struct pmu_sleep_notifier aty_sleep_notifier = {
-        aty_sleep_notify, SLEEP_LEVEL_VIDEO,
+	aty_sleep_notify, SLEEP_LEVEL_VIDEO,
 };
-#endif /* CONFIG_PMAC_PBOOK */
+#endif				/* CONFIG_PMAC_PBOOK */
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 
@@ -1697,12 +1708,11 @@
 	0x9a, 0xa7, 0xb4, 0xc1, 0xcf, 0xdc, 0xe9, 0xff
 };
 
-static int
-aty_set_backlight_enable(int on, int level, void* data)
+static int aty_set_backlight_enable(int on, int level, void *data)
 {
-	struct fb_info_aty *info = (struct fb_info_aty *)data;
+	struct fb_info *info = (struct fb_info *) data;
 	unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, info);
-	
+
 	reg |= (BLMOD_EN | BIASMOD_EN);
 	if (on && level > BACKLIGHT_OFF) {
 		reg &= ~BIAS_MOD_LEVEL_MASK;
@@ -1716,8 +1726,7 @@
 	return 0;
 }
 
-static int
-aty_set_backlight_level(int level, void* data)
+static int aty_set_backlight_level(int level, void *data)
 {
 	return aty_set_backlight_enable(1, level, data);
 }
@@ -1726,7 +1735,7 @@
 	aty_set_backlight_enable,
 	aty_set_backlight_level
 };
-#endif /* CONFIG_PMAC_BACKLIGHT */
+#endif				/* CONFIG_PMAC_BACKLIGHT */
 
 
 
@@ -1734,994 +1743,1072 @@
      *  Initialisation
      */
 
-static struct fb_info_aty *fb_list = NULL;
+static struct fb_info *fb_list = NULL;
 
-static int __init aty_init(struct fb_info_aty *info, const char *name)
+static int __init aty_init(struct fb_info *info, const char *name)
 {
-    u32 chip_id;
-    u32 i;
-    int j, k;
-    struct fb_var_screeninfo var;
-    struct display *disp;
-    u16 type;
-    u8 rev;
-    const char *chipname = NULL, *ramname = NULL, *xtal;
-    int pll, mclk, gtb_memsize;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	const char *chipname = NULL, *ramname = NULL, *xtal;
+	int j, pll, mclk, gtb_memsize;
+	struct fb_var_screeninfo var;
+	struct display *disp;
+	u32 chip_id, i;
+	u16 type;
+	u8 rev;
 #if defined(CONFIG_PPC)
-    int sense;
+	int sense;
 #endif
-    u8 pll_ref_div;
+	u8 pll_ref_div;
 
-    info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0);
-    chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
-    type = chip_id & CFG_CHIP_TYPE;
-    rev = (chip_id & CFG_CHIP_REV)>>24;
-    for (j = 0; j < (sizeof(aty_chips)/sizeof(*aty_chips)); j++)
-	if (type == aty_chips[j].chip_type &&
-	    (rev & aty_chips[j].rev_mask) == aty_chips[j].rev_val) {
-	    chipname = aty_chips[j].name;
-	    pll = aty_chips[j].pll;
-	    mclk = aty_chips[j].mclk;
-	    info->features = aty_chips[j].features;
-	    goto found;
-	}
-    printk("atyfb: Unknown mach64 0x%04x rev 0x%04x\n", type, rev);
-    return 0;
+	par->aty_cmap_regs =
+	    (struct aty_cmap_regs *) (par->ati_regbase + 0xc0);
+	chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
+	type = chip_id & CFG_CHIP_TYPE;
+	rev = (chip_id & CFG_CHIP_REV) >> 24;
+	for (j = 0; j < (sizeof(aty_chips) / sizeof(*aty_chips)); j++)
+		if (type == aty_chips[j].chip_type &&
+		    (rev & aty_chips[j].rev_mask) ==
+		    aty_chips[j].rev_val) {
+			chipname = aty_chips[j].name;
+			pll = aty_chips[j].pll;
+			mclk = aty_chips[j].mclk;
+			par->features = aty_chips[j].features;
+			goto found;
+		}
+	printk("atyfb: Unknown mach64 0x%04x rev 0x%04x\n", type, rev);
+	return 0;
 
-found:
-    printk("atyfb: %s [0x%04x rev 0x%02x] ", chipname, type, rev);
+      found:
+	printk("atyfb: %s [0x%04x rev 0x%02x] ", chipname, type, rev);
 #ifdef CONFIG_FB_ATY_GX
-    if (!M64_HAS(INTEGRATED)) {
-	u32 stat0;
-	u8 dac_type, dac_subtype, clk_type;
-	stat0 = aty_ld_le32(CONFIG_STAT0, info);
-	info->bus_type = (stat0 >> 0) & 0x07;
-	info->ram_type = (stat0 >> 3) & 0x07;
-	ramname = aty_gx_ram[info->ram_type];
-	/* FIXME: clockchip/RAMDAC probing? */
-	dac_type = (aty_ld_le32(DAC_CNTL, info) >> 16) & 0x07;
+	if (!M64_HAS(INTEGRATED)) {
+		u32 stat0;
+		u8 dac_type, dac_subtype, clk_type;
+		stat0 = aty_ld_le32(CONFIG_STAT0, info);
+		par->bus_type = (stat0 >> 0) & 0x07;
+		par->ram_type = (stat0 >> 3) & 0x07;
+		ramname = aty_gx_ram[par->ram_type];
+		/* FIXME: clockchip/RAMDAC probing? */
+		dac_type = (aty_ld_le32(DAC_CNTL, par) >> 16) & 0x07;
 #ifdef CONFIG_ATARI
-	clk_type = CLK_ATI18818_1;
-	dac_type = (stat0 >> 9) & 0x07;
-	if (dac_type == 0x07)
-	    dac_subtype = DAC_ATT20C408;
-	else
-	    dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, info) & 0xF0) | dac_type;
+		clk_type = CLK_ATI18818_1;
+		dac_type = (stat0 >> 9) & 0x07;
+		if (dac_type == 0x07)
+			dac_subtype = DAC_ATT20C408;
+		else
+			dac_subtype =
+			    (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) |
+			    dac_type;
 #else
-	dac_type = DAC_IBMRGB514;
-	dac_subtype = DAC_IBMRGB514;
-	clk_type = CLK_IBMRGB514;
-#endif
-	switch (dac_subtype) {
-	    case DAC_IBMRGB514:
-		info->dac_ops = &aty_dac_ibm514;
-		break;
-	    case DAC_ATI68860_B:
-	    case DAC_ATI68860_C:
-		info->dac_ops = &aty_dac_ati68860b;
-		break;
-	    case DAC_ATT20C408:
-	    case DAC_ATT21C498:
-		info->dac_ops = &aty_dac_att21c498;
-		break;
-	    default:
-		printk(" atyfb_set_par: DAC type not implemented yet!\n");
-		info->dac_ops = &aty_dac_unsupported;
-		break;
-	}
-	switch (clk_type) {
-	    case CLK_ATI18818_1:
-		info->pll_ops = &aty_pll_ati18818_1;
-		break;
-	    case CLK_STG1703:
-		info->pll_ops = &aty_pll_stg1703;
-		break;
-	    case CLK_CH8398:
-		info->pll_ops = &aty_pll_ch8398;
-		break;
-	    case CLK_ATT20C408:
-		info->pll_ops = &aty_pll_att20c408;
-		break;
-	    case CLK_IBMRGB514:
-		info->pll_ops = &aty_pll_ibm514;
-		break;
-	    default:
-		printk(" atyfb_set_par: CLK type not implemented yet!");
-		info->pll_ops = &aty_pll_unsupported;
-		break;
+		dac_type = DAC_IBMRGB514;
+		dac_subtype = DAC_IBMRGB514;
+		clk_type = CLK_IBMRGB514;
+#endif
+		switch (dac_subtype) {
+		case DAC_IBMRGB514:
+			par->dac_ops = &aty_dac_ibm514;
+			break;
+		case DAC_ATI68860_B:
+		case DAC_ATI68860_C:
+			par->dac_ops = &aty_dac_ati68860b;
+			break;
+		case DAC_ATT20C408:
+		case DAC_ATT21C498:
+			par->dac_ops = &aty_dac_att21c498;
+			break;
+		default:
+			printk
+			    (" atyfb_set_par: DAC type not implemented yet!\n");
+			par->dac_ops = &aty_dac_unsupported;
+			break;
+		}
+		switch (clk_type) {
+		case CLK_ATI18818_1:
+			par->pll_ops = &aty_pll_ati18818_1;
+			break;
+		case CLK_STG1703:
+			par->pll_ops = &aty_pll_stg1703;
+			break;
+		case CLK_CH8398:
+			par->pll_ops = &aty_pll_ch8398;
+			break;
+		case CLK_ATT20C408:
+			par->pll_ops = &aty_pll_att20c408;
+			break;
+		case CLK_IBMRGB514:
+			par->pll_ops = &aty_pll_ibm514;
+			break;
+		default:
+			printk
+			    (" atyfb_set_par: CLK type not implemented yet!");
+			par->pll_ops = &aty_pll_unsupported;
+			break;
+		}
 	}
-    }
-#endif /* CONFIG_FB_ATY_GX */
+#endif				/* CONFIG_FB_ATY_GX */
 #ifdef CONFIG_FB_ATY_CT
-    if (M64_HAS(INTEGRATED)) {
-	info->bus_type = PCI;
-	info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) & 0x07);
-	ramname = aty_ct_ram[info->ram_type];
-	info->dac_ops = &aty_dac_ct;
-	info->pll_ops = &aty_pll_ct;
-	/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
-	if (mclk == 67 && info->ram_type < SDRAM)
-	    mclk = 63;
-    }
-#endif /* CONFIG_FB_ATY_CT */
-
-    info->ref_clk_per = 1000000000000ULL/14318180;
-    xtal = "14.31818";
-    if (M64_HAS(GTB_DSP) && (pll_ref_div = aty_ld_pll(PLL_REF_DIV, info))) {
-	int diff1, diff2;
-	diff1 = 510*14/pll_ref_div-pll;
-	diff2 = 510*29/pll_ref_div-pll;
-	if (diff1 < 0)
-	    diff1 = -diff1;
-	if (diff2 < 0)
-	    diff2 = -diff2;
-	if (diff2 < diff1) {
-	    info->ref_clk_per = 1000000000000ULL/29498928;
-	    xtal = "29.498928";
+	if (M64_HAS(INTEGRATED)) {
+		par->bus_type = PCI;
+		par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
+		ramname = aty_ct_ram[par->ram_type];
+		par->dac_ops = &aty_dac_ct;
+		par->pll_ops = &aty_pll_ct;
+		/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
+		if (mclk == 67 && par->ram_type < SDRAM)
+			mclk = 63;
+	}
+#endif				/* CONFIG_FB_ATY_CT */
+
+	par->ref_clk_per = 1000000000000ULL / 14318180;
+	xtal = "14.31818";
+	if (M64_HAS(GTB_DSP)
+	    && (pll_ref_div = aty_ld_pll(PLL_REF_DIV, par))) {
+		int diff1, diff2;
+		diff1 = 510 * 14 / pll_ref_div - pll;
+		diff2 = 510 * 29 / pll_ref_div - pll;
+		if (diff1 < 0)
+			diff1 = -diff1;
+		if (diff2 < 0)
+			diff2 = -diff2;
+		if (diff2 < diff1) {
+			par->ref_clk_per = 1000000000000ULL / 29498928;
+			xtal = "29.498928";
+		}
 	}
-    }
 
-    i = aty_ld_le32(MEM_CNTL, info);
-    gtb_memsize = M64_HAS(GTB_DSP);
-    if (gtb_memsize)
-	switch (i & 0xF) {	/* 0xF used instead of MEM_SIZE_ALIAS */
-	    case MEM_SIZE_512K:
-		info->total_vram = 0x80000;
-		break;
-	    case MEM_SIZE_1M:
-		info->total_vram = 0x100000;
-		break;
-	    case MEM_SIZE_2M_GTB:
-		info->total_vram = 0x200000;
-		break;
-	    case MEM_SIZE_4M_GTB:
-		info->total_vram = 0x400000;
-		break;
-	    case MEM_SIZE_6M_GTB:
-		info->total_vram = 0x600000;
-		break;
-	    case MEM_SIZE_8M_GTB:
-		info->total_vram = 0x800000;
-		break;
-	    default:
-		info->total_vram = 0x80000;
-	}
-    else
-	switch (i & MEM_SIZE_ALIAS) {
-	    case MEM_SIZE_512K:
-		info->total_vram = 0x80000;
-		break;
-	    case MEM_SIZE_1M:
-		info->total_vram = 0x100000;
-		break;
-	    case MEM_SIZE_2M:
-		info->total_vram = 0x200000;
-		break;
-	    case MEM_SIZE_4M:
-		info->total_vram = 0x400000;
-		break;
-	    case MEM_SIZE_6M:
-		info->total_vram = 0x600000;
-		break;
-	    case MEM_SIZE_8M:
-		info->total_vram = 0x800000;
-		break;
-	    default:
-		info->total_vram = 0x80000;
-	}
+	i = aty_ld_le32(MEM_CNTL, par);
+	gtb_memsize = M64_HAS(GTB_DSP);
+	if (gtb_memsize)
+		switch (i & 0xF) {	/* 0xF used instead of MEM_SIZE_ALIAS */
+		case MEM_SIZE_512K:
+			info->fix.smem_len = 0x80000;
+			break;
+		case MEM_SIZE_1M:
+			info->fix.smem_len = 0x100000;
+			break;
+		case MEM_SIZE_2M_GTB:
+			info->fix.smem_len = 0x200000;
+			break;
+		case MEM_SIZE_4M_GTB:
+			info->fix.smem_len = 0x400000;
+			break;
+		case MEM_SIZE_6M_GTB:
+			info->fix.smem_len = 0x600000;
+			break;
+		case MEM_SIZE_8M_GTB:
+			info->fix.smem_len = 0x800000;
+			break;
+		default:
+			info->fix.smem_len = 0x80000;
+	} else
+		switch (i & MEM_SIZE_ALIAS) {
+		case MEM_SIZE_512K:
+			info->fix.smem_len = 0x80000;
+			break;
+		case MEM_SIZE_1M:
+			info->fix.smem_len = 0x100000;
+			break;
+		case MEM_SIZE_2M:
+			info->fix.smem_len = 0x200000;
+			break;
+		case MEM_SIZE_4M:
+			info->fix.smem_len = 0x400000;
+			break;
+		case MEM_SIZE_6M:
+			info->fix.smem_len = 0x600000;
+			break;
+		case MEM_SIZE_8M:
+			info->fix.smem_len = 0x800000;
+			break;
+		default:
+			info->fix.smem_len = 0x80000;
+		}
 
-    if (M64_HAS(MAGIC_VRAM_SIZE)) {
-	if (aty_ld_le32(CONFIG_STAT1, info) & 0x40000000)
-	  info->total_vram += 0x400000;
-    }
+	if (M64_HAS(MAGIC_VRAM_SIZE)) {
+		if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000)
+			info->fix.smem_len += 0x400000;
+	}
+
+	if (default_vram) {
+		info->fix.smem_len = default_vram * 1024;
+		i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
+		if (info->fix.smem_len <= 0x80000)
+			i |= MEM_SIZE_512K;
+		else if (info->fix.smem_len <= 0x100000)
+			i |= MEM_SIZE_1M;
+		else if (info->fix.smem_len <= 0x200000)
+			i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
+		else if (info->fix.smem_len <= 0x400000)
+			i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
+		else if (info->fix.smem_len <= 0x600000)
+			i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
+		else
+			i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
+		aty_st_le32(MEM_CNTL, i, par);
+	}
 
-    if (default_vram) {
-	info->total_vram = default_vram*1024;
-	i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
-	if (info->total_vram <= 0x80000)
-	    i |= MEM_SIZE_512K;
-	else if (info->total_vram <= 0x100000)
-	    i |= MEM_SIZE_1M;
-	else if (info->total_vram <= 0x200000)
-	    i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
-	else if (info->total_vram <= 0x400000)
-	    i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
-	else if (info->total_vram <= 0x600000)
-	    i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
+	/*
+	 *  Reg Block 0 (CT-compatible block) is at mmio_start 
+	 *  Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
+	 */
+	if (M64_HAS(GX)) {
+		info->fix.mmio_len = 0x400;
+		info->fix.accel = FB_ACCEL_ATI_MACH64GX;
+	} else if (M64_HAS(CT)) {
+		info->fix.mmio_len = 0x400;
+		info->fix.accel = FB_ACCEL_ATI_MACH64CT;
+	} else if (M64_HAS(VT)) {
+		info->fix.mmio_start = -0x400;
+		info->fix.mmio_len = 0x800;
+		info->fix.accel = FB_ACCEL_ATI_MACH64VT;
+	} else {		/* if (M64_HAS(GT)) */
+
+		info->fix.mmio_start = -0x400;
+		info->fix.mmio_len = 0x800;
+		info->fix.accel = FB_ACCEL_ATI_MACH64GT;
+	}
+
+	if (default_pll)
+		pll = default_pll;
+	if (default_mclk)
+		mclk = default_mclk;
+
+	printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
+	       info->fix.smem_len ==
+	       0x80000 ? 512 : (info->fix.smem_len >> 20),
+	       info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname,
+	       xtal, pll, mclk);
+
+	if (mclk < 44)
+		par->mem_refresh_rate = 0;	/* 000 = 10 Mhz - 43 Mhz */
+	else if (mclk < 50)
+		par->mem_refresh_rate = 1;	/* 001 = 44 Mhz - 49 Mhz */
+	else if (mclk < 55)
+		par->mem_refresh_rate = 2;	/* 010 = 50 Mhz - 54 Mhz */
+	else if (mclk < 66)
+		par->mem_refresh_rate = 3;	/* 011 = 55 Mhz - 65 Mhz */
+	else if (mclk < 75)
+		par->mem_refresh_rate = 4;	/* 100 = 66 Mhz - 74 Mhz */
+	else if (mclk < 80)
+		par->mem_refresh_rate = 5;	/* 101 = 75 Mhz - 79 Mhz */
+	else if (mclk < 100)
+		par->mem_refresh_rate = 6;	/* 110 = 80 Mhz - 100 Mhz */
 	else
-	    i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
-	aty_st_le32(MEM_CNTL, i, info);
-    }
-    if (default_pll)
-	pll = default_pll;
-    if (default_mclk)
-	mclk = default_mclk;
-
-    printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
-    	   info->total_vram == 0x80000 ? 512 : (info->total_vram >> 20),
-    	   info->total_vram == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk);
-
-    if (mclk < 44)
-	info->mem_refresh_rate = 0;	/* 000 = 10 Mhz - 43 Mhz */
-    else if (mclk < 50)
-	info->mem_refresh_rate = 1;	/* 001 = 44 Mhz - 49 Mhz */
-    else if (mclk < 55)
-	info->mem_refresh_rate = 2;	/* 010 = 50 Mhz - 54 Mhz */
-    else if (mclk < 66)
-	info->mem_refresh_rate = 3;	/* 011 = 55 Mhz - 65 Mhz */
-    else if (mclk < 75)
-	info->mem_refresh_rate = 4;	/* 100 = 66 Mhz - 74 Mhz */
-    else if (mclk < 80)
-	info->mem_refresh_rate = 5;	/* 101 = 75 Mhz - 79 Mhz */
-    else if (mclk < 100)
-	info->mem_refresh_rate = 6;	/* 110 = 80 Mhz - 100 Mhz */
-    else
-	info->mem_refresh_rate = 7;	/* 111 = 100 Mhz and above */
-    info->pll_per = 1000000/pll;
-    info->mclk_per = 1000000/mclk;
+		par->mem_refresh_rate = 7;	/* 111 = 100 Mhz and above */
+	par->pll_per = 1000000 / pll;
+	par->mclk_per = 1000000 / mclk;
 
 #ifdef DEBUG
-    if (M64_HAS(INTEGRATED)) {
-	int i;
-	printk("BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
-	       "DSP_CONFIG DSP_ON_OFF\n"
-	       "%08x %08x %08x %08x     %08x      %08x   %08x\n"
-	       "PLL",
-	       aty_ld_le32(BUS_CNTL, info), aty_ld_le32(DAC_CNTL, info),
-	       aty_ld_le32(MEM_CNTL, info), aty_ld_le32(EXT_MEM_CNTL, info),
-	       aty_ld_le32(CRTC_GEN_CNTL, info), aty_ld_le32(DSP_CONFIG, info),
-	       aty_ld_le32(DSP_ON_OFF, info));
-	for (i = 0; i < 16; i++)
-	    printk(" %02x", aty_ld_pll(i, info));
-	printk("\n");
-    }
+	if (M64_HAS(INTEGRATED)) {
+		int i;
+		printk
+		    ("BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
+		     "DSP_CONFIG DSP_ON_OFF\n"
+		     "%08x %08x %08x %08x     %08x      %08x   %08x\n"
+		     "PLL", aty_ld_le32(BUS_CNTL, par),
+		     aty_ld_le32(DAC_CNTL, par), aty_ld_le32(MEM_CNTL,
+							     par),
+		     aty_ld_le32(EXT_MEM_CNTL, par),
+		     aty_ld_le32(CRTC_GEN_CNTL, par),
+		     aty_ld_le32(DSP_CONFIG, par), aty_ld_le32(DSP_ON_OFF,
+							       par));
+		for (i = 0; i < 16; i++)
+			printk(" %02x", aty_ld_pll(i, par));
+		printk("\n");
+	}
 #endif
 
-    /*
-     *  Last page of 8 MB (4 MB on ISA) aperture is MMIO
-     *  FIXME: we should use the auxiliary aperture instead so we can access
-     *  the full 8 MB of video RAM on 8 MB boards
-     */
-    if (info->total_vram == 0x800000 ||
-	(info->bus_type == ISA && info->total_vram == 0x400000))
-	    info->total_vram -= GUI_RESERVE;
-
-    /* Clear the video memory */
-    fb_memset((void *)info->frame_buffer, 0, info->total_vram);
-
-    disp = &info->disp;
-
-    strcpy(info->fb_info.modename, atyfb_name);
-    info->fb_info.node = NODEV;
-    info->fb_info.fbops = &atyfb_ops;
-    info->fb_info.disp = disp;
-    info->fb_info.currcon = -1;  	
-    strcpy(info->fb_info.fontname, fontname);
-    info->fb_info.changevar = NULL;
-    info->fb_info.switch_con = &atyfbcon_switch;
-    info->fb_info.updatevar = &atyfbcon_updatevar;
-    info->fb_info.flags = FBINFO_FLAG_DEFAULT;
+	/*
+	 *  Last page of 8 MB (4 MB on ISA) aperture is MMIO
+	 *  FIXME: we should use the auxiliary aperture instead so we can access
+	 *  the full 8 MB of video RAM on 8 MB boards
+	 */
+	if (info->fix.smem_len == 0x800000 ||
+	    (par->bus_type == ISA 
+	     && info->fix.smem_len == 0x400000))
+		info->fix.smem_len -= GUI_RESERVE;
+
+	/* Clear the video memory */
+	fb_memset((void *) info->screen_base, 0,
+		  info->fix.smem_len);
+
+	disp = info->disp;
+
+	strcpy(info->modename, atyfb_name);
+	info->node = NODEV;
+	info->fbops = &atyfb_ops;
+	info->disp = disp;
+	info->pseudo_palette = pseudo_palette;
+	info->currcon = -1;
+	strcpy(info->fontname, fontname);
+	info->changevar = NULL;
+	info->switch_con = gen_switch;
+	info->updatevar = &atyfbcon_updatevar;
+	info->flags = FBINFO_FLAG_DEFAULT;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-    if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
-	/* these bits let the 101 powerbook wake up from sleep -- paulus */
-	aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, info)
-		| (USE_F32KHZ | TRISTATE_MEM_EN), info);
-    }
-    if (M64_HAS(MOBIL_BUS))
-	register_backlight_controller(&aty_backlight_controller, info, "ati");
-#endif /* CONFIG_PMAC_BACKLIGHT */
+	if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
+		/* these bits let the 101 powerbook wake up from sleep -- paulus */
+		aty_st_lcd(POWER_MANAGEMENT,
+			   aty_ld_lcd(POWER_MANAGEMENT, par)
+			   | (USE_F32KHZ | TRISTATE_MEM_EN), par);
+	}
+	if (M64_HAS(MOBIL_BUS))
+		register_backlight_controller(&aty_backlight_controller,
+					      info, "ati");
+#endif				/* CONFIG_PMAC_BACKLIGHT */
 
 #ifdef MODULE
-    var = default_var;
-#else /* !MODULE */
-    memset(&var, 0, sizeof(var));
+	var = default_var;
+#else				/* !MODULE */
+	memset(&var, 0, sizeof(var));
 #ifdef CONFIG_PPC
-    if (_machine == _MACH_Pmac) {
-	    /*
-	     *  FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
-	     *         applies to all Mac video cards
-	     */
-	    if (mode_option) {
-		if (!mac_find_mode(&var, &info->fb_info, mode_option, 8))
-		    var = default_var;
-	    } else {
+	if (_machine == _MACH_Pmac) {
+		/*
+		 *  FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
+		 *         applies to all Mac video cards
+		 */
+		if (mode_option) {
+			if (!mac_find_mode
+			    (&var, info, mode_option, 8))
+				var = default_var;
+		} else {
 #ifdef CONFIG_NVRAM
-		if (default_vmode == VMODE_NVRAM) {
-		    default_vmode = nvram_read_byte(NV_VMODE);
-		    if (default_vmode <= 0 || default_vmode > VMODE_MAX)
-			default_vmode = VMODE_CHOOSE;
-		}
-#endif
-		if (default_vmode == VMODE_CHOOSE) {
-		    if (M64_HAS(G3_PB_1024x768))
-			/* G3 PowerBook with 1024x768 LCD */
-			default_vmode = VMODE_1024_768_60;
-		    else if (machine_is_compatible("iMac"))
-			default_vmode = VMODE_1024_768_75;
-		    else if (machine_is_compatible("PowerBook2,1"))
-			/* iBook with 800x600 LCD */
-			default_vmode = VMODE_800_600_60;
-		    else
-			default_vmode = VMODE_640_480_67;
-		    sense = read_aty_sense(info);
-		    printk(KERN_INFO "atyfb: monitor sense=%x, mode %d\n",
-			   sense, mac_map_monitor_sense(sense));
-		}
-		if (default_vmode <= 0 || default_vmode > VMODE_MAX)
-		    default_vmode = VMODE_640_480_60;
+			if (default_vmode == VMODE_NVRAM) {
+				default_vmode = nvram_read_byte(NV_VMODE);
+				if (default_vmode <= 0
+				    || default_vmode > VMODE_MAX)
+					default_vmode = VMODE_CHOOSE;
+			}
+#endif
+			if (default_vmode == VMODE_CHOOSE) {
+				if (M64_HAS(G3_PB_1024x768))
+					/* G3 PowerBook with 1024x768 LCD */
+					default_vmode = VMODE_1024_768_60;
+				else if (machine_is_compatible("iMac"))
+					default_vmode = VMODE_1024_768_75;
+				else if (machine_is_compatible
+					 ("PowerBook2,1"))
+					/* iBook with 800x600 LCD */
+					default_vmode = VMODE_800_600_60;
+				else
+					default_vmode = VMODE_640_480_67;
+				sense = read_aty_sense(info);
+				printk(KERN_INFO
+				       "atyfb: monitor sense=%x, mode %d\n",
+				       sense,
+				       mac_map_monitor_sense(sense));
+			}
+			if (default_vmode <= 0
+			    || default_vmode > VMODE_MAX)
+				default_vmode = VMODE_640_480_60;
 #ifdef CONFIG_NVRAM
-		if (default_cmode == CMODE_NVRAM)
-		    default_cmode = nvram_read_byte(NV_CMODE);
+			if (default_cmode == CMODE_NVRAM)
+				default_cmode = nvram_read_byte(NV_CMODE);
 #endif
-		if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
-		    default_cmode = CMODE_8;
-		if (mac_vmode_to_var(default_vmode, default_cmode, &var))
-		    var = default_var;
-	    }
-    }
-    else if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
-	var = default_var;
-#else /* !CONFIG_PPC */
+			if (default_cmode < CMODE_8
+			    || default_cmode > CMODE_32)
+				default_cmode = CMODE_8;
+			if (mac_vmode_to_var
+			    (default_vmode, default_cmode, &var))
+				var = default_var;
+		}
+	} else
+	    if (!fb_find_mode
+		(&var, info, mode_option, NULL, 0, NULL, 8))
+		var = default_var;
+#else				/* !CONFIG_PPC */
 #ifdef __sparc__
-    if (mode_option) {
-    	if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
-	    var = default_var;
-    } else
-	var = default_var;
+	if (mode_option) {
+		if (!fb_find_mode
+		    (&var, info, mode_option, NULL, 0, NULL, 8))
+			var = default_var;
+	} else
+		var = default_var;
 #else
-    if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
-	var = default_var;
-#endif /* !__sparc__ */
-#endif /* !CONFIG_PPC */
-#endif /* !MODULE */
-    if (noaccel)
-        var.accel_flags &= ~FB_ACCELF_TEXT;
-    else
-        var.accel_flags |= FB_ACCELF_TEXT;
-
-    if (var.yres == var.yres_virtual) {
-	u32 vram = (info->total_vram - (PAGE_SIZE << 2));
-	var.yres_virtual = ((vram * 8) / var.bits_per_pixel) / var.xres_virtual;
-	if (var.yres_virtual < var.yres)
-		var.yres_virtual = var.yres;
-    }
+	if (!fb_find_mode
+	    (&var, info, mode_option, NULL, 0, NULL, 8))
+		var = default_var;
+#endif				/* !__sparc__ */
+#endif				/* !CONFIG_PPC */
+#endif				/* !MODULE */
+	if (noaccel)
+		var.accel_flags &= ~FB_ACCELF_TEXT;
+	else
+		var.accel_flags |= FB_ACCELF_TEXT;
 
-    if (atyfb_decode_var(&var, &info->default_par, info)) {
-	printk("atyfb: can't set default video mode\n");
-	return 0;
-    }
+	if (var.yres == var.yres_virtual) {
+		u32 vram = (info->fix.smem_len - (PAGE_SIZE << 2));
+		var.yres_virtual =
+		    ((vram * 8) / var.bits_per_pixel) / var.xres_virtual;
+		if (var.yres_virtual < var.yres)
+			var.yres_virtual = var.yres;
+	}
 
+	if (atyfb_decode_var(&var, par, info)) {
+		printk("atyfb: can't set default video mode\n");
+		return 0;
+	}
 #ifdef __sparc__
-    atyfb_save_palette(&info->fb_info, 0);
+	atyfb_save_palette(info, 0);
 #endif
-    for (j = 0; j < 16; j++) {
-	k = color_table[j];
-	info->palette[j].red = default_red[k];
-	info->palette[j].green = default_grn[k];
-	info->palette[j].blue = default_blu[k];
-    }
 
 #ifdef CONFIG_FB_ATY_CT
-    if (curblink && M64_HAS(INTEGRATED)) {
-	info->cursor = aty_init_cursor(info);
-	if (info->cursor) {
-	    info->dispsw.cursor = atyfb_cursor;
-	    info->dispsw.set_font = atyfb_set_font;
+	if (curblink && M64_HAS(INTEGRATED)) {
+		par->cursor = aty_init_cursor(info);
+		if (par->cursor) {
+			/*
+			disp->dispsw.cursor = atyfb_cursor;
+			disp->dispsw.set_font = atyfb_set_font;
+			*/
+		}
 	}
-    }
-#endif /* CONFIG_FB_ATY_CT */
+#endif				/* CONFIG_FB_ATY_CT */
+	info->var = var;
 
-    atyfb_set_var(&var, -1, &info->fb_info);
+	fb_alloc_cmap(&info->cmap, 256, 0);
 
-    if (register_framebuffer(&info->fb_info) < 0)
-	return 0;
+	atyfb_set_var(&var, -1, info);
+
+	if (register_framebuffer(info) < 0)
+		return 0;
 
-    info->next = fb_list;
-    fb_list = info;
+	fb_list = info;
 
-    printk("fb%d: %s frame buffer device on %s\n",
-	   GET_FB_IDX(info->fb_info.node), atyfb_name, name);
-    return 1;
+	printk("fb%d: %s frame buffer device on %s\n",
+	       GET_FB_IDX(info->node), atyfb_name, name);
+	return 1;
 }
 
 int __init atyfb_init(void)
 {
 #if defined(CONFIG_PCI)
-    struct pci_dev *pdev = NULL;
-    struct fb_info_aty *info;
-    unsigned long addr, res_start, res_size;
-    int i;
+	struct pci_dev *pdev = NULL;
+	struct fb_info *info;
+	unsigned long addr, res_start, res_size;
+	int i;
 #ifdef __sparc__
-    extern void (*prom_palette) (int);
-    extern int con_is_present(void);
-    struct pcidev_cookie *pcp;
-    char prop[128];
-    int node, len, j;
-    u32 mem, chip_id;
-
-    /* Do not attach when we have a serial console. */
-    if (!con_is_present())
-	return -ENXIO;
-#else
-    u16 tmp;
-#endif
+	extern void (*prom_palette) (int);
+	extern int con_is_present(void);
+	struct pcidev_cookie *pcp;
+	char prop[128];
+	int node, len, j;
+	u32 mem, chip_id;
 
-    while ((pdev = pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, pdev))) {
-	if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
-	    struct resource *rp;
-
-	    for (i = sizeof(aty_chips)/sizeof(*aty_chips)-1; i >= 0; i--)
-		if (pdev->device == aty_chips[i].pci_id)
-		    break;
-	    if (i < 0)
-		continue;
-
-	    info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
-	    if (!info) {
-		printk("atyfb_init: can't alloc fb_info_aty\n");
+	/* Do not attach when we have a serial console. */
+	if (!con_is_present())
 		return -ENXIO;
-	    }
-	    memset(info, 0, sizeof(struct fb_info_aty));
-
-	    rp = &pdev->resource[0];
-	    if (rp->flags & IORESOURCE_IO)
-		    rp = &pdev->resource[1];
-	    addr = rp->start;
-	    if (!addr)
-		continue;
-
-	    res_start = rp->start;
-	    res_size = rp->end-rp->start+1;
-	    if (!request_mem_region(res_start, res_size, "atyfb"))
-		continue;
-
-#ifdef __sparc__
-	    /*
-	     * Map memory-mapped registers.
-	     */
-	    info->ati_regbase = addr + 0x7ffc00UL;
-	    info->ati_regbase_phys = addr + 0x7ffc00UL;
-
-	    /*
-	     * Map in big-endian aperture.
-	     */
-	    info->frame_buffer = (unsigned long) addr + 0x800000UL;
-	    info->frame_buffer_phys = addr + 0x800000UL;
-
-	    /*
-	     * Figure mmap addresses from PCI config space.
-	     * Split Framebuffer in big- and little-endian halfs.
-	     */
-	    for (i = 0; i < 6 && pdev->resource[i].start; i++)
-		/* nothing */;
-	    j = i + 4;
-
-	    info->mmap_map = kmalloc(j * sizeof(*info->mmap_map), GFP_ATOMIC);
-	    if (!info->mmap_map) {
-		printk("atyfb_init: can't alloc mmap_map\n");
-		kfree(info);
-		release_mem_region(res_start, res_size);
-		return -ENXIO;
-	    }
-	    memset(info->mmap_map, 0, j * sizeof(*info->mmap_map));
-
-	    for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
-		struct resource *rp = &pdev->resource[i];
-		int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
-		unsigned long base;
-		u32 size, pbase;
+#else
+	u16 tmp;
+#endif
+	struct atyfb_par *default_par;
 
-		base = rp->start;
+	while ((pdev =
+		pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, pdev))) {
+		if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+			struct resource *rp;
+
+			for (i =
+			     sizeof(aty_chips) / sizeof(*aty_chips) - 1;
+			     i >= 0; i--)
+				if (pdev->device == aty_chips[i].pci_id)
+					break;
+			if (i < 0)
+				continue;
 
-		io = (rp->flags & IORESOURCE_IO);
+			info =
+			    kmalloc(sizeof(struct fb_info) +
+				    sizeof(struct display), GFP_ATOMIC);
+			if (!info) {
+				printk
+				    ("atyfb_init: can't alloc fb_info\n");
+				return -ENXIO;
+			}
+			memset(info, 0,
+			       sizeof(struct fb_info) +
+			       sizeof(struct display));
+
+			default_par =
+			    kmalloc(sizeof(struct atyfb_par), GFP_ATOMIC);
+			if (!default_par) {
+				printk
+				    ("atyfb_init: can't alloc atyfb_par\n");
+				kfree(info);
+				return -ENXIO;
+			}
+			memset(default_par, 0, sizeof(struct atyfb_par));
 
-		size = rp->end - base + 1;
+			info->disp = (struct display *) (info + 1);
+			info->par = default_par;
 
-		pci_read_config_dword(pdev, breg, &pbase);
+			rp = &pdev->resource[0];
+			if (rp->flags & IORESOURCE_IO)
+				rp = &pdev->resource[1];
+			addr = rp->start;
+			if (!addr)
+				continue;
 
-		if (io)
-			size &= ~1;
+			res_start = rp->start;
+			res_size = rp->end - rp->start + 1;
+			if (!request_mem_region
+			    (res_start, res_size, "atyfb"))
+				continue;
 
-		/*
-		 * Map the framebuffer a second time, this time without
-		 * the braindead _PAGE_IE setting. This is used by the
-		 * fixed Xserver, but we need to maintain the old mapping
-		 * to stay compatible with older ones...
-		 */
-		if (base == addr) {
-		    info->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
-		    info->mmap_map[j].poff = base & PAGE_MASK;
-		    info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
-		    info->mmap_map[j].prot_mask = _PAGE_CACHE;
-		    info->mmap_map[j].prot_flag = _PAGE_E;
-		    j++;
-		}
+#ifdef __sparc__
+			/*
+			 * Map memory-mapped registers.
+			 */
+			par->ati_regbase = addr + 0x7ffc00UL;
+			info->fix.mmio_start = addr + 0x7ffc00UL;
 
-		/*
-		 * Here comes the old framebuffer mapping with _PAGE_IE
-		 * set for the big endian half of the framebuffer...
-		 */
-		if (base == addr) {
-		    info->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
-		    info->mmap_map[j].poff = (base+0x800000) & PAGE_MASK;
-		    info->mmap_map[j].size = 0x800000;
-		    info->mmap_map[j].prot_mask = _PAGE_CACHE;
-		    info->mmap_map[j].prot_flag = _PAGE_E|_PAGE_IE;
-		    size -= 0x800000;
-		    j++;
-		}
-
-		info->mmap_map[j].voff = pbase & PAGE_MASK;
-		info->mmap_map[j].poff = base & PAGE_MASK;
-		info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
-		info->mmap_map[j].prot_mask = _PAGE_CACHE;
-		info->mmap_map[j].prot_flag = _PAGE_E;
-		j++;
-	    }
-
-	    if (pdev->device != XL_CHIP_ID) {
-		    /*
-		     * Fix PROMs idea of MEM_CNTL settings...
-		     */
-		    mem = aty_ld_le32(MEM_CNTL, info);
-		    chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
-		    if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) &&
-			!((chip_id >> 24) & 1)) {
-			switch (mem & 0x0f) {
-			    case 3:
-				mem = (mem & ~(0x0f)) | 2;
-				break;
-			    case 7:
-				mem = (mem & ~(0x0f)) | 3;
-				break;
-			    case 9:
-				mem = (mem & ~(0x0f)) | 4;
-				break;
-			    case 11:
-				mem = (mem & ~(0x0f)) | 5;
-				break;
-			    default:
-				break;
+			/*
+			 * Map in big-endian aperture.
+			 */
+			info->screen_base =
+			    (unsigned long) addr + 0x800000UL;
+			info->fix.smem_start = addr + 0x800000UL;
+
+			/*
+			 * Figure mmap addresses from PCI config space.
+			 * Split Framebuffer in big- and little-endian halfs.
+			 */
+			for (i = 0; i < 6 && pdev->resource[i].start; i++)
+				/* nothing */ ;
+			j = i + 4;
+
+			default_par->mmap_map =
+			    kmalloc(j * sizeof(*default_par->mmap_map),
+				    GFP_ATOMIC);
+			if (!default_par->mmap_map) {
+				printk
+				    ("atyfb_init: can't alloc mmap_map\n");
+				kfree(info);
+				release_mem_region(res_start, res_size);
+				return -ENXIO;
 			}
-			if ((aty_ld_le32(CONFIG_STAT0, info) & 7) >= SDRAM)
-				mem &= ~(0x00700000);
-		    }
-		    mem &= ~(0xcf80e000);	/* Turn off all undocumented bits. */
-		    aty_st_le32(MEM_CNTL, mem, info);
-	    }
-
-	    /*
-	     * If this is the console device, we will set default video
-	     * settings to what the PROM left us with.
-	     */
-	    node = prom_getchild(prom_root_node);
-	    node = prom_searchsiblings(node, "aliases");
-	    if (node) {
-		len = prom_getproperty(node, "screen", prop, sizeof(prop));
-		if (len > 0) {
-		    prop[len] = '\0';
-		    node = prom_finddevice(prop);
-		} else {
-		    node = 0;
-		}
-	    }
+			memset(default_par->mmap_map, 0,
+			       j * sizeof(*default_par->mmap_map));
 
-	    pcp = pdev->sysdata;
-	    if (node == pcp->prom_node) {
+			for (i = 0, j = 2;
+			     i < 6 && pdev->resource[i].start; i++) {
+				struct resource *rp = &pdev->resource[i];
+				int io, breg =
+				    PCI_BASE_ADDRESS_0 + (i << 2);
+				unsigned long base;
+				u32 size, pbase;
+
+				base = rp->start;
+
+				io = (rp->flags & IORESOURCE_IO);
+
+				size = rp->end - base + 1;
+
+				pci_read_config_dword(pdev, breg, &pbase);
+
+				if (io)
+					size &= ~1;
+
+				/*
+				 * Map the framebuffer a second time, this time without
+				 * the braindead _PAGE_IE setting. This is used by the
+				 * fixed Xserver, but we need to maintain the old mapping
+				 * to stay compatible with older ones...
+				 */
+				if (base == addr) {
+					default_par->mmap_map[j].voff =
+					    (pbase +
+					     0x10000000) & PAGE_MASK;
+					default_par->mmap_map[j].poff =
+					    base & PAGE_MASK;
+					default_par->mmap_map[j].size =
+					    (size +
+					     ~PAGE_MASK) & PAGE_MASK;
+					default_par->mmap_map[j].prot_mask =
+					    _PAGE_CACHE;
+					default_par->mmap_map[j].prot_flag =
+					    _PAGE_E;
+					j++;
+				}
+
+				/*
+				 * Here comes the old framebuffer mapping with _PAGE_IE
+				 * set for the big endian half of the framebuffer...
+				 */
+				if (base == addr) {
+					default_par->mmap_map[j].voff =
+					    (pbase + 0x800000) & PAGE_MASK;
+					default_par->mmap_map[j].poff =
+					    (base + 0x800000) & PAGE_MASK;
+					default_par->mmap_map[j].size = 0x800000;
+					default_par->mmap_map[j].prot_mask =
+					    _PAGE_CACHE;
+					default_par->mmap_map[j].prot_flag =
+					    _PAGE_E | _PAGE_IE;
+					size -= 0x800000;
+					j++;
+				}
+
+				default_par->mmap_map[j].voff = pbase & PAGE_MASK;
+				default_par->mmap_map[j].poff = base & PAGE_MASK;
+				default_par->mmap_map[j].size =
+				    (size + ~PAGE_MASK) & PAGE_MASK;
+				default_par->mmap_map[j].prot_mask = _PAGE_CACHE;
+				default_par->mmap_map[j].prot_flag = _PAGE_E;
+				j++;
+			}
 
-		struct fb_var_screeninfo *var = &default_var;
-		unsigned int N, P, Q, M, T, R;
-		u32 v_total, h_total;
-		struct crtc crtc;
-		u8 pll_regs[16];
-		u8 clock_cntl;
-
-		crtc.vxres = prom_getintdefault(node, "width", 1024);
-		crtc.vyres = prom_getintdefault(node, "height", 768);
-		crtc.bpp = prom_getintdefault(node, "depth", 8);
-		crtc.xoffset = crtc.yoffset = 0;
-		crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, info);
-		crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, info);
-		crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, info);
-		crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, info);
-		crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, info);
-		aty_crtc_to_var(&crtc, var);
-
-		h_total = var->xres + var->right_margin +
-			  var->hsync_len + var->left_margin;
-		v_total = var->yres + var->lower_margin +
-			  var->vsync_len + var->upper_margin;
+			if (pdev->device != XL_CHIP_ID) {
+				/*
+				 * Fix PROMs idea of MEM_CNTL settings...
+				 */
+				mem = aty_ld_le32(MEM_CNTL, info);
+				chip_id =
+				    aty_ld_le32(CONFIG_CHIP_ID, info);
+				if (((chip_id & CFG_CHIP_TYPE) ==
+				     VT_CHIP_ID)
+				    && !((chip_id >> 24) & 1)) {
+					switch (mem & 0x0f) {
+					case 3:
+						mem = (mem & ~(0x0f)) | 2;
+						break;
+					case 7:
+						mem = (mem & ~(0x0f)) | 3;
+						break;
+					case 9:
+						mem = (mem & ~(0x0f)) | 4;
+						break;
+					case 11:
+						mem = (mem & ~(0x0f)) | 5;
+						break;
+					default:
+						break;
+					}
+					if ((aty_ld_le32
+					     (CONFIG_STAT0,
+					      info) & 7) >= SDRAM)
+						mem &= ~(0x00700000);
+				}
+				mem &= ~(0xcf80e000);	/* Turn off all undocumented bits. */
+				aty_st_le32(MEM_CNTL, mem, info);
+			}
 
-		/*
-		 * Read the PLL to figure actual Refresh Rate.
-		 */
-    		clock_cntl = aty_ld_8(CLOCK_CNTL, info);
-		/* printk("atyfb: CLOCK_CNTL: %02x\n", clock_cntl); */
-		for (i = 0; i < 16; i++)
-			pll_regs[i] = aty_ld_pll(i, info);
+			/*
+			 * If this is the console device, we will set default video
+			 * settings to what the PROM left us with.
+			 */
+			node = prom_getchild(prom_root_node);
+			node = prom_searchsiblings(node, "aliases");
+			if (node) {
+				len =
+				    prom_getproperty(node, "screen", prop,
+						     sizeof(prop));
+				if (len > 0) {
+					prop[len] = '\0';
+					node = prom_finddevice(prop);
+				} else {
+					node = 0;
+				}
+			}
 
-		/*
-		 * PLL Reference Divider M:
-		 */
-		M = pll_regs[2];
+			pcp = pdev->sysdata;
+			if (node == pcp->prom_node) {
 
-		/*
-		 * PLL Feedback Divider N (Dependant on CLOCK_CNTL):
-		 */
-		N = pll_regs[7 + (clock_cntl & 3)];
+				struct fb_var_screeninfo *var =
+				    &default_var;
+				unsigned int N, P, Q, M, T, R;
+				u32 v_total, h_total;
+				struct crtc crtc;
+				u8 pll_regs[16];
+				u8 clock_cntl;
+
+				crtc.vxres =
+				    prom_getintdefault(node, "width",
+						       1024);
+				crtc.vyres =
+				    prom_getintdefault(node, "height",
+						       768);
+				crtc.bpp =
+				    prom_getintdefault(node, "depth", 8);
+				crtc.xoffset = crtc.yoffset = 0;
+				crtc.h_tot_disp =
+				    aty_ld_le32(CRTC_H_TOTAL_DISP, info);
+				crtc.h_sync_strt_wid =
+				    aty_ld_le32(CRTC_H_SYNC_STRT_WID,
+						info);
+				crtc.v_tot_disp =
+				    aty_ld_le32(CRTC_V_TOTAL_DISP, info);
+				crtc.v_sync_strt_wid =
+				    aty_ld_le32(CRTC_V_SYNC_STRT_WID,
+						info);
+				crtc.gen_cntl =
+				    aty_ld_le32(CRTC_GEN_CNTL, info);
+				aty_crtc_to_var(&crtc, var);
+
+				h_total = var->xres + var->right_margin +
+				    var->hsync_len + var->left_margin;
+				v_total = var->yres + var->lower_margin +
+				    var->vsync_len + var->upper_margin;
+
+				/*
+				 * Read the PLL to figure actual Refresh Rate.
+				 */
+				clock_cntl = aty_ld_8(CLOCK_CNTL, info);
+				/* printk("atyfb: CLOCK_CNTL: %02x\n", clock_cntl); */
+				for (i = 0; i < 16; i++)
+					pll_regs[i] = aty_ld_pll(i, info);
+
+				/*
+				 * PLL Reference Divider M:
+				 */
+				M = pll_regs[2];
+
+				/*
+				 * PLL Feedback Divider N (Dependant on CLOCK_CNTL):
+				 */
+				N = pll_regs[7 + (clock_cntl & 3)];
+
+				/*
+				 * PLL Post Divider P (Dependant on CLOCK_CNTL):
+				 */
+				P = 1 << (pll_regs[6] >>
+					  ((clock_cntl & 3) << 1));
+
+				/*
+				 * PLL Divider Q:
+				 */
+				Q = N / P;
+
+				/*
+				 * Target Frequency:
+				 *
+				 *      T * M
+				 * Q = -------
+				 *      2 * R
+				 *
+				 * where R is XTALIN (= 14318 or 29498 kHz).
+				 */
+				if (pdev->device == XL_CHIP_ID)
+					R = 29498;
+				else
+					R = 14318;
 
-		/*
-		 * PLL Post Divider P (Dependant on CLOCK_CNTL):
-		 */
-		P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
+				T = 2 * Q * R / M;
 
-		/*
-		 * PLL Divider Q:
-		 */
-		Q = N / P;
-
-		/*
-		 * Target Frequency:
-		 *
-		 *      T * M
-		 * Q = -------
-		 *      2 * R
-		 *
-		 * where R is XTALIN (= 14318 or 29498 kHz).
-		 */
-		if (pdev->device == XL_CHIP_ID)
-			R = 29498;
-		else
-			R = 14318;
+				default_var.pixclock = 1000000000 / T;
+			}
+#else				/* __sparc__ */
 
-		T = 2 * Q * R / M;
+			info->fix.mmio_start = 0x7ff000 + addr;
+			default_par->ati_regbase = (unsigned long)
+			    ioremap(info->fix.mmio_start, 0x1000);
+
+			if (!default_par->ati_regbase) {
+				kfree(default_par);
+				kfree(info);
+				release_mem_region(res_start, res_size);
+				return -ENOMEM;
+			}
 
-		default_var.pixclock = 1000000000 / T;
-	    }
-#else /* __sparc__ */
-
-	    info->ati_regbase_phys = 0x7ff000 + addr;
-	    info->ati_regbase = (unsigned long)
-				ioremap(info->ati_regbase_phys, 0x1000);
-
-	    if(!info->ati_regbase) {
-		    kfree(info);
-		    release_mem_region(res_start, res_size);
-		    return -ENOMEM;
-	    }
-
-	    info->ati_regbase_phys += 0xc00;
-	    info->ati_regbase += 0xc00;
-
-	    /*
-	     * Enable memory-space accesses using config-space
-	     * command register.
-	     */
-	    pci_read_config_word(pdev, PCI_COMMAND, &tmp);
-	    if (!(tmp & PCI_COMMAND_MEMORY)) {
-		tmp |= PCI_COMMAND_MEMORY;
-		pci_write_config_word(pdev, PCI_COMMAND, tmp);
-	    }
+			info->fix.mmio_start += 0xc00;
+			default_par->ati_regbase += 0xc00;
 
+			/*
+			 * Enable memory-space accesses using config-space
+			 * command register.
+			 */
+			pci_read_config_word(pdev, PCI_COMMAND, &tmp);
+			if (!(tmp & PCI_COMMAND_MEMORY)) {
+				tmp |= PCI_COMMAND_MEMORY;
+				pci_write_config_word(pdev, PCI_COMMAND,
+						      tmp);
+			}
 #ifdef __BIG_ENDIAN
-	    /* Use the big-endian aperture */
-	    addr += 0x800000;
+			/* Use the big-endian aperture */
+			addr += 0x800000;
 #endif
 
-	    /* Map in frame buffer */
-	    info->frame_buffer_phys = addr;
-	    info->frame_buffer = (unsigned long)ioremap(addr, 0x800000);
-
-	    if(!info->frame_buffer) {
-		    kfree(info);
-		    release_mem_region(res_start, res_size);
-		    return -ENXIO;
-	    }
-
-#endif /* __sparc__ */
-
-	    if (!aty_init(info, "PCI")) {
-		if (info->mmap_map)
-		    kfree(info->mmap_map);
-		kfree(info);
-		release_mem_region(res_start, res_size);
-		return -ENXIO;
-	    }
+			/* Map in frame buffer */
+			info->fix.smem_start = addr;
+			info->screen_base =
+			    (char *) ioremap(addr, 0x800000);
+
+			if (!info->screen_base) {
+				kfree(info);
+				release_mem_region(res_start, res_size);
+				return -ENXIO;
+			}
+#endif				/* __sparc__ */
 
+			if (!aty_init(info, "PCI")) {
+#ifdef __sparc__	
+				if (default_par->mmap_map)
+					kfree(default_par->mmap_map);
+#endif
+				kfree(info);
+				release_mem_region(res_start, res_size);
+				return -ENXIO;
+			}
 #ifdef __sparc__
-	    if (!prom_palette)
-		prom_palette = atyfb_palette;
+			if (!prom_palette)
+				prom_palette = atyfb_palette;
 
-	    /*
-	     * Add /dev/fb mmap values.
-	     */
-	    info->mmap_map[0].voff = 0x8000000000000000UL;
-	    info->mmap_map[0].poff = info->frame_buffer & PAGE_MASK;
-	    info->mmap_map[0].size = info->total_vram;
-	    info->mmap_map[0].prot_mask = _PAGE_CACHE;
-	    info->mmap_map[0].prot_flag = _PAGE_E;
-	    info->mmap_map[1].voff = info->mmap_map[0].voff + info->total_vram;
-	    info->mmap_map[1].poff = info->ati_regbase & PAGE_MASK;
-	    info->mmap_map[1].size = PAGE_SIZE;
-	    info->mmap_map[1].prot_mask = _PAGE_CACHE;
-	    info->mmap_map[1].prot_flag = _PAGE_E;
-#endif /* __sparc__ */
+			/*
+			 * Add /dev/fb mmap values.
+			 */
+			par->mmap_map[0].voff = 0x8000000000000000UL;
+			par->mmap_map[0].poff =
+			    info->screen_base & PAGE_MASK;
+			par->mmap_map[0].size =
+			    info->fix.smem_len;
+			par->mmap_map[0].prot_mask = _PAGE_CACHE;
+			par->mmap_map[0].prot_flag = _PAGE_E;
+			par->mmap_map[1].voff =
+			    par->mmap_map[0].voff +
+			    info->fix.smem_len;
+			par->mmap_map[1].poff =
+			    par->ati_regbase & PAGE_MASK;
+			par->mmap_map[1].size = PAGE_SIZE;
+			par->mmap_map[1].prot_mask = _PAGE_CACHE;
+			par->mmap_map[1].prot_flag = _PAGE_E;
+#endif				/* __sparc__ */
 
 #ifdef CONFIG_PMAC_PBOOK
-	    if (first_display == NULL)
-		    pmu_register_sleep_notifier(&aty_sleep_notifier);
-	    info->next = first_display;
-	    first_display = info;
+			if (first_display == NULL)
+				pmu_register_sleep_notifier
+				    (&aty_sleep_notifier);
+			/* FIXME info->next = first_display; */
+			first_display = info;
 #endif
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-	    if (!console_fb_info)
-		console_fb_info = &info->fb_info;
-#endif /* CONFIG_FB_COMPAT_XPMAC */
+		}
 	}
-    }
 
 #elif defined(CONFIG_ATARI)
-    u32 clock_r;
-    int m64_num;
-    struct fb_info_aty *info;
-
-    for (m64_num = 0; m64_num < mach64_count; m64_num++) {
-	if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
-	    !phys_guiregbase[m64_num]) {
-	    printk(" phys_*[%d] parameters not set => returning early. \n",
-		   m64_num);
-	    continue;
-	}
-
-	info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
-	if (!info) {
-	    printk("atyfb_init: can't alloc fb_info_aty\n");
-	    return -ENOMEM;
-	}
-	memset(info, 0, sizeof(struct fb_info_aty));
+	u32 clock_r;
+	int m64_num;
+	struct fb_info *info;
+
+	for (m64_num = 0; m64_num < mach64_count; m64_num++) {
+		if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
+		    !phys_guiregbase[m64_num]) {
+			printk
+			    (" phys_*[%d] parameters not set => returning early. \n",
+			     m64_num);
+			continue;
+		}
 
-	/*
-	 *  Map the video memory (physical address given) to somewhere in the
-	 *  kernel address space.
-	 */
-	info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
-	info->frame_buffer_phys = info->frame_buffer;  /* Fake! */
-	info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul;
-	info->ati_regbase_phys = info->ati_regbase;  /* Fake! */
-
-	aty_st_le32(CLOCK_CNTL, 0x12345678, info);
-	clock_r = aty_ld_le32(CLOCK_CNTL, info);
-
-	switch (clock_r & 0x003F) {
-	    case 0x12:
-		info->clk_wr_offset = 3;  /*  */
-		break;
-	    case 0x34:
-		info->clk_wr_offset = 2;  /* Medusa ST-IO ISA Adapter etc. */
-		break;
-	    case 0x16:
-		info->clk_wr_offset = 1;  /*  */
-		break;
-	    case 0x38:
-		info->clk_wr_offset = 0;  /* Panther 1 ISA Adapter (Gerald) */
-		break;
-	}
+		info = kmalloc(sizeof(struct fb_info), GFP_ATOMIC);
+		if (!info) {
+			printk("atyfb_init: can't alloc fb_info\n");
+			return -ENOMEM;
+		}
+		memset(info, 0, sizeof(struct fb_info));
+
+		/*
+		 *  Map the video memory (physical address given) to somewhere in the
+		 *  kernel address space.
+		 */
+		info->screen_base = (unsigned long)ioremap(phys_vmembase[m64_num],
+					 		   phys_size[m64_num]);	
+		info->fix.smem_start = info->screen_base;	/* Fake! */
+		par->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num],
+							  0x10000) + 0xFC00ul;
+		info->fix.mmio_start = par->ati_regbase; /* Fake! */
+
+		aty_st_le32(CLOCK_CNTL, 0x12345678, info);
+		clock_r = aty_ld_le32(CLOCK_CNTL, info);
+
+		switch (clock_r & 0x003F) {
+		case 0x12:
+			par->clk_wr_offset = 3;	/*  */
+			break;
+		case 0x34:
+			par->clk_wr_offset = 2;	/* Medusa ST-IO ISA Adapter etc. */
+			break;
+		case 0x16:
+			par->clk_wr_offset = 1;	/*  */
+			break;
+		case 0x38:
+			par->clk_wr_offset = 0;	/* Panther 1 ISA Adapter (Gerald) */
+			break;
+		}
 
-	if (!aty_init(info, "ISA bus")) {
-	    kfree(info);
-	    /* This is insufficient! kernel_map has added two large chunks!! */
-	    return -ENXIO;
+		if (!aty_init(info, "ISA bus")) {
+			kfree(info);
+			/* This is insufficient! kernel_map has added two large chunks!! */
+			return -ENXIO;
+		}
 	}
-    }
-#endif /* CONFIG_ATARI */
-    return 0;
+#endif				/* CONFIG_ATARI */
+	return 0;
 }
 
 #ifndef MODULE
 int __init atyfb_setup(char *options)
 {
-    char *this_opt;
-
-    if (!options || !*options)
-	return 0;
+	char *this_opt;
 
-    while ((this_opt = strsep(&options, ",")) != NULL) {
-	if (!strncmp(this_opt, "font:", 5)) {
-		char *p;
-		int i;
+	if (!options || !*options)
+		return 0;
 
-		p = this_opt + 5;
-		for (i = 0; i < sizeof(fontname) - 1; i++)
-			if (!*p || *p == ' ' || *p == ',')
-				break;
-		memcpy(fontname, this_opt + 5, i);
-		fontname[i] = 0;
-	} else if (!strncmp(this_opt, "noblink", 7)) {
-		curblink = 0;
-	} else if (!strncmp(this_opt, "noaccel", 7)) {
-		noaccel = 1;
-	} else if (!strncmp(this_opt, "vram:", 5))
-		default_vram = simple_strtoul(this_opt+5, NULL, 0);
-	else if (!strncmp(this_opt, "pll:", 4))
-		default_pll = simple_strtoul(this_opt+4, NULL, 0);
-	else if (!strncmp(this_opt, "mclk:", 5))
-		default_mclk = simple_strtoul(this_opt+5, NULL, 0);
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+		if (!strncmp(this_opt, "font:", 5)) {
+			char *p;
+			int i;
+
+			p = this_opt + 5;
+			for (i = 0; i < sizeof(fontname) - 1; i++)
+				if (!*p || *p == ' ' || *p == ',')
+					break;
+			memcpy(fontname, this_opt + 5, i);
+			fontname[i] = 0;
+		} else if (!strncmp(this_opt, "noblink", 7)) {
+			curblink = 0;
+		} else if (!strncmp(this_opt, "noaccel", 7)) {
+			noaccel = 1;
+		} else if (!strncmp(this_opt, "vram:", 5))
+			default_vram =
+			    simple_strtoul(this_opt + 5, NULL, 0);
+		else if (!strncmp(this_opt, "pll:", 4))
+			default_pll =
+			    simple_strtoul(this_opt + 4, NULL, 0);
+		else if (!strncmp(this_opt, "mclk:", 5))
+			default_mclk =
+			    simple_strtoul(this_opt + 5, NULL, 0);
 #ifdef CONFIG_PPC
-	else if (!strncmp(this_opt, "vmode:", 6)) {
-	    unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
-	    if (vmode > 0 && vmode <= VMODE_MAX)
-		default_vmode = vmode;
-	} else if (!strncmp(this_opt, "cmode:", 6)) {
-	    unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
-	    switch (cmode) {
-		case 0:
-		case 8:
-		    default_cmode = CMODE_8;
-		    break;
-		case 15:
-		case 16:
-		    default_cmode = CMODE_16;
-		    break;
-		case 24:
-		case 32:
-		    default_cmode = CMODE_32;
-		    break;
-	    }
-	}
+		else if (!strncmp(this_opt, "vmode:", 6)) {
+			unsigned int vmode =
+			    simple_strtoul(this_opt + 6, NULL, 0);
+			if (vmode > 0 && vmode <= VMODE_MAX)
+				default_vmode = vmode;
+		} else if (!strncmp(this_opt, "cmode:", 6)) {
+			unsigned int cmode =
+			    simple_strtoul(this_opt + 6, NULL, 0);
+			switch (cmode) {
+			case 0:
+			case 8:
+				default_cmode = CMODE_8;
+				break;
+			case 15:
+			case 16:
+				default_cmode = CMODE_16;
+				break;
+			case 24:
+			case 32:
+				default_cmode = CMODE_32;
+				break;
+			}
+		}
 #endif
 #ifdef CONFIG_ATARI
-	/*
-	 * Why do we need this silly Mach64 argument?
-	 * We are already here because of mach64= so its redundant.
-	 */
-	else if (MACH_IS_ATARI && (!strncmp(this_opt, "Mach64:", 7))) {
-	    static unsigned char m64_num;
-	    static char mach64_str[80];
-	    strncpy(mach64_str, this_opt+7, 80);
-	    if (!store_video_par(mach64_str, m64_num)) {
-		m64_num++;
-		mach64_count = m64_num;
-	    }
-	}
+		/*
+		 * Why do we need this silly Mach64 argument?
+		 * We are already here because of mach64= so its redundant.
+		 */
+		else if (MACH_IS_ATARI
+			 && (!strncmp(this_opt, "Mach64:", 7))) {
+			static unsigned char m64_num;
+			static char mach64_str[80];
+			strncpy(mach64_str, this_opt + 7, 80);
+			if (!store_video_par(mach64_str, m64_num)) {
+				m64_num++;
+				mach64_count = m64_num;
+			}
+		}
 #endif
-	else
-	    mode_option = this_opt;
-    }
-    return 0;
+		else
+			mode_option = this_opt;
+	}
+	return 0;
 }
-#endif /* !MODULE */
+#endif				/* !MODULE */
 
 #ifdef CONFIG_ATARI
 static int __init store_video_par(char *video_str, unsigned char m64_num)
 {
-    char *p;
-    unsigned long vmembase, size, guiregbase;
-
-    printk("store_video_par() '%s' \n", video_str);
+	char *p;
+	unsigned long vmembase, size, guiregbase;
 
-    if (!(p = strsep(&video_str, ";")) || !*p)
-	goto mach64_invalid;
-    vmembase = simple_strtoul(p, NULL, 0);
-    if (!(p = strsep(&video_str, ";")) || !*p)
-	goto mach64_invalid;
-    size = simple_strtoul(p, NULL, 0);
-    if (!(p = strsep(&video_str, ";")) || !*p)
-	goto mach64_invalid;
-    guiregbase = simple_strtoul(p, NULL, 0);
-
-    phys_vmembase[m64_num] = vmembase;
-    phys_size[m64_num] = size;
-    phys_guiregbase[m64_num] = guiregbase;
-    printk(" stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
-	   guiregbase);
-    return 0;
-
-mach64_invalid:
-    phys_vmembase[m64_num]   = 0;
-    return -1;
-}
-#endif /* CONFIG_ATARI */
-
-static int atyfbcon_switch(int con, struct fb_info *fb)
-{
-    struct fb_info_aty *info = (struct fb_info_aty *)fb;
-    struct atyfb_par par;
-
-    /* Do we have to save the colormap? */
-    if (fb_display[fb->currcon].cmap.len)
-	fb_get_cmap(&fb_display[fb->currcon].cmap, 1, atyfb_getcolreg, fb);
-
-#ifdef CONFIG_FB_ATY_CT
-    /* Erase HW Cursor */
-    if (info->cursor && (fb->currcon >= 0))
-	atyfb_cursor(&fb_display[fb->currcon], CM_ERASE,
-		     info->cursor->pos.x, info->cursor->pos.y);
-#endif /* CONFIG_FB_ATY_CT */
+	printk("store_video_par() '%s' \n", video_str);
 
-    fb->currcon = con;
+	if (!(p = strsep(&video_str, ";")) || !*p)
+		goto mach64_invalid;
+	vmembase = simple_strtoul(p, NULL, 0);
+	if (!(p = strsep(&video_str, ";")) || !*p)
+		goto mach64_invalid;
+	size = simple_strtoul(p, NULL, 0);
+	if (!(p = strsep(&video_str, ";")) || !*p)
+		goto mach64_invalid;
+	guiregbase = simple_strtoul(p, NULL, 0);
+
+	phys_vmembase[m64_num] = vmembase;
+	phys_size[m64_num] = size;
+	phys_guiregbase[m64_num] = guiregbase;
+	printk(" stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
+	       guiregbase);
+	return 0;
 
-    atyfb_decode_var(&fb_display[con].var, &par, info);
-    atyfb_set_par(&par, info);
-    atyfb_set_dispsw(&fb_display[con], info, par.crtc.bpp,
-		     par.accel_flags & FB_ACCELF_TEXT);
+      mach64_invalid:
+	phys_vmembase[m64_num] = 0;
+	return -1;
+}
+#endif				/* CONFIG_ATARI */
 
-    /* Install new colormap */
-    do_install_cmap(con, fb);
+/*
+#ifdef CONFIG_FB_ATY_CT
+   * Erase HW Cursor *
+    if (par->cursor && (info->currcon >= 0))
+	atyfb_cursor(&fb_display[par->currcon], CM_ERASE,
+		     par->cursor->pos.x, par->cursor->pos.y);
+#endif * CONFIG_FB_ATY_CT *
 
 #ifdef CONFIG_FB_ATY_CT
-    /* Install hw cursor */
-    if (info->cursor) {
+    * Install hw cursor *
+    if (par->cursor) {
 	aty_set_cursor_color(info);
 	aty_set_cursor_shape(info);
     }
-#endif /* CONFIG_FB_ATY_CT */
-    return 1;
-}
+#endif * CONFIG_FB_ATY_CT */
 
     /*
      *  Blank the display.
      */
 
-static int atyfb_blank(int blank, struct fb_info *fb)
+static int atyfb_blank(int blank, struct fb_info *info)
 {
-    struct fb_info_aty *info = (struct fb_info_aty *)fb;
-    u8 gen_cntl;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u8 gen_cntl;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-    if ((_machine == _MACH_Pmac) && blank)
-    	set_backlight_enable(0);
-#endif /* CONFIG_PMAC_BACKLIGHT */
-
-    gen_cntl = aty_ld_8(CRTC_GEN_CNTL, info);
-    if (blank > 0)
-	switch (blank-1) {
-	    case VESA_NO_BLANKING:
-		gen_cntl |= 0x40;
-		break;
-	    case VESA_VSYNC_SUSPEND:
-		gen_cntl |= 0x8;
-		break;
-	    case VESA_HSYNC_SUSPEND:
-		gen_cntl |= 0x4;
-		break;
-	    case VESA_POWERDOWN:
-		gen_cntl |= 0x4c;
-		break;
-	}
-    else
-	gen_cntl &= ~(0x4c);
-    aty_st_8(CRTC_GEN_CNTL, gen_cntl, info);
+	if ((_machine == _MACH_Pmac) && blank)
+		set_backlight_enable(0);
+#endif				/* CONFIG_PMAC_BACKLIGHT */
+
+	gen_cntl = aty_ld_8(CRTC_GEN_CNTL, par);
+	if (blank > 0)
+		switch (blank - 1) {
+		case VESA_NO_BLANKING:
+			gen_cntl |= 0x40;
+			break;
+		case VESA_VSYNC_SUSPEND:
+			gen_cntl |= 0x8;
+			break;
+		case VESA_HSYNC_SUSPEND:
+			gen_cntl |= 0x4;
+			break;
+		case VESA_POWERDOWN:
+			gen_cntl |= 0x4c;
+			break;
+	} else
+		gen_cntl &= ~(0x4c);
+	aty_st_8(CRTC_GEN_CNTL, gen_cntl, par);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-    if ((_machine == _MACH_Pmac) && !blank)
-    	set_backlight_enable(1);
-#endif /* CONFIG_PMAC_BACKLIGHT */
-    return 0;	
-}
-
-
-    /*
-     *  Read a single color register and split it into
-     *  colors/transparent. Return != 0 for invalid regno.
-     */
-
-static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			   u_int *transp, struct fb_info *fb)
-{
-    struct fb_info_aty *info = (struct fb_info_aty *)fb;
-
-    if (regno > 255)
-	return 1;
-    *red = (info->palette[regno].red<<8) | info->palette[regno].red;
-    *green = (info->palette[regno].green<<8) | info->palette[regno].green;
-    *blue = (info->palette[regno].blue<<8) | info->palette[regno].blue;
-    *transp = 0;
-    return 0;
+	if ((_machine == _MACH_Pmac) && !blank)
+		set_backlight_enable(1);
+#endif				/* CONFIG_PMAC_BACKLIGHT */
+	return 0;
 }
 
-
     /*
      *  Set a single color register. The values supplied are already
      *  rounded down to the hardware's capabilities (according to the
@@ -2729,98 +2816,94 @@
      */
 
 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			   u_int transp, struct fb_info *fb)
+			   u_int transp, struct fb_info *info)
 {
-    struct fb_info_aty *info = (struct fb_info_aty *)fb;
-    int i, scale;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	int i, scale;
 
-    if (regno > 255)
-	return 1;
-    red >>= 8;
-    green >>= 8;
-    blue >>= 8;
-    info->palette[regno].red = red;
-    info->palette[regno].green = green;
-    info->palette[regno].blue = blue;
-    i = aty_ld_8(DAC_CNTL, info) & 0xfc;
-    if (M64_HAS(EXTRA_BRIGHT))
-	i |= 0x2;	/*DAC_CNTL|0x2 turns off the extra brightness for gt*/
-    aty_st_8(DAC_CNTL, i, info);
-    aty_st_8(DAC_MASK, 0xff, info);
-    scale = (M64_HAS(INTEGRATED) && info->current_par.crtc.bpp == 16) ? 3 : 0;
-    writeb(regno << scale, &info->aty_cmap_regs->windex);
-    writeb(red, &info->aty_cmap_regs->lut);
-    writeb(green, &info->aty_cmap_regs->lut);
-    writeb(blue, &info->aty_cmap_regs->lut);
-    if (regno < 16)
-	switch (info->current_par.crtc.bpp) {
-#ifdef FBCON_HAS_CFB16
-	    case 16:
-		info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
-						regno;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB24
-	    case 24:
-		info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) |
-						regno;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	    case 32:
-		i = (regno << 8) | regno;
-		info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
-		break;
+	if (regno > 255)
+		return 1;
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+	i = aty_ld_8(DAC_CNTL, par) & 0xfc;
+	if (M64_HAS(EXTRA_BRIGHT))
+		i |= 0x2;	/*DAC_CNTL|0x2 turns off the extra brightness for gt */
+	aty_st_8(DAC_CNTL, i, par);
+	aty_st_8(DAC_MASK, 0xff, par);
+	scale = (M64_HAS(INTEGRATED) && par->crtc.bpp == 16) ? 3 : 0;
+#ifdef CONFIG_ATARI
+	out_8(&par->aty_cmap_regs->windex, regno << scale);
+	out_8(&par->aty_cmap_regs->lut, red);
+	out_8(&par->aty_cmap_regs->lut, green);
+	out_8(&par->aty_cmap_regs->lut, blue);
+#else
+	writeb(regno << scale, &par->aty_cmap_regs->windex);
+	writeb(red, &par->aty_cmap_regs->lut);
+	writeb(green, &par->aty_cmap_regs->lut);
+	writeb(blue, &par->aty_cmap_regs->lut);
 #endif
-	    }
-    return 0;
+	if (regno < 16)
+		switch (par->crtc.bpp) {
+		case 16:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 10) | (regno << 5) | regno;
+			break;
+		case 24:
+			((u32 *) (info->pseudo_palette))[regno] =
+			    (regno << 16) | (regno << 8) | regno;
+			break;
+		case 32:
+			i = (regno << 8) | regno;
+			((u32 *) (info->pseudo_palette))[regno] =
+			    (i << 16) | i;
+			break;
+		}
+	return 0;
 }
 
     /*
      *  Update the `var' structure (called by fbcon.c)
      */
 
-static int atyfbcon_updatevar(int con, struct fb_info *fb)
+static int atyfbcon_updatevar(int con, struct fb_info *info)
 {
-    struct fb_info_aty *info = (struct fb_info_aty *)fb;
-    struct atyfb_par *par = &info->current_par;
-    struct display *p = &fb_display[con];
-    struct vc_data *conp = p->conp;
-    u32 yres, yoffset, sy, height;
-
-    yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
-    yoffset = fb_display[con].var.yoffset;
-
-    sy = (conp->vc_rows + p->yscroll) * fontheight(p);
-    height = yres - conp->vc_rows * fontheight(p);
-
-    if (height && (yoffset + yres > sy)) {
-	u32 xres, xoffset;
-	u32 bgx;
-
-	xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
-	xoffset = fb_display[con].var.xoffset;
-
-
-	bgx = attr_bgcol_ec(p, conp);
-	bgx |= (bgx << 8);
-	bgx |= (bgx << 16);
-
-	if (sy + height > par->crtc.vyres) {
-	    wait_for_fifo(1, info);
-	    aty_st_le32(SC_BOTTOM, sy + height - 1, info);
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct display *p = &fb_display[con];
+	struct vc_data *conp = p->conp;
+	u32 yres, yoffset, sy, height;
+
+	yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
+	yoffset = fb_display[con].var.yoffset;
+
+	sy = (conp->vc_rows + p->yscroll) * fontheight(p);
+	height = yres - conp->vc_rows * fontheight(p);
+
+	if (height && (yoffset + yres > sy)) {
+		struct fb_fillrect area;
+
+		area.dx = fb_display[con].var.xoffset;
+		area.dy = sy;
+		area.height = height;
+		area.width = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
+		area.color = attr_bgcol_ec(p, conp);
+		area.rop = ROP_COPY;
+
+		if (sy + height > par->crtc.vyres) {
+			wait_for_fifo(1, par);
+			aty_st_le32(SC_BOTTOM, sy + height - 1, par);
+		}
+		atyfb_fillrect(info, &area);
 	}
-	aty_rectfill(xoffset, sy, xres, height, bgx, info);
-    }
-
 #ifdef CONFIG_FB_ATY_CT
-    if (info->cursor && (yoffset + yres <= sy))
-	atyfb_cursor(p, CM_ERASE, info->cursor->pos.x, info->cursor->pos.y);
-#endif /* CONFIG_FB_ATY_CT */
+	if (par->cursor && (yoffset + yres <= sy))
+		atyfb_cursor(p, CM_ERASE, par->cursor->pos.x,
+			     par->cursor->pos.y);
+#endif				/* CONFIG_FB_ATY_CT */
 
-    info->current_par.crtc.yoffset = yoffset;
-    set_off_pitch(&info->current_par, info);
-    return 0;
+	par->crtc.yoffset = yoffset;
+	set_off_pitch(par, info);
+	return 0;
 }
 
 
@@ -2828,40 +2911,37 @@
 #ifdef MODULE
 int __init init_module(void)
 {
-    atyfb_init();
-    return fb_list ? 0 : -ENXIO;
+	atyfb_init();
+	return fb_list ? 0 : -ENXIO;
 }
 
 void cleanup_module(void)
 {
-    while (fb_list) {
-	struct fb_info_aty *info = fb_list;
-	fb_list = info->next;
-
-	unregister_framebuffer(&info->fb_info);
+	struct fb_info *info = fb_list;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;		
+	unregister_framebuffer(info);
 
 #ifndef __sparc__
-	if (info->ati_regbase)
-	    iounmap((void *)info->ati_regbase);
-	if (info->frame_buffer)
-	    iounmap((void *)info->frame_buffer);
+	if (par->ati_regbase)
+		iounmap((void *) par->ati_regbase);
+	if (info->screen_base)
+		iounmap((void *) info->screen_base);
 #ifdef __BIG_ENDIAN
 	if (info->cursor && info->cursor->ram)
-	    iounmap(info->cursor->ram);
+		iounmap(info->cursor->ram);
 #endif
 #endif
 
 	if (info->cursor) {
-	    if (info->cursor->timer)
-		kfree(info->cursor->timer);
-	    kfree(info->cursor);
+		if (info->cursor->timer)
+			kfree(info->cursor->timer);
+		kfree(info->cursor);
 	}
 #ifdef __sparc__
-	if (info->mmap_map)
-	    kfree(info->mmap_map);
+	if (par->mmap_map)
+		kfree(par->mmap_map);
 #endif
 	kfree(info);
-    }
 }
 
 #endif
diff -Nru a/drivers/video/aty/mach64.h b/drivers/video/aty/mach64.h
--- a/drivers/video/aty/mach64.h	Wed Jul 24 14:03:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1158 +0,0 @@
-/*
- * ATI Mach64 Register Definitions
- *
- * Copyright (C) 1997 Michael AK Tesch
- *  written with much help from Jon Howell
- *
- * Updated for 3D RAGE PRO and 3D RAGE Mobility by Geert Uytterhoeven
- *	
- * 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.
- */
-
-/*
- * most of the rest of this file comes from ATI sample code
- */
-#ifndef REGMACH64_H
-#define REGMACH64_H
-
-/* NON-GUI MEMORY MAPPED Registers - expressed in BYTE offsets */
-
-/* Accelerator CRTC */
-#define CRTC_H_TOTAL_DISP	0x0000	/* Dword offset 0_00 */
-#define CRTC2_H_TOTAL_DISP	0x0000	/* Dword offset 0_00 */
-#define CRTC_H_SYNC_STRT_WID	0x0004	/* Dword offset 0_01 */
-#define CRTC2_H_SYNC_STRT_WID	0x0004	/* Dword offset 0_01 */
-#define CRTC_H_SYNC_STRT	0x0004
-#define CRTC2_H_SYNC_STRT	0x0004
-#define CRTC_H_SYNC_DLY		0x0005
-#define CRTC2_H_SYNC_DLY	0x0005
-#define CRTC_H_SYNC_WID		0x0006
-#define CRTC2_H_SYNC_WID	0x0006
-#define CRTC_V_TOTAL_DISP	0x0008	/* Dword offset 0_02 */
-#define CRTC2_V_TOTAL_DISP	0x0008	/* Dword offset 0_02 */
-#define CRTC_V_TOTAL		0x0008
-#define CRTC2_V_TOTAL		0x0008
-#define CRTC_V_DISP		0x000A
-#define CRTC2_V_DISP		0x000A
-#define CRTC_V_SYNC_STRT_WID	0x000C	/* Dword offset 0_03 */
-#define CRTC2_V_SYNC_STRT_WID	0x000C	/* Dword offset 0_03 */
-#define CRTC_V_SYNC_STRT	0x000C
-#define CRTC2_V_SYNC_STRT	0x000C
-#define CRTC_V_SYNC_WID		0x000E
-#define CRTC2_V_SYNC_WID	0x000E
-#define CRTC_VLINE_CRNT_VLINE	0x0010	/* Dword offset 0_04 */
-#define CRTC2_VLINE_CRNT_VLINE	0x0010	/* Dword offset 0_04 */
-#define CRTC_OFF_PITCH		0x0014	/* Dword offset 0_05 */
-#define CRTC_OFFSET		0x0014
-#define CRTC_PITCH		0x0016
-#define CRTC_INT_CNTL		0x0018	/* Dword offset 0_06 */
-#define CRTC_GEN_CNTL		0x001C	/* Dword offset 0_07 */
-#define CRTC_PIX_WIDTH		0x001D
-#define CRTC_FIFO		0x001E
-#define CRTC_EXT_DISP		0x001F
-
-/* Memory Buffer Control */
-#define DSP_CONFIG		0x0020	/* Dword offset 0_08 */
-#define PM_DSP_CONFIG		0x0020	/* Dword offset 0_08 (Mobility Only) */
-#define DSP_ON_OFF		0x0024	/* Dword offset 0_09 */
-#define PM_DSP_ON_OFF		0x0024	/* Dword offset 0_09 (Mobility Only) */
-#define TIMER_CONFIG		0x0028	/* Dword offset 0_0A */
-#define MEM_BUF_CNTL		0x002C	/* Dword offset 0_0B */
-#define MEM_ADDR_CONFIG		0x0034	/* Dword offset 0_0D */
-
-/* Accelerator CRTC */
-#define CRT_TRAP		0x0038	/* Dword offset 0_0E */
-
-#define I2C_CNTL_0		0x003C	/* Dword offset 0_0F */
-
-/* Overscan */
-#define OVR_CLR			0x0040	/* Dword offset 0_10 */
-#define OVR2_CLR		0x0040	/* Dword offset 0_10 */
-#define OVR_WID_LEFT_RIGHT	0x0044	/* Dword offset 0_11 */
-#define OVR2_WID_LEFT_RIGHT	0x0044	/* Dword offset 0_11 */
-#define OVR_WID_TOP_BOTTOM	0x0048	/* Dword offset 0_12 */
-#define OVR2_WID_TOP_BOTTOM	0x0048	/* Dword offset 0_12 */
-
-/* Memory Buffer Control */
-#define VGA_DSP_CONFIG		0x004C	/* Dword offset 0_13 */
-#define PM_VGA_DSP_CONFIG	0x004C	/* Dword offset 0_13 (Mobility Only) */
-#define VGA_DSP_ON_OFF		0x0050	/* Dword offset 0_14 */
-#define PM_VGA_DSP_ON_OFF	0x0050	/* Dword offset 0_14 (Mobility Only) */
-#define DSP2_CONFIG		0x0054	/* Dword offset 0_15 */
-#define PM_DSP2_CONFIG		0x0054	/* Dword offset 0_15 (Mobility Only) */
-#define DSP2_ON_OFF		0x0058	/* Dword offset 0_16 */
-#define PM_DSP2_ON_OFF		0x0058	/* Dword offset 0_16 (Mobility Only) */
-
-/* Accelerator CRTC */
-#define CRTC2_OFF_PITCH		0x005C	/* Dword offset 0_17 */
-
-/* Hardware Cursor */
-#define CUR_CLR0		0x0060	/* Dword offset 0_18 */
-#define CUR2_CLR0		0x0060	/* Dword offset 0_18 */
-#define CUR_CLR1		0x0064	/* Dword offset 0_19 */
-#define CUR2_CLR1		0x0064	/* Dword offset 0_19 */
-#define CUR_OFFSET		0x0068	/* Dword offset 0_1A */
-#define CUR2_OFFSET		0x0068	/* Dword offset 0_1A */
-#define CUR_HORZ_VERT_POSN	0x006C	/* Dword offset 0_1B */
-#define CUR2_HORZ_VERT_POSN	0x006C	/* Dword offset 0_1B */
-#define CUR_HORZ_VERT_OFF	0x0070	/* Dword offset 0_1C */
-#define CUR2_HORZ_VERT_OFF	0x0070	/* Dword offset 0_1C */
-
-#define CONFIG_PANEL_LG		0x0074	/* Dword offset 0_1D */
-
-/* General I/O Control */
-#define GP_IO			0x0078	/* Dword offset 0_1E */
-
-/* Test and Debug */
-#define HW_DEBUG		0x007C	/* Dword offset 0_1F */
-
-/* Scratch Pad and Test */
-#define SCRATCH_REG0		0x0080	/* Dword offset 0_20 */
-#define SCRATCH_REG1		0x0084	/* Dword offset 0_21 */
-#define SCRATCH_REG2		0x0088	/* Dword offset 0_22 */
-#define SCRATCH_REG3		0x008C	/* Dword offset 0_23 */
-
-/* Clock Control */
-#define CLOCK_CNTL		0x0090	/* Dword offset 0_24 */
-#define CLOCK_SEL_CNTL		0x0090	/* Dword offset 0_24 */
-
-/* Configuration */
-#define CONFIG_STAT1		0x0094	/* Dword offset 0_25 */
-#define CONFIG_STAT2		0x0098	/* Dword offset 0_26 */
-
-/* Bus Control */
-#define BUS_CNTL		0x00A0	/* Dword offset 0_28 */
-
-#define LCD_INDEX		0x00A4	/* Dword offset 0_29 */
-#define LCD_DATA		0x00A8	/* Dword offset 0_2A */
-
-/* Memory Control */
-#define EXT_MEM_CNTL		0x00AC	/* Dword offset 0_2B */
-#define MEM_CNTL		0x00B0	/* Dword offset 0_2C */
-#define MEM_VGA_WP_SEL		0x00B4	/* Dword offset 0_2D */
-#define MEM_VGA_RP_SEL		0x00B8	/* Dword offset 0_2E */
-
-#define I2C_CNTL_1		0x00BC	/* Dword offset 0_2F */
-
-/* DAC Control */
-#define DAC_REGS		0x00C0	/* Dword offset 0_30 */
-#define DAC_W_INDEX		0x00C0	/* Dword offset 0_30 */
-#define DAC_DATA		0x00C1	/* Dword offset 0_30 */
-#define DAC_MASK		0x00C2	/* Dword offset 0_30 */
-#define DAC_R_INDEX		0x00C3	/* Dword offset 0_30 */
-#define DAC_CNTL		0x00C4	/* Dword offset 0_31 */
-
-#define EXT_DAC_REGS		0x00C8	/* Dword offset 0_32 */
-
-/* Test and Debug */
-#define GEN_TEST_CNTL		0x00D0	/* Dword offset 0_34 */
-
-/* Custom Macros */
-#define CUSTOM_MACRO_CNTL	0x00D4	/* Dword offset 0_35 */
-
-#define LCD_GEN_CNTL_LG		0x00D4	/* Dword offset 0_35 */
-
-#define POWER_MANAGEMENT_LG	0x00D8	/* Dword offset 0_36 (LG) */
-
-/* Configuration */
-#define CONFIG_CNTL		0x00DC	/* Dword offset 0_37 (CT, ET, VT) */
-#define CONFIG_CHIP_ID		0x00E0	/* Dword offset 0_38 */
-#define CONFIG_STAT0		0x00E4	/* Dword offset 0_39 */
-
-/* Test and Debug */
-#define CRC_SIG			0x00E8	/* Dword offset 0_3A */
-#define CRC2_SIG		0x00E8	/* Dword offset 0_3A */
-
-
-/* GUI MEMORY MAPPED Registers */
-
-/* Draw Engine Destination Trajectory */
-#define DST_OFF_PITCH		0x0100	/* Dword offset 0_40 */
-#define DST_X			0x0104	/* Dword offset 0_41 */
-#define DST_Y			0x0108	/* Dword offset 0_42 */
-#define DST_Y_X			0x010C	/* Dword offset 0_43 */
-#define DST_WIDTH		0x0110	/* Dword offset 0_44 */
-#define DST_HEIGHT		0x0114	/* Dword offset 0_45 */
-#define DST_HEIGHT_WIDTH	0x0118	/* Dword offset 0_46 */
-#define DST_X_WIDTH		0x011C	/* Dword offset 0_47 */
-#define DST_BRES_LNTH		0x0120	/* Dword offset 0_48 */
-#define DST_BRES_ERR		0x0124	/* Dword offset 0_49 */
-#define DST_BRES_INC		0x0128	/* Dword offset 0_4A */
-#define DST_BRES_DEC		0x012C	/* Dword offset 0_4B */
-#define DST_CNTL		0x0130	/* Dword offset 0_4C */
-#define DST_Y_X__ALIAS__	0x0134	/* Dword offset 0_4D */
-#define TRAIL_BRES_ERR		0x0138	/* Dword offset 0_4E */
-#define TRAIL_BRES_INC		0x013C	/* Dword offset 0_4F */
-#define TRAIL_BRES_DEC		0x0140	/* Dword offset 0_50 */
-#define LEAD_BRES_LNTH		0x0144	/* Dword offset 0_51 */
-#define Z_OFF_PITCH		0x0148	/* Dword offset 0_52 */
-#define Z_CNTL			0x014C	/* Dword offset 0_53 */
-#define ALPHA_TST_CNTL		0x0150	/* Dword offset 0_54 */
-#define SECONDARY_STW_EXP	0x0158	/* Dword offset 0_56 */
-#define SECONDARY_S_X_INC	0x015C	/* Dword offset 0_57 */
-#define SECONDARY_S_Y_INC	0x0160	/* Dword offset 0_58 */
-#define SECONDARY_S_START	0x0164	/* Dword offset 0_59 */
-#define SECONDARY_W_X_INC	0x0168	/* Dword offset 0_5A */
-#define SECONDARY_W_Y_INC	0x016C	/* Dword offset 0_5B */
-#define SECONDARY_W_START	0x0170	/* Dword offset 0_5C */
-#define SECONDARY_T_X_INC	0x0174	/* Dword offset 0_5D */
-#define SECONDARY_T_Y_INC	0x0178	/* Dword offset 0_5E */
-#define SECONDARY_T_START	0x017C	/* Dword offset 0_5F */
-
-/* Draw Engine Source Trajectory */
-#define SRC_OFF_PITCH		0x0180	/* Dword offset 0_60 */
-#define SRC_X			0x0184	/* Dword offset 0_61 */
-#define SRC_Y			0x0188	/* Dword offset 0_62 */
-#define SRC_Y_X			0x018C	/* Dword offset 0_63 */
-#define SRC_WIDTH1		0x0190	/* Dword offset 0_64 */
-#define SRC_HEIGHT1		0x0194	/* Dword offset 0_65 */
-#define SRC_HEIGHT1_WIDTH1	0x0198	/* Dword offset 0_66 */
-#define SRC_X_START		0x019C	/* Dword offset 0_67 */
-#define SRC_Y_START		0x01A0	/* Dword offset 0_68 */
-#define SRC_Y_X_START		0x01A4	/* Dword offset 0_69 */
-#define SRC_WIDTH2		0x01A8	/* Dword offset 0_6A */
-#define SRC_HEIGHT2		0x01AC	/* Dword offset 0_6B */
-#define SRC_HEIGHT2_WIDTH2	0x01B0	/* Dword offset 0_6C */
-#define SRC_CNTL		0x01B4	/* Dword offset 0_6D */
-
-#define SCALE_OFF		0x01C0	/* Dword offset 0_70 */
-#define SECONDARY_SCALE_OFF	0x01C4	/* Dword offset 0_71 */
-
-#define TEX_0_OFF		0x01C0	/* Dword offset 0_70 */
-#define TEX_1_OFF		0x01C4	/* Dword offset 0_71 */
-#define TEX_2_OFF		0x01C8	/* Dword offset 0_72 */
-#define TEX_3_OFF		0x01CC	/* Dword offset 0_73 */
-#define TEX_4_OFF		0x01D0	/* Dword offset 0_74 */
-#define TEX_5_OFF		0x01D4	/* Dword offset 0_75 */
-#define TEX_6_OFF		0x01D8	/* Dword offset 0_76 */
-#define TEX_7_OFF		0x01DC	/* Dword offset 0_77 */
-
-#define SCALE_WIDTH		0x01DC	/* Dword offset 0_77 */
-#define SCALE_HEIGHT		0x01E0	/* Dword offset 0_78 */
-
-#define TEX_8_OFF		0x01E0	/* Dword offset 0_78 */
-#define TEX_9_OFF		0x01E4	/* Dword offset 0_79 */
-#define TEX_10_OFF		0x01E8	/* Dword offset 0_7A */
-#define S_Y_INC			0x01EC	/* Dword offset 0_7B */
-
-#define SCALE_PITCH		0x01EC	/* Dword offset 0_7B */
-#define SCALE_X_INC		0x01F0	/* Dword offset 0_7C */
-
-#define RED_X_INC		0x01F0	/* Dword offset 0_7C */
-#define GREEN_X_INC		0x01F4	/* Dword offset 0_7D */
-
-#define SCALE_Y_INC		0x01F4	/* Dword offset 0_7D */
-#define SCALE_VACC		0x01F8	/* Dword offset 0_7E */
-#define SCALE_3D_CNTL		0x01FC	/* Dword offset 0_7F */
-
-/* Host Data */
-#define HOST_DATA0		0x0200	/* Dword offset 0_80 */
-#define HOST_DATA1		0x0204	/* Dword offset 0_81 */
-#define HOST_DATA2		0x0208	/* Dword offset 0_82 */
-#define HOST_DATA3		0x020C	/* Dword offset 0_83 */
-#define HOST_DATA4		0x0210	/* Dword offset 0_84 */
-#define HOST_DATA5		0x0214	/* Dword offset 0_85 */
-#define HOST_DATA6		0x0218	/* Dword offset 0_86 */
-#define HOST_DATA7		0x021C	/* Dword offset 0_87 */
-#define HOST_DATA8		0x0220	/* Dword offset 0_88 */
-#define HOST_DATA9		0x0224	/* Dword offset 0_89 */
-#define HOST_DATAA		0x0228	/* Dword offset 0_8A */
-#define HOST_DATAB		0x022C	/* Dword offset 0_8B */
-#define HOST_DATAC		0x0230	/* Dword offset 0_8C */
-#define HOST_DATAD		0x0234	/* Dword offset 0_8D */
-#define HOST_DATAE		0x0238	/* Dword offset 0_8E */
-#define HOST_DATAF		0x023C	/* Dword offset 0_8F */
-#define HOST_CNTL		0x0240	/* Dword offset 0_90 */
-
-/* GUI Bus Mastering */
-#define BM_HOSTDATA		0x0244	/* Dword offset 0_91 */
-#define BM_ADDR			0x0248	/* Dword offset 0_92 */
-#define BM_DATA			0x0248	/* Dword offset 0_92 */
-#define BM_GUI_TABLE_CMD	0x024C	/* Dword offset 0_93 */
-
-/* Pattern */
-#define PAT_REG0		0x0280	/* Dword offset 0_A0 */
-#define PAT_REG1		0x0284	/* Dword offset 0_A1 */
-#define PAT_CNTL		0x0288	/* Dword offset 0_A2 */
-
-/* Scissors */
-#define SC_LEFT			0x02A0	/* Dword offset 0_A8 */
-#define SC_RIGHT		0x02A4	/* Dword offset 0_A9 */
-#define SC_LEFT_RIGHT		0x02A8	/* Dword offset 0_AA */
-#define SC_TOP			0x02AC	/* Dword offset 0_AB */
-#define SC_BOTTOM		0x02B0	/* Dword offset 0_AC */
-#define SC_TOP_BOTTOM		0x02B4	/* Dword offset 0_AD */
-
-/* Data Path */
-#define USR1_DST_OFF_PITCH	0x02B8	/* Dword offset 0_AE */
-#define USR2_DST_OFF_PITCH	0x02BC	/* Dword offset 0_AF */
-#define DP_BKGD_CLR		0x02C0	/* Dword offset 0_B0 */
-#define DP_FOG_CLR		0x02C4	/* Dword offset 0_B1 */
-#define DP_FRGD_CLR		0x02C4	/* Dword offset 0_B1 */
-#define DP_WRITE_MASK		0x02C8	/* Dword offset 0_B2 */
-#define DP_CHAIN_MASK		0x02CC	/* Dword offset 0_B3 */
-#define DP_PIX_WIDTH		0x02D0	/* Dword offset 0_B4 */
-#define DP_MIX			0x02D4	/* Dword offset 0_B5 */
-#define DP_SRC			0x02D8	/* Dword offset 0_B6 */
-#define DP_FRGD_CLR_MIX		0x02DC	/* Dword offset 0_B7 */
-#define DP_FRGD_BKGD_CLR	0x02E0	/* Dword offset 0_B8 */
-
-/* Draw Engine Destination Trajectory */
-#define DST_X_Y			0x02E8	/* Dword offset 0_BA */
-#define DST_WIDTH_HEIGHT	0x02EC	/* Dword offset 0_BB */
-
-/* Data Path */
-#define USR_DST_PICTH		0x02F0	/* Dword offset 0_BC */
-#define DP_SET_GUI_ENGINE2	0x02F8	/* Dword offset 0_BE */
-#define DP_SET_GUI_ENGINE	0x02FC	/* Dword offset 0_BF */
-
-/* Color Compare */
-#define CLR_CMP_CLR		0x0300	/* Dword offset 0_C0 */
-#define CLR_CMP_MASK		0x0304	/* Dword offset 0_C1 */
-#define CLR_CMP_CNTL		0x0308	/* Dword offset 0_C2 */
-
-/* Command FIFO */
-#define FIFO_STAT		0x0310	/* Dword offset 0_C4 */
-
-#define CONTEXT_MASK		0x0320	/* Dword offset 0_C8 */
-#define CONTEXT_LOAD_CNTL	0x032C	/* Dword offset 0_CB */
-
-/* Engine Control */
-#define GUI_TRAJ_CNTL		0x0330	/* Dword offset 0_CC */
-
-/* Engine Status/FIFO */
-#define GUI_STAT		0x0338	/* Dword offset 0_CE */
-
-#define TEX_PALETTE_INDEX	0x0340	/* Dword offset 0_D0 */
-#define STW_EXP			0x0344	/* Dword offset 0_D1 */
-#define LOG_MAX_INC		0x0348	/* Dword offset 0_D2 */
-#define S_X_INC			0x034C	/* Dword offset 0_D3 */
-#define S_Y_INC__ALIAS__	0x0350	/* Dword offset 0_D4 */
-
-#define SCALE_PITCH__ALIAS__	0x0350	/* Dword offset 0_D4 */
-
-#define S_START			0x0354	/* Dword offset 0_D5 */
-#define W_X_INC			0x0358	/* Dword offset 0_D6 */
-#define W_Y_INC			0x035C	/* Dword offset 0_D7 */
-#define W_START			0x0360	/* Dword offset 0_D8 */
-#define T_X_INC			0x0364	/* Dword offset 0_D9 */
-#define T_Y_INC			0x0368	/* Dword offset 0_DA */
-
-#define SECONDARY_SCALE_PITCH	0x0368	/* Dword offset 0_DA */
-
-#define T_START			0x036C	/* Dword offset 0_DB */
-#define TEX_SIZE_PITCH		0x0370	/* Dword offset 0_DC */
-#define TEX_CNTL		0x0374	/* Dword offset 0_DD */
-#define SECONDARY_TEX_OFFSET	0x0378	/* Dword offset 0_DE */
-#define TEX_PALETTE		0x037C	/* Dword offset 0_DF */
-
-#define SCALE_PITCH_BOTH	0x0380	/* Dword offset 0_E0 */
-#define SECONDARY_SCALE_OFF_ACC	0x0384	/* Dword offset 0_E1 */
-#define SCALE_OFF_ACC		0x0388	/* Dword offset 0_E2 */
-#define SCALE_DST_Y_X		0x038C	/* Dword offset 0_E3 */
-
-/* Draw Engine Destination Trajectory */
-#define COMPOSITE_SHADOW_ID	0x0398	/* Dword offset 0_E6 */
-
-#define SECONDARY_SCALE_X_INC	0x039C	/* Dword offset 0_E7 */
-
-#define SPECULAR_RED_X_INC	0x039C	/* Dword offset 0_E7 */
-#define SPECULAR_RED_Y_INC	0x03A0	/* Dword offset 0_E8 */
-#define SPECULAR_RED_START	0x03A4	/* Dword offset 0_E9 */
-
-#define SECONDARY_SCALE_HACC	0x03A4	/* Dword offset 0_E9 */
-
-#define SPECULAR_GREEN_X_INC	0x03A8	/* Dword offset 0_EA */
-#define SPECULAR_GREEN_Y_INC	0x03AC	/* Dword offset 0_EB */
-#define SPECULAR_GREEN_START	0x03B0	/* Dword offset 0_EC */
-#define SPECULAR_BLUE_X_INC	0x03B4	/* Dword offset 0_ED */
-#define SPECULAR_BLUE_Y_INC	0x03B8	/* Dword offset 0_EE */
-#define SPECULAR_BLUE_START	0x03BC	/* Dword offset 0_EF */
-
-#define SCALE_X_INC__ALIAS__	0x03C0	/* Dword offset 0_F0 */
-
-#define RED_X_INC__ALIAS__	0x03C0	/* Dword offset 0_F0 */
-#define RED_Y_INC		0x03C4	/* Dword offset 0_F1 */
-#define RED_START		0x03C8	/* Dword offset 0_F2 */
-
-#define SCALE_HACC		0x03C8	/* Dword offset 0_F2 */
-#define SCALE_Y_INC__ALIAS__	0x03CC	/* Dword offset 0_F3 */
-
-#define GREEN_X_INC__ALIAS__	0x03CC	/* Dword offset 0_F3 */
-#define GREEN_Y_INC		0x03D0	/* Dword offset 0_F4 */
-
-#define SECONDARY_SCALE_Y_INC	0x03D0	/* Dword offset 0_F4 */
-#define SECONDARY_SCALE_VACC	0x03D4	/* Dword offset 0_F5 */
-
-#define GREEN_START		0x03D4	/* Dword offset 0_F5 */
-#define BLUE_X_INC		0x03D8	/* Dword offset 0_F6 */
-#define BLUE_Y_INC		0x03DC	/* Dword offset 0_F7 */
-#define BLUE_START		0x03E0	/* Dword offset 0_F8 */
-#define Z_X_INC			0x03E4	/* Dword offset 0_F9 */
-#define Z_Y_INC			0x03E8	/* Dword offset 0_FA */
-#define Z_START			0x03EC	/* Dword offset 0_FB */
-#define ALPHA_X_INC		0x03F0	/* Dword offset 0_FC */
-#define FOG_X_INC		0x03F0	/* Dword offset 0_FC */
-#define ALPHA_Y_INC		0x03F4	/* Dword offset 0_FD */
-#define FOG_Y_INC		0x03F4	/* Dword offset 0_FD */
-#define ALPHA_START		0x03F8	/* Dword offset 0_FE */
-#define FOG_START		0x03F8	/* Dword offset 0_FE */
-
-#define OVERLAY_Y_X_START		0x0400	/* Dword offset 1_00 */
-#define OVERLAY_Y_X_END			0x0404	/* Dword offset 1_01 */
-#define OVERLAY_VIDEO_KEY_CLR		0x0408	/* Dword offset 1_02 */
-#define OVERLAY_VIDEO_KEY_MSK		0x040C	/* Dword offset 1_03 */
-#define OVERLAY_GRAPHICS_KEY_CLR	0x0410	/* Dword offset 1_04 */
-#define OVERLAY_GRAPHICS_KEY_MSK	0x0414	/* Dword offset 1_05 */
-#define OVERLAY_KEY_CNTL		0x0418	/* Dword offset 1_06 */
-
-#define OVERLAY_SCALE_INC	0x0420	/* Dword offset 1_08 */
-#define OVERLAY_SCALE_CNTL	0x0424	/* Dword offset 1_09 */
-#define SCALER_HEIGHT_WIDTH	0x0428	/* Dword offset 1_0A */
-#define SCALER_TEST		0x042C	/* Dword offset 1_0B */
-#define SCALER_BUF0_OFFSET	0x0434	/* Dword offset 1_0D */
-#define SCALER_BUF1_OFFSET	0x0438	/* Dword offset 1_0E */
-#define SCALE_BUF_PITCH		0x043C	/* Dword offset 1_0F */
-
-#define CAPTURE_START_END	0x0440	/* Dword offset 1_10 */
-#define CAPTURE_X_WIDTH		0x0444	/* Dword offset 1_11 */
-#define VIDEO_FORMAT		0x0448	/* Dword offset 1_12 */
-#define VBI_START_END		0x044C	/* Dword offset 1_13 */
-#define CAPTURE_CONFIG		0x0450	/* Dword offset 1_14 */
-#define TRIG_CNTL		0x0454	/* Dword offset 1_15 */
-
-#define OVERLAY_EXCLUSIVE_HORZ	0x0458	/* Dword offset 1_16 */
-#define OVERLAY_EXCLUSIVE_VERT	0x045C	/* Dword offset 1_17 */
-
-#define VAL_WIDTH		0x0460	/* Dword offset 1_18 */
-#define CAPTURE_DEBUG		0x0464	/* Dword offset 1_19 */
-#define VIDEO_SYNC_TEST		0x0468	/* Dword offset 1_1A */
-
-/* GenLocking */
-#define SNAPSHOT_VH_COUNTS	0x0470	/* Dword offset 1_1C */
-#define SNAPSHOT_F_COUNT	0x0474	/* Dword offset 1_1D */
-#define N_VIF_COUNT		0x0478	/* Dword offset 1_1E */
-#define SNAPSHOT_VIF_COUNT	0x047C	/* Dword offset 1_1F */
-
-#define CAPTURE_BUF0_OFFSET	0x0480	/* Dword offset 1_20 */
-#define CAPTURE_BUF1_OFFSET	0x0484	/* Dword offset 1_21 */
-#define CAPTURE_BUF_PITCH	0x0488	/* Dword offset 1_22 */
-
-/* GenLocking */
-#define SNAPSHOT2_VH_COUNTS	0x04B0	/* Dword offset 1_2C */
-#define SNAPSHOT2_F_COUNT	0x04B4	/* Dword offset 1_2D */
-#define N_VIF2_COUNT		0x04B8	/* Dword offset 1_2E */
-#define SNAPSHOT2_VIF_COUNT	0x04BC	/* Dword offset 1_2F */
-
-#define MPP_CONFIG		0x04C0	/* Dword offset 1_30 */
-#define MPP_STROBE_SEQ		0x04C4	/* Dword offset 1_31 */
-#define MPP_ADDR		0x04C8	/* Dword offset 1_32 */
-#define MPP_DATA		0x04CC	/* Dword offset 1_33 */
-#define TVO_CNTL		0x0500	/* Dword offset 1_40 */
-
-/* Test and Debug */
-#define CRT_HORZ_VERT_LOAD	0x0544	/* Dword offset 1_51 */
-
-/* AGP */
-#define AGP_BASE		0x0548	/* Dword offset 1_52 */
-#define AGP_CNTL		0x054C	/* Dword offset 1_53 */
-
-#define SCALER_COLOUR_CNTL	0x0550	/* Dword offset 1_54 */
-#define SCALER_H_COEFF0		0x0554	/* Dword offset 1_55 */
-#define SCALER_H_COEFF1		0x0558	/* Dword offset 1_56 */
-#define SCALER_H_COEFF2		0x055C	/* Dword offset 1_57 */
-#define SCALER_H_COEFF3		0x0560	/* Dword offset 1_58 */
-#define SCALER_H_COEFF4		0x0564	/* Dword offset 1_59 */
-
-/* Command FIFO */
-#define GUI_CMDFIFO_DEBUG	0x0570	/* Dword offset 1_5C */
-#define GUI_CMDFIFO_DATA	0x0574	/* Dword offset 1_5D */
-#define GUI_CNTL		0x0578	/* Dword offset 1_5E */
-
-/* Bus Mastering */
-#define BM_FRAME_BUF_OFFSET	0x0580	/* Dword offset 1_60 */
-#define BM_SYSTEM_MEM_ADDR	0x0584	/* Dword offset 1_61 */
-#define BM_COMMAND		0x0588	/* Dword offset 1_62 */
-#define BM_STATUS		0x058C	/* Dword offset 1_63 */
-#define BM_GUI_TABLE		0x05B8	/* Dword offset 1_6E */
-#define BM_SYSTEM_TABLE		0x05BC	/* Dword offset 1_6F */
-
-#define SCALER_BUF0_OFFSET_U	0x05D4	/* Dword offset 1_75 */
-#define SCALER_BUF0_OFFSET_V	0x05D8	/* Dword offset 1_76 */
-#define SCALER_BUF1_OFFSET_U	0x05DC	/* Dword offset 1_77 */
-#define SCALER_BUF1_OFFSET_V	0x05E0	/* Dword offset 1_78 */
-
-/* Setup Engine */
-#define VERTEX_1_S		0x0640	/* Dword offset 1_90 */
-#define VERTEX_1_T		0x0644	/* Dword offset 1_91 */
-#define VERTEX_1_W		0x0648	/* Dword offset 1_92 */
-#define VERTEX_1_SPEC_ARGB	0x064C	/* Dword offset 1_93 */
-#define VERTEX_1_Z		0x0650	/* Dword offset 1_94 */
-#define VERTEX_1_ARGB		0x0654	/* Dword offset 1_95 */
-#define VERTEX_1_X_Y		0x0658	/* Dword offset 1_96 */
-#define ONE_OVER_AREA		0x065C	/* Dword offset 1_97 */
-#define VERTEX_2_S		0x0660	/* Dword offset 1_98 */
-#define VERTEX_2_T		0x0664	/* Dword offset 1_99 */
-#define VERTEX_2_W		0x0668	/* Dword offset 1_9A */
-#define VERTEX_2_SPEC_ARGB	0x066C	/* Dword offset 1_9B */
-#define VERTEX_2_Z		0x0670	/* Dword offset 1_9C */
-#define VERTEX_2_ARGB		0x0674	/* Dword offset 1_9D */
-#define VERTEX_2_X_Y		0x0678	/* Dword offset 1_9E */
-#define ONE_OVER_AREA		0x065C	/* Dword offset 1_9F */
-#define VERTEX_3_S		0x0680	/* Dword offset 1_A0 */
-#define VERTEX_3_T		0x0684	/* Dword offset 1_A1 */
-#define VERTEX_3_W		0x0688	/* Dword offset 1_A2 */
-#define VERTEX_3_SPEC_ARGB	0x068C	/* Dword offset 1_A3 */
-#define VERTEX_3_Z		0x0690	/* Dword offset 1_A4 */
-#define VERTEX_3_ARGB		0x0694	/* Dword offset 1_A5 */
-#define VERTEX_3_X_Y		0x0698	/* Dword offset 1_A6 */
-#define ONE_OVER_AREA		0x065C	/* Dword offset 1_A7 */
-#define VERTEX_1_S		0x0640	/* Dword offset 1_AB */
-#define VERTEX_1_T		0x0644	/* Dword offset 1_AC */
-#define VERTEX_1_W		0x0648	/* Dword offset 1_AD */
-#define VERTEX_2_S		0x0660	/* Dword offset 1_AE */
-#define VERTEX_2_T		0x0664	/* Dword offset 1_AF */
-#define VERTEX_2_W		0x0668	/* Dword offset 1_B0 */
-#define VERTEX_3_SECONDARY_S	0x06C0	/* Dword offset 1_B0 */
-#define VERTEX_3_S		0x0680	/* Dword offset 1_B1 */
-#define VERTEX_3_SECONDARY_T	0x06C4	/* Dword offset 1_B1 */
-#define VERTEX_3_T		0x0684	/* Dword offset 1_B2 */
-#define VERTEX_3_SECONDARY_W	0x06C8	/* Dword offset 1_B2 */
-#define VERTEX_3_W		0x0688	/* Dword offset 1_B3 */
-#define VERTEX_1_SPEC_ARGB	0x064C	/* Dword offset 1_B4 */
-#define VERTEX_2_SPEC_ARGB	0x066C	/* Dword offset 1_B5 */
-#define VERTEX_3_SPEC_ARGB	0x068C	/* Dword offset 1_B6 */
-#define VERTEX_1_Z		0x0650	/* Dword offset 1_B7 */
-#define VERTEX_2_Z		0x0670	/* Dword offset 1_B8 */
-#define VERTEX_3_Z		0x0690	/* Dword offset 1_B9 */
-#define VERTEX_1_ARGB		0x0654	/* Dword offset 1_BA */
-#define VERTEX_2_ARGB		0x0674	/* Dword offset 1_BB */
-#define VERTEX_3_ARGB		0x0694	/* Dword offset 1_BC */
-#define VERTEX_1_X_Y		0x0658	/* Dword offset 1_BD */
-#define VERTEX_2_X_Y		0x0678	/* Dword offset 1_BE */
-#define VERTEX_3_X_Y		0x0698	/* Dword offset 1_BF */
-#define ONE_OVER_AREA_UC	0x0700	/* Dword offset 1_C0 */
-#define SETUP_CNTL		0x0704	/* Dword offset 1_C1 */
-#define VERTEX_1_SECONDARY_S	0x0728	/* Dword offset 1_CA */
-#define VERTEX_1_SECONDARY_T	0x072C	/* Dword offset 1_CB */
-#define VERTEX_1_SECONDARY_W	0x0730	/* Dword offset 1_CC */
-#define VERTEX_2_SECONDARY_S	0x0734	/* Dword offset 1_CD */
-#define VERTEX_2_SECONDARY_T	0x0738	/* Dword offset 1_CE */
-#define VERTEX_2_SECONDARY_W	0x073C	/* Dword offset 1_CF */
-
-
-#define GTC_3D_RESET_DELAY	3	/* 3D engine reset delay in ms */
-
-/* CRTC control values (mostly CRTC_GEN_CNTL) */
-
-#define CRTC_H_SYNC_NEG		0x00200000
-#define CRTC_V_SYNC_NEG		0x00200000
-
-#define CRTC_DBL_SCAN_EN	0x00000001
-#define CRTC_INTERLACE_EN	0x00000002
-#define CRTC_HSYNC_DIS		0x00000004
-#define CRTC_VSYNC_DIS		0x00000008
-#define CRTC_CSYNC_EN		0x00000010
-#define CRTC_PIX_BY_2_EN	0x00000020	/* unused on RAGE */
-#define CRTC_DISPLAY_DIS	0x00000040
-#define CRTC_VGA_XOVERSCAN	0x00000040
-
-#define CRTC_PIX_WIDTH_MASK	0x00000700
-#define CRTC_PIX_WIDTH_4BPP	0x00000100
-#define CRTC_PIX_WIDTH_8BPP	0x00000200
-#define CRTC_PIX_WIDTH_15BPP	0x00000300
-#define CRTC_PIX_WIDTH_16BPP	0x00000400
-#define CRTC_PIX_WIDTH_24BPP	0x00000500
-#define CRTC_PIX_WIDTH_32BPP	0x00000600
-
-#define CRTC_BYTE_PIX_ORDER	0x00000800
-#define CRTC_PIX_ORDER_MSN_LSN	0x00000000
-#define CRTC_PIX_ORDER_LSN_MSN	0x00000800
-
-#define CRTC_FIFO_LWM		0x000f0000
-
-#define VGA_128KAP_PAGING	0x00100000
-#define VFC_SYNC_TRISTATE	0x00200000
-#define CRTC_LOCK_REGS		0x00400000
-#define CRTC_SYNC_TRISTATE	0x00800000
-
-#define CRTC_EXT_DISP_EN	0x01000000
-#define CRTC_ENABLE		0x02000000
-#define CRTC_DISP_REQ_ENB	0x04000000
-#define VGA_ATI_LINEAR		0x08000000
-#define CRTC_VSYNC_FALL_EDGE	0x10000000
-#define VGA_TEXT_132		0x20000000
-#define VGA_XCRT_CNT_EN		0x40000000
-#define VGA_CUR_B_TEST		0x80000000
-
-#define CRTC_CRNT_VLINE		0x07f00000
-#define CRTC_VBLANK		0x00000001
-
-
-/* DAC control values */
-
-#define DAC_EXT_SEL_RS2		0x01
-#define DAC_EXT_SEL_RS3		0x02
-#define DAC_8BIT_EN		0x00000100
-#define DAC_PIX_DLY_MASK	0x00000600
-#define DAC_PIX_DLY_0NS		0x00000000
-#define DAC_PIX_DLY_2NS		0x00000200
-#define DAC_PIX_DLY_4NS		0x00000400
-#define DAC_BLANK_ADJ_MASK	0x00001800
-#define DAC_BLANK_ADJ_0		0x00000000
-#define DAC_BLANK_ADJ_1		0x00000800
-#define DAC_BLANK_ADJ_2		0x00001000
-
-
-/* Mix control values */
-
-#define MIX_NOT_DST		0x0000
-#define MIX_0			0x0001
-#define MIX_1			0x0002
-#define MIX_DST			0x0003
-#define MIX_NOT_SRC		0x0004
-#define MIX_XOR			0x0005
-#define MIX_XNOR		0x0006
-#define MIX_SRC			0x0007
-#define MIX_NAND		0x0008
-#define MIX_NOT_SRC_OR_DST	0x0009
-#define MIX_SRC_OR_NOT_DST	0x000a
-#define MIX_OR			0x000b
-#define MIX_AND			0x000c
-#define MIX_SRC_AND_NOT_DST	0x000d
-#define MIX_NOT_SRC_AND_DST	0x000e
-#define MIX_NOR			0x000f
-
-/* Maximum engine dimensions */
-#define ENGINE_MIN_X		0
-#define ENGINE_MIN_Y		0
-#define ENGINE_MAX_X		4095
-#define ENGINE_MAX_Y		16383
-
-/* Mach64 engine bit constants - these are typically ORed together */
-
-/* BUS_CNTL register constants */
-#define BUS_FIFO_ERR_ACK	0x00200000
-#define BUS_HOST_ERR_ACK	0x00800000
-
-/* GEN_TEST_CNTL register constants */
-#define GEN_OVR_OUTPUT_EN	0x20
-#define HWCURSOR_ENABLE		0x80
-#define GUI_ENGINE_ENABLE	0x100
-#define BLOCK_WRITE_ENABLE	0x200
-
-/* DSP_CONFIG register constants */
-#define DSP_XCLKS_PER_QW	0x00003fff
-#define DSP_LOOP_LATENCY	0x000f0000
-#define DSP_PRECISION		0x00700000
-
-/* DSP_ON_OFF register constants */
-#define DSP_OFF			0x000007ff
-#define DSP_ON			0x07ff0000
-
-/* CLOCK_CNTL register constants */
-#define CLOCK_SEL		0x0f
-#define CLOCK_DIV		0x30
-#define CLOCK_DIV1		0x00
-#define CLOCK_DIV2		0x10
-#define CLOCK_DIV4		0x20
-#define CLOCK_STROBE		0x40
-#define PLL_WR_EN		0x02
-
-/* PLL register indices */
-#define MPLL_CNTL		0x00
-#define VPLL_CNTL		0x01
-#define PLL_REF_DIV		0x02
-#define PLL_GEN_CNTL		0x03
-#define MCLK_FB_DIV		0x04
-#define PLL_VCLK_CNTL		0x05
-#define VCLK_POST_DIV		0x06
-#define VCLK0_FB_DIV		0x07
-#define VCLK1_FB_DIV		0x08
-#define VCLK2_FB_DIV		0x09
-#define VCLK3_FB_DIV		0x0A
-#define PLL_EXT_CNTL		0x0B
-#define DLL_CNTL		0x0C
-#define DLL1_CNTL		0x0C
-#define VFC_CNTL		0x0D
-#define PLL_TEST_CNTL		0x0E
-#define PLL_TEST_COUNT		0x0F
-#define LVDS_CNTL0		0x10
-#define LVDS_CNTL1		0x11
-#define AGP1_CNTL		0x12
-#define AGP2_CNTL		0x13
-#define DLL2_CNTL		0x14
-#define SCLK_FB_DIV		0x15
-#define SPLL_CNTL1		0x16
-#define SPLL_CNTL2		0x17
-#define APLL_STRAPS		0x18
-#define EXT_VPLL_CNTL		0x19
-#define EXT_VPLL_REF_DIV	0x1A
-#define EXT_VPLL_FB_DIV		0x1B
-#define EXT_VPLL_MSB		0x1C
-#define HTOTAL_CNTL		0x1D
-#define BYTE_CLK_CNTL		0x1E
-#define TV_PLL_CNTL1		0x1F
-#define TV_PLL_CNTL2		0x20
-#define TV_PLL_CNTL		0x21
-#define EXT_TV_PLL		0x22
-#define V2PLL_CNTL		0x23
-#define PLL_V2CLK_CNTL		0x24
-#define EXT_V2PLL_REF_DIV	0x25
-#define EXT_V2PLL_FB_DIV	0x26
-#define EXT_V2PLL_MSB		0x27
-#define HTOTAL2_CNTL		0x28
-#define PLL_YCLK_CNTL		0x29
-#define PM_DYN_CLK_CNTL		0x2A
-
-/* Fields in PLL registers */
-#define PLL_PC_GAIN		0x07
-#define PLL_VC_GAIN		0x18
-#define PLL_DUTY_CYC		0xE0
-#define PLL_OVERRIDE		0x01
-#define PLL_MCLK_RST		0x02
-#define OSC_EN			0x04
-#define EXT_CLK_EN		0x08
-#define MCLK_SRC_SEL		0x70
-#define EXT_CLK_CNTL		0x80
-#define VCLK_SRC_SEL		0x03
-#define PLL_VCLK_RST		0x04
-#define VCLK_INVERT		0x08
-#define VCLK0_POST		0x03
-#define VCLK1_POST		0x0C
-#define VCLK2_POST		0x30
-#define VCLK3_POST		0xC0
-
-/* CONFIG_CNTL register constants */
-#define APERTURE_4M_ENABLE	1
-#define APERTURE_8M_ENABLE	2
-#define VGA_APERTURE_ENABLE	4
-
-/* CONFIG_STAT0 register constants (GX, CX) */
-#define CFG_BUS_TYPE		0x00000007
-#define CFG_MEM_TYPE		0x00000038
-#define CFG_INIT_DAC_TYPE	0x00000e00
-
-/* CONFIG_STAT0 register constants (CT, ET, VT) */
-#define CFG_MEM_TYPE_xT		0x00000007
-
-#define ISA			0
-#define EISA			1
-#define LOCAL_BUS		6
-#define PCI			7
-
-/* Memory types for GX, CX */
-#define DRAMx4			0
-#define VRAMx16			1
-#define VRAMx16ssr		2
-#define DRAMx16			3
-#define GraphicsDRAMx16		4
-#define EnhancedVRAMx16		5
-#define EnhancedVRAMx16ssr	6
-
-/* Memory types for CT, ET, VT, GT */
-#define DRAM			1
-#define EDO			2
-#define PSEUDO_EDO		3
-#define SDRAM			4
-#define SGRAM			5
-#define WRAM			6
-
-#define DAC_INTERNAL		0x00
-#define DAC_IBMRGB514		0x01
-#define DAC_ATI68875		0x02
-#define DAC_TVP3026_A		0x72
-#define DAC_BT476		0x03
-#define DAC_BT481		0x04
-#define DAC_ATT20C491		0x14
-#define DAC_SC15026		0x24
-#define DAC_MU9C1880		0x34
-#define DAC_IMSG174		0x44
-#define DAC_ATI68860_B		0x05
-#define DAC_ATI68860_C		0x15
-#define DAC_TVP3026_B		0x75
-#define DAC_STG1700		0x06
-#define DAC_ATT498		0x16
-#define DAC_STG1702		0x07
-#define DAC_SC15021		0x17
-#define DAC_ATT21C498		0x27
-#define DAC_STG1703		0x37
-#define DAC_CH8398		0x47
-#define DAC_ATT20C408		0x57
-
-#define CLK_ATI18818_0		0
-#define CLK_ATI18818_1		1
-#define CLK_STG1703		2
-#define CLK_CH8398		3
-#define CLK_INTERNAL		4
-#define CLK_ATT20C408		5
-#define CLK_IBMRGB514		6
-
-/* MEM_CNTL register constants */
-#define MEM_SIZE_ALIAS		0x00000007
-#define MEM_SIZE_512K		0x00000000
-#define MEM_SIZE_1M		0x00000001
-#define MEM_SIZE_2M		0x00000002
-#define MEM_SIZE_4M		0x00000003
-#define MEM_SIZE_6M		0x00000004
-#define MEM_SIZE_8M		0x00000005
-#define MEM_SIZE_ALIAS_GTB	0x0000000F
-#define MEM_SIZE_2M_GTB		0x00000003
-#define MEM_SIZE_4M_GTB		0x00000007
-#define MEM_SIZE_6M_GTB		0x00000009
-#define MEM_SIZE_8M_GTB		0x0000000B
-#define MEM_BNDRY		0x00030000
-#define MEM_BNDRY_0K		0x00000000
-#define MEM_BNDRY_256K		0x00010000
-#define MEM_BNDRY_512K		0x00020000
-#define MEM_BNDRY_1M		0x00030000
-#define MEM_BNDRY_EN		0x00040000
-
-/* ATI PCI constants */
-#define PCI_ATI_VENDOR_ID	0x1002
-
-
-/* CONFIG_CHIP_ID register constants */
-#define CFG_CHIP_TYPE		0x0000FFFF
-#define CFG_CHIP_CLASS		0x00FF0000
-#define CFG_CHIP_REV		0xFF000000
-#define CFG_CHIP_MAJOR		0x07000000
-#define CFG_CHIP_FND_ID		0x38000000
-#define CFG_CHIP_MINOR		0xC0000000
-
-
-/* Chip IDs read from CONFIG_CHIP_ID */
-
-/* mach64GX family */
-#define GX_CHIP_ID	0xD7	/* mach64GX (ATI888GX00) */
-#define CX_CHIP_ID	0x57	/* mach64CX (ATI888CX00) */
-
-#define GX_PCI_ID	0x4758	/* mach64GX (ATI888GX00) */
-#define CX_PCI_ID	0x4358	/* mach64CX (ATI888CX00) */
-
-/* mach64CT family */
-#define CT_CHIP_ID	0x4354	/* mach64CT (ATI264CT) */
-#define ET_CHIP_ID	0x4554	/* mach64ET (ATI264ET) */
-
-/* mach64CT family / mach64VT class */
-#define VT_CHIP_ID	0x5654	/* mach64VT (ATI264VT) */
-#define VU_CHIP_ID	0x5655	/* mach64VTB (ATI264VTB) */
-#define VV_CHIP_ID	0x5656	/* mach64VT4 (ATI264VT4) */
-
-/* mach64CT family / mach64GT (3D RAGE) class */
-#define LB_CHIP_ID	0x4c42	/* RAGE LT PRO, AGP */
-#define LD_CHIP_ID	0x4c44	/* RAGE LT PRO */
-#define LG_CHIP_ID	0x4c47	/* RAGE LT */
-#define LI_CHIP_ID	0x4c49	/* RAGE LT PRO */
-#define LP_CHIP_ID	0x4c50	/* RAGE LT PRO */
-#define LT_CHIP_ID	0x4c54	/* RAGE LT */
-#define XL_CHIP_ID	0x4752	/* RAGE (XL) */
-#define GT_CHIP_ID	0x4754	/* RAGE (GT) */
-#define GU_CHIP_ID	0x4755	/* RAGE II/II+ (GTB) */
-#define GV_CHIP_ID	0x4756	/* RAGE IIC, PCI */
-#define GW_CHIP_ID	0x4757	/* RAGE IIC, AGP */
-#define GZ_CHIP_ID	0x475a	/* RAGE IIC, AGP */
-#define GB_CHIP_ID	0x4742	/* RAGE PRO, BGA, AGP 1x and 2x */
-#define GD_CHIP_ID	0x4744	/* RAGE PRO, BGA, AGP 1x only */
-#define GI_CHIP_ID	0x4749	/* RAGE PRO, BGA, PCI33 only */
-#define GP_CHIP_ID	0x4750	/* RAGE PRO, PQFP, PCI33, full 3D */
-#define GQ_CHIP_ID	0x4751	/* RAGE PRO, PQFP, PCI33, limited 3D */
-#define LM_CHIP_ID	0x4c4d	/* RAGE Mobility PCI */
-#define LN_CHIP_ID	0x4c4e	/* RAGE Mobility AGP */
-
-
-/* Mach64 major ASIC revisions */
-#define MACH64_ASIC_NEC_VT_A3		0x08
-#define MACH64_ASIC_NEC_VT_A4		0x48
-#define MACH64_ASIC_SGS_VT_A4		0x40
-#define MACH64_ASIC_SGS_VT_B1S1		0x01
-#define MACH64_ASIC_SGS_GT_B1S1		0x01
-#define MACH64_ASIC_SGS_GT_B1S2		0x41
-#define MACH64_ASIC_UMC_GT_B2U1		0x1a
-#define MACH64_ASIC_UMC_GT_B2U2		0x5a
-#define MACH64_ASIC_UMC_VT_B2U3		0x9a
-#define MACH64_ASIC_UMC_GT_B2U3		0x9a
-#define MACH64_ASIC_UMC_R3B_D_P_A1	0x1b
-#define MACH64_ASIC_UMC_R3B_D_P_A2	0x5b
-#define MACH64_ASIC_UMC_R3B_D_P_A3	0x1c
-#define MACH64_ASIC_UMC_R3B_D_P_A4	0x5c
-
-/* Mach64 foundries */
-#define MACH64_FND_SGS		0
-#define MACH64_FND_NEC		1
-#define MACH64_FND_UMC		3
-
-/* Mach64 chip types */
-#define MACH64_UNKNOWN		0
-#define MACH64_GX		1
-#define MACH64_CX		2
-#define MACH64_CT		3
-#define MACH64_ET		4
-#define MACH64_VT		5
-#define MACH64_GT		6
-
-/* DST_CNTL register constants */
-#define DST_X_RIGHT_TO_LEFT	0
-#define DST_X_LEFT_TO_RIGHT	1
-#define DST_Y_BOTTOM_TO_TOP	0
-#define DST_Y_TOP_TO_BOTTOM	2
-#define DST_X_MAJOR		0
-#define DST_Y_MAJOR		4
-#define DST_X_TILE		8
-#define DST_Y_TILE		0x10
-#define DST_LAST_PEL		0x20
-#define DST_POLYGON_ENABLE	0x40
-#define DST_24_ROTATION_ENABLE	0x80
-
-/* SRC_CNTL register constants */
-#define SRC_PATTERN_ENABLE		1
-#define SRC_ROTATION_ENABLE		2
-#define SRC_LINEAR_ENABLE		4
-#define SRC_BYTE_ALIGN			8
-#define SRC_LINE_X_RIGHT_TO_LEFT	0
-#define SRC_LINE_X_LEFT_TO_RIGHT	0x10
-
-/* HOST_CNTL register constants */
-#define HOST_BYTE_ALIGN		1
-
-/* GUI_TRAJ_CNTL register constants */
-#define PAT_MONO_8x8_ENABLE	0x01000000
-#define PAT_CLR_4x2_ENABLE	0x02000000
-#define PAT_CLR_8x1_ENABLE	0x04000000
-
-/* DP_CHAIN_MASK register constants */
-#define DP_CHAIN_4BPP		0x8888
-#define DP_CHAIN_7BPP		0xD2D2
-#define DP_CHAIN_8BPP		0x8080
-#define DP_CHAIN_8BPP_RGB	0x9292
-#define DP_CHAIN_15BPP		0x4210
-#define DP_CHAIN_16BPP		0x8410
-#define DP_CHAIN_24BPP		0x8080
-#define DP_CHAIN_32BPP		0x8080
-
-/* DP_PIX_WIDTH register constants */
-#define DST_1BPP		0
-#define DST_4BPP		1
-#define DST_8BPP		2
-#define DST_15BPP		3
-#define DST_16BPP		4
-#define DST_32BPP		6
-#define SRC_1BPP		0
-#define SRC_4BPP		0x100
-#define SRC_8BPP		0x200
-#define SRC_15BPP		0x300
-#define SRC_16BPP		0x400
-#define SRC_32BPP		0x600
-#define HOST_1BPP		0
-#define HOST_4BPP		0x10000
-#define HOST_8BPP		0x20000
-#define HOST_15BPP		0x30000
-#define HOST_16BPP		0x40000
-#define HOST_32BPP		0x60000
-#define BYTE_ORDER_MSB_TO_LSB	0
-#define BYTE_ORDER_LSB_TO_MSB	0x1000000
-
-/* DP_MIX register constants */
-#define BKGD_MIX_NOT_D			0
-#define BKGD_MIX_ZERO			1
-#define BKGD_MIX_ONE			2
-#define BKGD_MIX_D			3
-#define BKGD_MIX_NOT_S			4
-#define BKGD_MIX_D_XOR_S		5
-#define BKGD_MIX_NOT_D_XOR_S		6
-#define BKGD_MIX_S			7
-#define BKGD_MIX_NOT_D_OR_NOT_S		8
-#define BKGD_MIX_D_OR_NOT_S		9
-#define BKGD_MIX_NOT_D_OR_S		10
-#define BKGD_MIX_D_OR_S			11
-#define BKGD_MIX_D_AND_S		12
-#define BKGD_MIX_NOT_D_AND_S		13
-#define BKGD_MIX_D_AND_NOT_S		14
-#define BKGD_MIX_NOT_D_AND_NOT_S	15
-#define BKGD_MIX_D_PLUS_S_DIV2		0x17
-#define FRGD_MIX_NOT_D			0
-#define FRGD_MIX_ZERO			0x10000
-#define FRGD_MIX_ONE			0x20000
-#define FRGD_MIX_D			0x30000
-#define FRGD_MIX_NOT_S			0x40000
-#define FRGD_MIX_D_XOR_S		0x50000
-#define FRGD_MIX_NOT_D_XOR_S		0x60000
-#define FRGD_MIX_S			0x70000
-#define FRGD_MIX_NOT_D_OR_NOT_S		0x80000
-#define FRGD_MIX_D_OR_NOT_S		0x90000
-#define FRGD_MIX_NOT_D_OR_S		0xa0000
-#define FRGD_MIX_D_OR_S			0xb0000
-#define FRGD_MIX_D_AND_S		0xc0000
-#define FRGD_MIX_NOT_D_AND_S		0xd0000
-#define FRGD_MIX_D_AND_NOT_S		0xe0000
-#define FRGD_MIX_NOT_D_AND_NOT_S	0xf0000
-#define FRGD_MIX_D_PLUS_S_DIV2		0x170000
-
-/* DP_SRC register constants */
-#define BKGD_SRC_BKGD_CLR	0
-#define BKGD_SRC_FRGD_CLR	1
-#define BKGD_SRC_HOST		2
-#define BKGD_SRC_BLIT		3
-#define BKGD_SRC_PATTERN	4
-#define FRGD_SRC_BKGD_CLR	0
-#define FRGD_SRC_FRGD_CLR	0x100
-#define FRGD_SRC_HOST		0x200
-#define FRGD_SRC_BLIT		0x300
-#define FRGD_SRC_PATTERN	0x400
-#define MONO_SRC_ONE		0
-#define MONO_SRC_PATTERN	0x10000
-#define MONO_SRC_HOST		0x20000
-#define MONO_SRC_BLIT		0x30000
-
-/* CLR_CMP_CNTL register constants */
-#define COMPARE_FALSE		0
-#define COMPARE_TRUE		1
-#define COMPARE_NOT_EQUAL	4
-#define COMPARE_EQUAL		5
-#define COMPARE_DESTINATION	0
-#define COMPARE_SOURCE		0x1000000
-
-/* FIFO_STAT register constants */
-#define FIFO_ERR		0x80000000
-
-/* CONTEXT_LOAD_CNTL constants */
-#define CONTEXT_NO_LOAD			0
-#define CONTEXT_LOAD			0x10000
-#define CONTEXT_LOAD_AND_DO_FILL	0x20000
-#define CONTEXT_LOAD_AND_DO_LINE	0x30000
-#define CONTEXT_EXECUTE			0
-#define CONTEXT_CMD_DISABLE		0x80000000
-
-/* GUI_STAT register constants */
-#define ENGINE_IDLE		0
-#define ENGINE_BUSY		1
-#define SCISSOR_LEFT_FLAG	0x10
-#define SCISSOR_RIGHT_FLAG	0x20
-#define SCISSOR_TOP_FLAG	0x40
-#define SCISSOR_BOTTOM_FLAG	0x80
-
-/* ATI VGA Extended Regsiters */
-#define sioATIEXT		0x1ce
-#define bioATIEXT		0x3ce
-
-#define ATI2E			0xae
-#define ATI32			0xb2
-#define ATI36			0xb6
-
-/* VGA Graphics Controller Registers */
-#define VGAGRA			0x3ce
-#define GRA06			0x06
-
-/* VGA Seququencer Registers */
-#define VGASEQ			0x3c4
-#define SEQ02			0x02
-#define SEQ04			0x04
-
-#define MACH64_MAX_X		ENGINE_MAX_X
-#define MACH64_MAX_Y		ENGINE_MAX_Y
-
-#define INC_X			0x0020
-#define INC_Y			0x0080
-
-#define RGB16_555		0x0000
-#define RGB16_565		0x0040
-#define RGB16_655		0x0080
-#define RGB16_664		0x00c0
-
-#define POLY_TEXT_TYPE		0x0001
-#define IMAGE_TEXT_TYPE		0x0002
-#define TEXT_TYPE_8_BIT		0x0004
-#define TEXT_TYPE_16_BIT	0x0008
-#define POLY_TEXT_TYPE_8	(POLY_TEXT_TYPE | TEXT_TYPE_8_BIT)
-#define IMAGE_TEXT_TYPE_8	(IMAGE_TEXT_TYPE | TEXT_TYPE_8_BIT)
-#define POLY_TEXT_TYPE_16	(POLY_TEXT_TYPE | TEXT_TYPE_16_BIT)
-#define IMAGE_TEXT_TYPE_16	(IMAGE_TEXT_TYPE | TEXT_TYPE_16_BIT)
-
-#define MACH64_NUM_CLOCKS	16
-#define MACH64_NUM_FREQS	50
-
-/* Power Management register constants (LT & LT Pro) */
-#define PWR_MGT_ON		0x00000001
-#define PWR_MGT_MODE_MASK	0x00000006
-#define AUTO_PWR_UP		0x00000008
-#define USE_F32KHZ		0x00000400
-#define TRISTATE_MEM_EN		0x00000800
-#define SELF_REFRESH		0x00000080
-#define PWR_BLON		0x02000000
-#define STANDBY_NOW		0x10000000
-#define SUSPEND_NOW		0x20000000
-#define PWR_MGT_STATUS_MASK	0xC0000000
-#define PWR_MGT_STATUS_SUSPEND	0x80000000
-
-/* PM Mode constants  */
-#define PWR_MGT_MODE_PIN	0x00000000
-#define PWR_MGT_MODE_REG	0x00000002
-#define PWR_MGT_MODE_TIMER	0x00000004
-#define PWR_MGT_MODE_PCI	0x00000006
-
-/* LCD registers (LT Pro) */
-
-/* LCD Index register */
-#define LCD_INDEX_MASK		0x0000003F
-#define LCD_DISPLAY_DIS		0x00000100
-#define LCD_SRC_SEL		0x00000200
-#define CRTC2_DISPLAY_DIS	0x00000400
-
-/* LCD register indices */
-#define CONFIG_PANEL		0x00
-#define LCD_GEN_CTRL		0x01
-#define DSTN_CONTROL		0x02
-#define HFB_PITCH_ADDR		0x03
-#define HORZ_STRETCHING		0x04
-#define VERT_STRETCHING		0x05
-#define EXT_VERT_STRETCH	0x06
-#define LT_GIO			0x07
-#define POWER_MANAGEMENT	0x08
-#define ZVGPIO			0x09
-#define ICON_CLR0		0x0A
-#define ICON_CLR1		0x0B
-#define ICON_OFFSET		0x0C
-#define ICON_HORZ_VERT_POSN	0x0D
-#define ICON_HORZ_VERT_OFF	0x0E
-#define ICON2_CLR0		0x0F
-#define ICON2_CLR1		0x10
-#define ICON2_OFFSET		0x11
-#define ICON2_HORZ_VERT_POSN	0x12
-#define ICON2_HORZ_VERT_OFF	0x13
-#define LCD_MISC_CNTL		0x14
-#define APC_CNTL		0x1C
-#define POWER_MANAGEMENT_2	0x1D
-#define ALPHA_BLENDING		0x25
-#define PORTRAIT_GEN_CNTL	0x26
-#define APC_CTRL_IO		0x27
-#define TEST_IO			0x28
-#define TEST_OUTPUTS		0x29
-#define DP1_MEM_ACCESS		0x2A
-#define DP0_MEM_ACCESS		0x2B
-#define DP0_DEBUG_A		0x2C
-#define DP0_DEBUG_B		0x2D
-#define DP1_DEBUG_A		0x2E
-#define DP1_DEBUG_B		0x2F
-#define DPCTRL_DEBUG_A		0x30
-#define DPCTRL_DEBUG_B		0x31
-#define MEMBLK_DEBUG		0x32
-#define APC_LUT_AB		0x33
-#define APC_LUT_CD		0x34
-#define APC_LUT_EF		0x35
-#define APC_LUT_GH		0x36
-#define APC_LUT_IJ		0x37
-#define APC_LUT_KL		0x38
-#define APC_LUT_MN		0x39
-#define APC_LUT_OP		0x3A
-
-
-/* Values in LCD_MISC_CNTL */
-#define BIAS_MOD_LEVEL_MASK	0x0000ff00
-#define BIAS_MOD_LEVEL_SHIFT	8
-#define BLMOD_EN		0x00010000
-#define BIASMOD_EN		0x00020000
-
-#endif /* REGMACH64_H */
diff -Nru a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c
--- a/drivers/video/aty/mach64_accel.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/video/aty/mach64_accel.c	Wed Jul 24 14:03:35 2002
@@ -13,294 +13,306 @@
 #include <video/fbcon-cfb24.h>
 #include <video/fbcon-cfb32.h>
 
-#include "mach64.h"
+#include <video/mach64.h>
 #include "atyfb.h"
 
     /*
      *  Text console acceleration
      */
 
-static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			    int height, int width);
-static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy,
-			    int sx, int height, int width);
+static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy,
+			    int dx, int height, int width);
+static void fbcon_aty_clear(struct vc_data *conp, struct display *p,
+			    int sy, int sx, int height, int width);
 
 
     /*
      *  Generic Mach64 routines
      */
 
-void aty_reset_engine(const struct fb_info_aty *info)
+void aty_reset_engine(const struct atyfb_par *par)
 {
-    /* reset engine */
-    aty_st_le32(GEN_TEST_CNTL,
-		aty_ld_le32(GEN_TEST_CNTL, info) & ~GUI_ENGINE_ENABLE, info);
-    /* enable engine */
-    aty_st_le32(GEN_TEST_CNTL,
-		aty_ld_le32(GEN_TEST_CNTL, info) | GUI_ENGINE_ENABLE, info);
-    /* ensure engine is not locked up by clearing any FIFO or */
-    /* HOST errors */
-    aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, info) | BUS_HOST_ERR_ACK |
-			  BUS_FIFO_ERR_ACK, info);
+	/* reset engine */
+	aty_st_le32(GEN_TEST_CNTL,
+		    aty_ld_le32(GEN_TEST_CNTL, par) & ~GUI_ENGINE_ENABLE,
+		    par);
+	/* enable engine */
+	aty_st_le32(GEN_TEST_CNTL,
+		    aty_ld_le32(GEN_TEST_CNTL, par) | GUI_ENGINE_ENABLE,
+		    par);
+	/* ensure engine is not locked up by clearing any FIFO or */
+	/* HOST errors */
+	aty_st_le32(BUS_CNTL,
+		    aty_ld_le32(BUS_CNTL,
+				par) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK,
+		    par);
 }
 
-static void reset_GTC_3D_engine(const struct fb_info_aty *info)
+static void reset_GTC_3D_engine(const struct atyfb_par *par)
 {
-	aty_st_le32(SCALE_3D_CNTL, 0xc0, info);
+	aty_st_le32(SCALE_3D_CNTL, 0xc0, par);
 	mdelay(GTC_3D_RESET_DELAY);
-	aty_st_le32(SETUP_CNTL, 0x00, info);
+	aty_st_le32(SETUP_CNTL, 0x00, par);
 	mdelay(GTC_3D_RESET_DELAY);
-	aty_st_le32(SCALE_3D_CNTL, 0x00, info);
+	aty_st_le32(SCALE_3D_CNTL, 0x00, par);
 	mdelay(GTC_3D_RESET_DELAY);
 }
 
-void aty_init_engine(const struct atyfb_par *par, struct fb_info_aty *info)
+void aty_init_engine(struct atyfb_par *par, struct fb_info *info)
 {
-    u32 pitch_value;
+	u32 pitch_value;
 
-    /* determine modal information from global mode structure */
-    pitch_value = par->crtc.vxres;
+	/* determine modal information from global mode structure */
+	pitch_value = par->crtc.vxres;
 
-    if (par->crtc.bpp == 24) {
-	/* In 24 bpp, the engine is in 8 bpp - this requires that all */
-	/* horizontal coordinates and widths must be adjusted */
-	pitch_value = pitch_value * 3;
-    }
-
-    /* On GTC (RagePro), we need to reset the 3D engine before */
-    if (M64_HAS(RESET_3D))
-    	reset_GTC_3D_engine(info);
-
-    /* Reset engine, enable, and clear any engine errors */
-    aty_reset_engine(info);
-    /* Ensure that vga page pointers are set to zero - the upper */
-    /* page pointers are set to 1 to handle overflows in the */
-    /* lower page */
-    aty_st_le32(MEM_VGA_WP_SEL, 0x00010000, info);
-    aty_st_le32(MEM_VGA_RP_SEL, 0x00010000, info);
-
-    /* ---- Setup standard engine context ---- */
-
-    /* All GUI registers here are FIFOed - therefore, wait for */
-    /* the appropriate number of empty FIFO entries */
-    wait_for_fifo(14, info);
-
-    /* enable all registers to be loaded for context loads */
-    aty_st_le32(CONTEXT_MASK, 0xFFFFFFFF, info);
-
-    /* set destination pitch to modal pitch, set offset to zero */
-    aty_st_le32(DST_OFF_PITCH, (pitch_value / 8) << 22, info);
-
-    /* zero these registers (set them to a known state) */
-    aty_st_le32(DST_Y_X, 0, info);
-    aty_st_le32(DST_HEIGHT, 0, info);
-    aty_st_le32(DST_BRES_ERR, 0, info);
-    aty_st_le32(DST_BRES_INC, 0, info);
-    aty_st_le32(DST_BRES_DEC, 0, info);
-
-    /* set destination drawing attributes */
-    aty_st_le32(DST_CNTL, DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
-			  DST_X_LEFT_TO_RIGHT, info);
-
-    /* set source pitch to modal pitch, set offset to zero */
-    aty_st_le32(SRC_OFF_PITCH, (pitch_value / 8) << 22, info);
-
-    /* set these registers to a known state */
-    aty_st_le32(SRC_Y_X, 0, info);
-    aty_st_le32(SRC_HEIGHT1_WIDTH1, 1, info);
-    aty_st_le32(SRC_Y_X_START, 0, info);
-    aty_st_le32(SRC_HEIGHT2_WIDTH2, 1, info);
-
-    /* set source pixel retrieving attributes */
-    aty_st_le32(SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT, info);
-
-    /* set host attributes */
-    wait_for_fifo(13, info);
-    aty_st_le32(HOST_CNTL, 0, info);
-
-    /* set pattern attributes */
-    aty_st_le32(PAT_REG0, 0, info);
-    aty_st_le32(PAT_REG1, 0, info);
-    aty_st_le32(PAT_CNTL, 0, info);
-
-    /* set scissors to modal size */
-    aty_st_le32(SC_LEFT, 0, info);
-    aty_st_le32(SC_TOP, 0, info);
-    aty_st_le32(SC_BOTTOM, par->crtc.vyres-1, info);
-    aty_st_le32(SC_RIGHT, pitch_value-1, info);
-
-    /* set background color to minimum value (usually BLACK) */
-    aty_st_le32(DP_BKGD_CLR, 0, info);
-
-    /* set foreground color to maximum value (usually WHITE) */
-    aty_st_le32(DP_FRGD_CLR, 0xFFFFFFFF, info);
-
-    /* set write mask to effect all pixel bits */
-    aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, info);
-
-    /* set foreground mix to overpaint and background mix to */
-    /* no-effect */
-    aty_st_le32(DP_MIX, FRGD_MIX_S | BKGD_MIX_D, info);
-
-    /* set primary source pixel channel to foreground color */
-    /* register */
-    aty_st_le32(DP_SRC, FRGD_SRC_FRGD_CLR, info);
-
-    /* set compare functionality to false (no-effect on */
-    /* destination) */
-    wait_for_fifo(3, info);
-    aty_st_le32(CLR_CMP_CLR, 0, info);
-    aty_st_le32(CLR_CMP_MASK, 0xFFFFFFFF, info);
-    aty_st_le32(CLR_CMP_CNTL, 0, info);
-
-    /* set pixel depth */
-    wait_for_fifo(2, info);
-    aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, info);
-    aty_st_le32(DP_CHAIN_MASK, par->crtc.dp_chain_mask, info);
-
-    wait_for_fifo(5, info);
-    aty_st_le32(SCALE_3D_CNTL, 0, info);
-    aty_st_le32(Z_CNTL, 0, info);
-    aty_st_le32(CRTC_INT_CNTL, aty_ld_le32(CRTC_INT_CNTL, info) & ~0x20, info);
-    aty_st_le32(GUI_TRAJ_CNTL, 0x100023, info);
+	if (par->crtc.bpp == 24) {
+		/* In 24 bpp, the engine is in 8 bpp - this requires that all */
+		/* horizontal coordinates and widths must be adjusted */
+		pitch_value = pitch_value * 3;
+	}
+
+	/* On GTC (RagePro), we need to reset the 3D engine before */
+	if (M64_HAS(RESET_3D))
+		reset_GTC_3D_engine(par);
+
+	/* Reset engine, enable, and clear any engine errors */
+	aty_reset_engine(par);
+	/* Ensure that vga page pointers are set to zero - the upper */
+	/* page pointers are set to 1 to handle overflows in the */
+	/* lower page */
+	aty_st_le32(MEM_VGA_WP_SEL, 0x00010000, par);
+	aty_st_le32(MEM_VGA_RP_SEL, 0x00010000, par);
+
+	/* ---- Setup standard engine context ---- */
+
+	/* All GUI registers here are FIFOed - therefore, wait for */
+	/* the appropriate number of empty FIFO entries */
+	wait_for_fifo(14, par);
+
+	/* enable all registers to be loaded for context loads */
+	aty_st_le32(CONTEXT_MASK, 0xFFFFFFFF, par);
+
+	/* set destination pitch to modal pitch, set offset to zero */
+	aty_st_le32(DST_OFF_PITCH, (pitch_value / 8) << 22, par);
+
+	/* zero these registers (set them to a known state) */
+	aty_st_le32(DST_Y_X, 0, par);
+	aty_st_le32(DST_HEIGHT, 0, par);
+	aty_st_le32(DST_BRES_ERR, 0, par);
+	aty_st_le32(DST_BRES_INC, 0, par);
+	aty_st_le32(DST_BRES_DEC, 0, par);
+
+	/* set destination drawing attributes */
+	aty_st_le32(DST_CNTL, DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
+		    DST_X_LEFT_TO_RIGHT, par);
+
+	/* set source pitch to modal pitch, set offset to zero */
+	aty_st_le32(SRC_OFF_PITCH, (pitch_value / 8) << 22, par);
+
+	/* set these registers to a known state */
+	aty_st_le32(SRC_Y_X, 0, par);
+	aty_st_le32(SRC_HEIGHT1_WIDTH1, 1, par);
+	aty_st_le32(SRC_Y_X_START, 0, par);
+	aty_st_le32(SRC_HEIGHT2_WIDTH2, 1, par);
+
+	/* set source pixel retrieving attributes */
+	aty_st_le32(SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT, par);
+
+	/* set host attributes */
+	wait_for_fifo(13, par);
+	aty_st_le32(HOST_CNTL, 0, par);
+
+	/* set pattern attributes */
+	aty_st_le32(PAT_REG0, 0, par);
+	aty_st_le32(PAT_REG1, 0, par);
+	aty_st_le32(PAT_CNTL, 0, par);
+
+	/* set scissors to modal size */
+	aty_st_le32(SC_LEFT, 0, par);
+	aty_st_le32(SC_TOP, 0, par);
+	aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par);
+	aty_st_le32(SC_RIGHT, pitch_value - 1, par);
+
+	/* set background color to minimum value (usually BLACK) */
+	aty_st_le32(DP_BKGD_CLR, 0, par);
+
+	/* set foreground color to maximum value (usually WHITE) */
+	aty_st_le32(DP_FRGD_CLR, 0xFFFFFFFF, par);
+
+	/* set write mask to effect all pixel bits */
+	aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, par);
+
+	/* set foreground mix to overpaint and background mix to */
+	/* no-effect */
+	aty_st_le32(DP_MIX, FRGD_MIX_S | BKGD_MIX_D, par);
+
+	/* set primary source pixel channel to foreground color */
+	/* register */
+	aty_st_le32(DP_SRC, FRGD_SRC_FRGD_CLR, par);
+
+	/* set compare functionality to false (no-effect on */
+	/* destination) */
+	wait_for_fifo(3, par);
+	aty_st_le32(CLR_CMP_CLR, 0, par);
+	aty_st_le32(CLR_CMP_MASK, 0xFFFFFFFF, par);
+	aty_st_le32(CLR_CMP_CNTL, 0, par);
+
+	/* set pixel depth */
+	wait_for_fifo(2, par);
+	aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, par);
+	aty_st_le32(DP_CHAIN_MASK, par->crtc.dp_chain_mask, par);
+
+	wait_for_fifo(5, par);
+	aty_st_le32(SCALE_3D_CNTL, 0, par);
+	aty_st_le32(Z_CNTL, 0, par);
+	aty_st_le32(CRTC_INT_CNTL, aty_ld_le32(CRTC_INT_CNTL, par) & ~0x20,
+		    par);
+	aty_st_le32(GUI_TRAJ_CNTL, 0x100023, par);
 
-    /* insure engine is idle before leaving */
-    wait_for_idle(info);
+	/* insure engine is idle before leaving */
+	wait_for_idle(par);
 }
 
-
     /*
      *  Accelerated functions
      */
 
 static inline void draw_rect(s16 x, s16 y, u16 width, u16 height,
-			     struct fb_info_aty *info)
+			     struct atyfb_par *par)
 {
-    /* perform rectangle fill */
-    wait_for_fifo(2, info);
-    aty_st_le32(DST_Y_X, (x << 16) | y, info);
-    aty_st_le32(DST_HEIGHT_WIDTH, (width << 16) | height, info);
-    info->blitter_may_be_busy = 1;
+	/* perform rectangle fill */
+	wait_for_fifo(2, par);
+	aty_st_le32(DST_Y_X, (x << 16) | y, par);
+	aty_st_le32(DST_HEIGHT_WIDTH, (width << 16) | height, par);
+	par->blitter_may_be_busy = 1;
 }
 
-static inline void aty_rectcopy(int srcx, int srcy, int dstx, int dsty,
-				u_int width, u_int height,
-				struct fb_info_aty *info)
+static void atyfb_copyarea(struct fb_info *info, struct fb_copyarea *area)
 {
-    u32 direction = DST_LAST_PEL;
-    u32 pitch_value;
-
-    if (!width || !height)
-	return;
-
-    pitch_value = info->current_par.crtc.vxres;
-    if (info->current_par.crtc.bpp == 24) {
-	/* In 24 bpp, the engine is in 8 bpp - this requires that all */
-	/* horizontal coordinates and widths must be adjusted */
-	pitch_value *= 3;
-	srcx *= 3;
-	dstx *= 3;
-	width *= 3;
-    }
-
-    if (srcy < dsty) {
-	dsty += height - 1;
-	srcy += height - 1;
-    } else
-	direction |= DST_Y_TOP_TO_BOTTOM;
-
-    if (srcx < dstx) {
-	dstx += width - 1;
-	srcx += width - 1;
-    } else
-	direction |= DST_X_LEFT_TO_RIGHT;
-
-    wait_for_fifo(4, info);
-    aty_st_le32(DP_SRC, FRGD_SRC_BLIT, info);
-    aty_st_le32(SRC_Y_X, (srcx << 16) | srcy, info);
-    aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | height, info);
-    aty_st_le32(DST_CNTL, direction, info);
-    draw_rect(dstx, dsty, width, height, info);
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	
+	u32 direction = DST_LAST_PEL;
+	u32 pitch_value;
+
+	if (!area->width || !area->height)
+		return;
+
+	pitch_value = par->crtc.vxres;
+	if (par->crtc.bpp == 24) {
+		/* In 24 bpp, the engine is in 8 bpp - this requires that all */
+		/* horizontal coordinates and widths must be adjusted */
+		pitch_value *= 3;
+		area->sx *= 3;
+		area->dx *= 3;
+		area->width *= 3;
+	}
+
+	if (area->sy < area->dy) {
+		area->dy += area->height - 1;
+		area->sy += area->height - 1;
+	} else
+		direction |= DST_Y_TOP_TO_BOTTOM;
+
+	if (area->sx < area->dx) {
+		area->dx += area->width - 1;
+		area->sx += area->width - 1;
+	} else
+		direction |= DST_X_LEFT_TO_RIGHT;
+
+	wait_for_fifo(4, par);
+	aty_st_le32(DP_SRC, FRGD_SRC_BLIT, par);
+	aty_st_le32(SRC_Y_X, (area->sx << 16) | area->sy, par);
+	aty_st_le32(SRC_HEIGHT1_WIDTH1, (area->width << 16) | area->height,par);
+	aty_st_le32(DST_CNTL, direction, par);
+	draw_rect(area->dx, area->dy, area->width, area->height, par);
 }
 
-void aty_rectfill(int dstx, int dsty, u_int width, u_int height, u_int color,
-		  struct fb_info_aty *info)
+void atyfb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
 {
-    if (!width || !height)
-	return;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
 
-    if (info->current_par.crtc.bpp == 24) {
-	/* In 24 bpp, the engine is in 8 bpp - this requires that all */
-	/* horizontal coordinates and widths must be adjusted */
-	dstx *= 3;
-	width *= 3;
-    }
-
-    wait_for_fifo(3, info);
-    aty_st_le32(DP_FRGD_CLR, color, info);
-    aty_st_le32(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE,
-		info);
-    aty_st_le32(DST_CNTL, DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
-			  DST_X_LEFT_TO_RIGHT, info);
-    draw_rect(dstx, dsty, width, height, info);
-}
+	if (!rect->width || !rect->height)
+		return;
 
+	rect->color |= (rect->color << 8);
+	rect->color |= (rect->color << 16);
+
+	if (par->crtc.bpp == 24) {
+		/* In 24 bpp, the engine is in 8 bpp - this requires that all */
+		/* horizontal coordinates and widths must be adjusted */
+		rect->dx *= 3;
+		rect->width *= 3;
+	}
+
+	wait_for_fifo(3, par);
+	aty_st_le32(DP_FRGD_CLR, rect->color, par);
+	aty_st_le32(DP_SRC,
+		    BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE,
+		    par);
+	aty_st_le32(DST_CNTL,
+		    DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
+		    DST_X_LEFT_TO_RIGHT, par);
+	draw_rect(rect->dx, rect->dy, rect->width, rect->height, par);
+}
 
     /*
      *  Text console acceleration
      */
 
-static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			    int height, int width)
+static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy,
+			    int dx, int height, int width)
 {
+	struct fb_info *info = p->fb_info;
+	struct fb_copyarea area;
 #ifdef __sparc__
-    struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+	struct atyfb_par *par = (struct atyfb_par *) (info->par);
 
-    if (fb->mmaped && (!fb->fb_info.display_fg
-	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
-	return;
+	if (par->mmaped && (!info->display_fg
+			   || info->display_fg->vc_num ==
+			   par->vtconsole))
+		return;
 #endif
 
-    sx *= fontwidth(p);
-    sy *= fontheight(p);
-    dx *= fontwidth(p);
-    dy *= fontheight(p);
-    width *= fontwidth(p);
-    height *= fontheight(p);
+	area.sx = sx * fontwidth(p);
+	area.sy = sy * fontheight(p);
+	area.dx = dx * fontwidth(p);
+	area.dy = dy * fontheight(p);
+	area.width  = width * fontwidth(p);
+	area.height = height * fontheight(p);
 
-    aty_rectcopy(sx, sy, dx, dy, width, height,
-		 (struct fb_info_aty *)p->fb_info);
+	atyfb_copyarea(info, &area); 
 }
 
-static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy,
-			    int sx, int height, int width)
+static void fbcon_aty_clear(struct vc_data *conp, struct display *p,
+			    int sy, int sx, int height, int width)
 {
-    u32 bgx;
+	struct fb_info *info = p->fb_info;
+	struct fb_fillrect region;
 #ifdef __sparc__
-    struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+	struct atyfb_par *par = (struct atyfb_par *) (info->par);
 
-    if (fb->mmaped && (!fb->fb_info.display_fg
-	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
-	return;
+	if (par->mmaped && (!info->display_fg
+			   || info->display_fg->vc_num ==
+			   par->vtconsole))
+		return;
 #endif
+	region.color = attr_bgcol_ec(p, conp);
+	region.color |= (region.color << 8);
+	region.color |= (region.color << 16);
+
+	region.dx = sx * fontwidth(p);
+	region.dy = sy * fontheight(p);
+	region.width = width * fontwidth(p);
+	region.height = height * fontheight(p);
+	region.rop = ROP_COPY;
 
-    bgx = attr_bgcol_ec(p, conp);
-    bgx |= (bgx << 8);
-    bgx |= (bgx << 16);
-
-    sx *= fontwidth(p);
-    sy *= fontheight(p);
-    width *= fontwidth(p);
-    height *= fontheight(p);
-
-    aty_rectfill(sx, sy, width, height, bgx,
-		 (struct fb_info_aty *)p->fb_info);
+	atyfb_fillrect(info, &region);
 }
 
 #ifdef __sparc__
 #define check_access \
-    if (fb->mmaped && (!fb->fb_info.display_fg \
-	|| fb->fb_info.display_fg->vc_num == fb->vtconsole)) \
+    if (par->mmaped && (!info->display_fg \
+	|| info->display_fg->vc_num == par->vtconsole)) \
 	return;
 #else
 #define check_access do { } while (0)
@@ -309,10 +321,11 @@
 #define DEF_FBCON_ATY_OP(name, call, args...) \
 static void name(struct vc_data *conp, struct display *p, args) \
 { \
-    struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); \
+    struct fb_info *info = p->fb_info; \
+    struct atyfb_par *par = (struct atyfb_par *) info->par; \
     check_access; \
-    if (fb->blitter_may_be_busy) \
-	wait_for_idle((struct fb_info_aty *)p->fb_info); \
+    if (par->blitter_may_be_busy) \
+	wait_for_idle(par); \
     call; \
 }
 
@@ -342,12 +355,11 @@
 DEF_FBCON_ATY(8)
 #endif
 #ifdef FBCON_HAS_CFB16
-DEF_FBCON_ATY(16)
+    DEF_FBCON_ATY(16)
 #endif
 #ifdef FBCON_HAS_CFB24
-DEF_FBCON_ATY(24)
+    DEF_FBCON_ATY(24)
 #endif
 #ifdef FBCON_HAS_CFB32
-DEF_FBCON_ATY(32)
+    DEF_FBCON_ATY(32)
 #endif
-
diff -Nru a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
--- a/drivers/video/aty/mach64_ct.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/video/aty/mach64_ct.c	Wed Jul 24 14:03:35 2002
@@ -9,33 +9,32 @@
 
 #include <video/fbcon.h>
 
-#include "mach64.h"
+#include <video/mach64.h>
 #include "atyfb.h"
 
 
 /* FIXME: remove the FAIL definition */
 #define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
 
-static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info);
-
-static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
+static void aty_st_pll(int offset, u8 val, const struct atyfb_par *par);
+static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per,
 			    struct pll_ct *pll);
-static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
+static int aty_dsp_gt(const struct fb_info *info, u8 bpp,
 		      struct pll_ct *pll);
-static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
+static int aty_var_to_pll_ct(const struct fb_info *info, u32 vclk_per,
 			     u8 bpp, union aty_pll *pll);
-static u32 aty_pll_ct_to_var(const struct fb_info_aty *info,
+static u32 aty_pll_ct_to_var(const struct fb_info *info,
 			     const union aty_pll *pll);
 
 
 
-static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info)
+static void aty_st_pll(int offset, u8 val, const struct atyfb_par *par)
 {
-    /* write addr byte */
-    aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, info);
-    /* write the register value */
-    aty_st_8(CLOCK_CNTL + 2, val, info);
-    aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);
+	/* write addr byte */
+	aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, par);
+	/* write the register value */
+	aty_st_8(CLOCK_CNTL + 2, val, par);
+	aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, par);
 }
 
 
@@ -45,228 +44,238 @@
      *  PLL programming (Mach64 CT family)
      */
 
-static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
+static int aty_dsp_gt(const struct fb_info *info, u8 bpp,
 		      struct pll_ct *pll)
 {
-    u32 dsp_xclks_per_row, dsp_loop_latency, dsp_precision, dsp_off, dsp_on;
-    u32 xclks_per_row, fifo_off, fifo_on, y, fifo_size, page_size;
-
-    /* xclocks_per_row<<11 */
-    xclks_per_row = (pll->mclk_fb_div*pll->vclk_post_div_real*64<<11)/
-		    (pll->vclk_fb_div*pll->mclk_post_div_real*bpp);
-    if (xclks_per_row < (1<<11))
-	FAIL("Dotclock to high");
-    if (M64_HAS(FIFO_24)) {
-	fifo_size = 24;
-	dsp_loop_latency = 0;
-    } else {
-	fifo_size = 32;
-	dsp_loop_latency = 2;
-    }
-    dsp_precision = 0;
-    y = (xclks_per_row*fifo_size)>>11;
-    while (y) {
-	y >>= 1;
-	dsp_precision++;
-    }
-    dsp_precision -= 5;
-    /* fifo_off<<6 */
-    fifo_off = ((xclks_per_row*(fifo_size-1))>>5)+(3<<6);
-
-    if (info->total_vram > 1*1024*1024) {
-	if (info->ram_type >= SDRAM) {
-	    /* >1 MB SDRAM */
-	    dsp_loop_latency += 8;
-	    page_size = 8;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 dsp_xclks_per_row, dsp_loop_latency, dsp_precision, dsp_off,
+	    dsp_on;
+	u32 xclks_per_row, fifo_off, fifo_on, y, fifo_size, page_size;
+
+	/* xclocks_per_row<<11 */
+	xclks_per_row =
+	    (pll->mclk_fb_div * pll->vclk_post_div_real * 64 << 11) /
+	    (pll->vclk_fb_div * pll->mclk_post_div_real * bpp);
+	if (xclks_per_row < (1 << 11))
+		FAIL("Dotclock to high");
+	if (M64_HAS(FIFO_24)) {
+		fifo_size = 24;
+		dsp_loop_latency = 0;
 	} else {
-	    /* >1 MB DRAM */
-	    dsp_loop_latency += 6;
-	    page_size = 9;
+		fifo_size = 32;
+		dsp_loop_latency = 2;
+	}
+	dsp_precision = 0;
+	y = (xclks_per_row * fifo_size) >> 11;
+	while (y) {
+		y >>= 1;
+		dsp_precision++;
 	}
-    } else {
-	if (info->ram_type >= SDRAM) {
-	    /* <2 MB SDRAM */
-	    dsp_loop_latency += 9;
-	    page_size = 10;
+	dsp_precision -= 5;
+	/* fifo_off<<6 */
+	fifo_off = ((xclks_per_row * (fifo_size - 1)) >> 5) + (3 << 6);
+
+	if (info->fix.smem_len > 1 * 1024 * 1024) {
+		if (par->ram_type >= SDRAM) {
+			/* >1 MB SDRAM */
+			dsp_loop_latency += 8;
+			page_size = 8;
+		} else {
+			/* >1 MB DRAM */
+			dsp_loop_latency += 6;
+			page_size = 9;
+		}
 	} else {
-	    /* <2 MB DRAM */
-	    dsp_loop_latency += 8;
-	    page_size = 10;
+		if (par->ram_type >= SDRAM) {
+			/* <2 MB SDRAM */
+			dsp_loop_latency += 9;
+			page_size = 10;
+		} else {
+			/* <2 MB DRAM */
+			dsp_loop_latency += 8;
+			page_size = 10;
+		}
 	}
-    }
-    /* fifo_on<<6 */
-    if (xclks_per_row >= (page_size<<11))
-	fifo_on = ((2*page_size+1)<<6)+(xclks_per_row>>5);
-    else
-	fifo_on = (3*page_size+2)<<6;
-
-    dsp_xclks_per_row = xclks_per_row>>dsp_precision;
-    dsp_on = fifo_on>>dsp_precision;
-    dsp_off = fifo_off>>dsp_precision;
-
-    pll->dsp_config = (dsp_xclks_per_row & 0x3fff) |
-		      ((dsp_loop_latency & 0xf)<<16) |
-		      ((dsp_precision & 7)<<20);
-    pll->dsp_on_off = (dsp_on & 0x7ff) | ((dsp_off & 0x7ff)<<16);
-    return 0;
+	/* fifo_on<<6 */
+	if (xclks_per_row >= (page_size << 11))
+		fifo_on =
+		    ((2 * page_size + 1) << 6) + (xclks_per_row >> 5);
+	else
+		fifo_on = (3 * page_size + 2) << 6;
+
+	dsp_xclks_per_row = xclks_per_row >> dsp_precision;
+	dsp_on = fifo_on >> dsp_precision;
+	dsp_off = fifo_off >> dsp_precision;
+
+	pll->dsp_config = (dsp_xclks_per_row & 0x3fff) |
+	    ((dsp_loop_latency & 0xf) << 16) | ((dsp_precision & 7) << 20);
+	pll->dsp_on_off = (dsp_on & 0x7ff) | ((dsp_off & 0x7ff) << 16);
+	return 0;
 }
 
-static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
+static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per,
 			    struct pll_ct *pll)
 {
-    u32 q, x;			/* x is a workaround for sparc64-linux-gcc */
-    x = x;			/* x is a workaround for sparc64-linux-gcc */
-
-    pll->pll_ref_div = info->pll_per*2*255/info->ref_clk_per;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 q, x;		/* x is a workaround for sparc64-linux-gcc */
+	x = x;			/* x is a workaround for sparc64-linux-gcc */
+
+	pll->pll_ref_div = par->pll_per * 2 * 255 / par->ref_clk_per;
+
+	/* FIXME: use the VTB/GTB /3 post divider if it's better suited */
+	q = par->ref_clk_per * pll->pll_ref_div * 4 / par->mclk_per;	/* actually 8*q */
+	if (q < 16 * 8 || q > 255 * 8)
+		FAIL("mclk out of range");
+	else if (q < 32 * 8)
+		pll->mclk_post_div_real = 8;
+	else if (q < 64 * 8)
+		pll->mclk_post_div_real = 4;
+	else if (q < 128 * 8)
+		pll->mclk_post_div_real = 2;
+	else
+		pll->mclk_post_div_real = 1;
+	pll->mclk_fb_div = q * pll->mclk_post_div_real / 8;
 
-    /* FIXME: use the VTB/GTB /3 post divider if it's better suited */
-    q = info->ref_clk_per*pll->pll_ref_div*4/info->mclk_per;	/* actually 8*q */
-    if (q < 16*8 || q > 255*8)
-	FAIL("mclk out of range");
-    else if (q < 32*8)
-	pll->mclk_post_div_real = 8;
-    else if (q < 64*8)
-	pll->mclk_post_div_real = 4;
-    else if (q < 128*8)
-	pll->mclk_post_div_real = 2;
-    else
-	pll->mclk_post_div_real = 1;
-    pll->mclk_fb_div = q*pll->mclk_post_div_real/8;
-
-    /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
-    q = info->ref_clk_per*pll->pll_ref_div*4/vclk_per;	/* actually 8*q */
-    if (q < 16*8 || q > 255*8)
-	FAIL("vclk out of range");
-    else if (q < 32*8)
-	pll->vclk_post_div_real = 8;
-    else if (q < 64*8)
-	pll->vclk_post_div_real = 4;
-    else if (q < 128*8)
-	pll->vclk_post_div_real = 2;
-    else
-	pll->vclk_post_div_real = 1;
-    pll->vclk_fb_div = q*pll->vclk_post_div_real/8;
-    return 0;
+	/* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
+	q = par->ref_clk_per * pll->pll_ref_div * 4 / vclk_per;	/* actually 8*q */
+	if (q < 16 * 8 || q > 255 * 8)
+		FAIL("vclk out of range");
+	else if (q < 32 * 8)
+		pll->vclk_post_div_real = 8;
+	else if (q < 64 * 8)
+		pll->vclk_post_div_real = 4;
+	else if (q < 128 * 8)
+		pll->vclk_post_div_real = 2;
+	else
+		pll->vclk_post_div_real = 1;
+	pll->vclk_fb_div = q * pll->vclk_post_div_real / 8;
+	return 0;
 }
 
-void aty_calc_pll_ct(const struct fb_info_aty *info, struct pll_ct *pll)
+void aty_calc_pll_ct(const struct fb_info *info, struct pll_ct *pll)
 {
-    u8 mpostdiv = 0;
-    u8 vpostdiv = 0;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u8 mpostdiv = 0;
+	u8 vpostdiv = 0;
 
-    if (M64_HAS(SDRAM_MAGIC_PLL) && (info->ram_type >= SDRAM))
-	pll->pll_gen_cntl = 0x04;
-    else
-	pll->pll_gen_cntl = 0x84;
+	if (M64_HAS(SDRAM_MAGIC_PLL) && (par->ram_type >= SDRAM))
+		pll->pll_gen_cntl = 0x04;
+	else
+		pll->pll_gen_cntl = 0x84;
 
-    switch (pll->mclk_post_div_real) {
+	switch (pll->mclk_post_div_real) {
 	case 1:
-	    mpostdiv = 0;
-	    break;
+		mpostdiv = 0;
+		break;
 	case 2:
-	    mpostdiv = 1;
-	    break;
+		mpostdiv = 1;
+		break;
 	case 3:
-	    mpostdiv = 4;
-	    break;
+		mpostdiv = 4;
+		break;
 	case 4:
-	    mpostdiv = 2;
-	    break;
+		mpostdiv = 2;
+		break;
 	case 8:
-	    mpostdiv = 3;
-	    break;
-    }
-    pll->pll_gen_cntl |= mpostdiv<<4;	/* mclk */
-
-    if (M64_HAS(MAGIC_POSTDIV))
-	pll->pll_ext_cntl = 0;
-    else
-    	pll->pll_ext_cntl = mpostdiv;	/* xclk == mclk */
+		mpostdiv = 3;
+		break;
+	}
+	pll->pll_gen_cntl |= mpostdiv << 4;	/* mclk */
+
+	if (M64_HAS(MAGIC_POSTDIV))
+		pll->pll_ext_cntl = 0;
+	else
+		pll->pll_ext_cntl = mpostdiv;	/* xclk == mclk */
 
-    switch (pll->vclk_post_div_real) {
+	switch (pll->vclk_post_div_real) {
 	case 2:
-	    vpostdiv = 1;
-	    break;
+		vpostdiv = 1;
+		break;
 	case 3:
-	    pll->pll_ext_cntl |= 0x10;
+		pll->pll_ext_cntl |= 0x10;
 	case 1:
-	    vpostdiv = 0;
-	    break;
+		vpostdiv = 0;
+		break;
 	case 6:
-	    pll->pll_ext_cntl |= 0x10;
+		pll->pll_ext_cntl |= 0x10;
 	case 4:
-	    vpostdiv = 2;
-	    break;
+		vpostdiv = 2;
+		break;
 	case 12:
-	    pll->pll_ext_cntl |= 0x10;
+		pll->pll_ext_cntl |= 0x10;
 	case 8:
-	    vpostdiv = 3;
-	    break;
-    }
+		vpostdiv = 3;
+		break;
+	}
 
-    pll->pll_vclk_cntl = 0x03;	/* VCLK = PLL_VCLK/VCLKx_POST */
-    pll->vclk_post_div = vpostdiv;
+	pll->pll_vclk_cntl = 0x03;	/* VCLK = PLL_VCLK/VCLKx_POST */
+	pll->vclk_post_div = vpostdiv;
 }
 
-static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
+static int aty_var_to_pll_ct(const struct fb_info *info, u32 vclk_per,
 			     u8 bpp, union aty_pll *pll)
 {
-    int err;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	int err;
 
-    if ((err = aty_valid_pll_ct(info, vclk_per, &pll->ct)))
-	return err;
-    if (M64_HAS(GTB_DSP) && (err = aty_dsp_gt(info, bpp, &pll->ct)))
-	return err;
-    aty_calc_pll_ct(info, &pll->ct);
-    return 0;
+	if ((err = aty_valid_pll_ct(info, vclk_per, &pll->ct)))
+		return err;
+	if (M64_HAS(GTB_DSP) && (err = aty_dsp_gt(info, bpp, &pll->ct)))
+		return err;
+	aty_calc_pll_ct(info, &pll->ct);
+	return 0;
 }
 
-static u32 aty_pll_ct_to_var(const struct fb_info_aty *info,
+static u32 aty_pll_ct_to_var(const struct fb_info *info,
 			     const union aty_pll *pll)
 {
-    u32 ref_clk_per = info->ref_clk_per;
-    u8 pll_ref_div = pll->ct.pll_ref_div;
-    u8 vclk_fb_div = pll->ct.vclk_fb_div;
-    u8 vclk_post_div = pll->ct.vclk_post_div_real;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+
+	u32 ref_clk_per = par->ref_clk_per;
+	u8 pll_ref_div = pll->ct.pll_ref_div;
+	u8 vclk_fb_div = pll->ct.vclk_fb_div;
+	u8 vclk_post_div = pll->ct.vclk_post_div_real;
 
-    return ref_clk_per*pll_ref_div*vclk_post_div/vclk_fb_div/2;
+	return ref_clk_per * pll_ref_div * vclk_post_div / vclk_fb_div / 2;
 }
 
-void aty_set_pll_ct(const struct fb_info_aty *info, const union aty_pll *pll)
+void aty_set_pll_ct(const struct fb_info *info,
+		    const union aty_pll *pll)
 {
-    aty_st_pll(PLL_REF_DIV, pll->ct.pll_ref_div, info);
-    aty_st_pll(PLL_GEN_CNTL, pll->ct.pll_gen_cntl, info);
-    aty_st_pll(MCLK_FB_DIV, pll->ct.mclk_fb_div, info);
-    aty_st_pll(PLL_VCLK_CNTL, pll->ct.pll_vclk_cntl, info);
-    aty_st_pll(VCLK_POST_DIV, pll->ct.vclk_post_div, info);
-    aty_st_pll(VCLK0_FB_DIV, pll->ct.vclk_fb_div, info);
-    aty_st_pll(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, info);
-
-    if (M64_HAS(GTB_DSP)) {
-	if (M64_HAS(XL_DLL))
-	    aty_st_pll(DLL_CNTL, 0x80, info);
-	else if (info->ram_type >= SDRAM)
-	    aty_st_pll(DLL_CNTL, 0xa6, info);
-	else
-	    aty_st_pll(DLL_CNTL, 0xa0, info);
-	aty_st_pll(VFC_CNTL, 0x1b, info);
-	aty_st_le32(DSP_CONFIG, pll->ct.dsp_config, info);
-	aty_st_le32(DSP_ON_OFF, pll->ct.dsp_on_off, info);
-    }
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+
+	aty_st_pll(PLL_REF_DIV, pll->ct.pll_ref_div, par);
+	aty_st_pll(PLL_GEN_CNTL, pll->ct.pll_gen_cntl, par);
+	aty_st_pll(MCLK_FB_DIV, pll->ct.mclk_fb_div, par);
+	aty_st_pll(PLL_VCLK_CNTL, pll->ct.pll_vclk_cntl, par);
+	aty_st_pll(VCLK_POST_DIV, pll->ct.vclk_post_div, par);
+	aty_st_pll(VCLK0_FB_DIV, pll->ct.vclk_fb_div, par);
+	aty_st_pll(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, par);
+
+	if (M64_HAS(GTB_DSP)) {
+		if (M64_HAS(XL_DLL))
+			aty_st_pll(DLL_CNTL, 0x80, par);
+		else if (par->ram_type >= SDRAM)
+			aty_st_pll(DLL_CNTL, 0xa6, par);
+		else
+			aty_st_pll(DLL_CNTL, 0xa0, par);
+		aty_st_pll(VFC_CNTL, 0x1b, par);
+		aty_st_le32(DSP_CONFIG, pll->ct.dsp_config, par);
+		aty_st_le32(DSP_ON_OFF, pll->ct.dsp_on_off, par);
+	}
 }
 
 static int dummy(void)
 {
-    return 0;
+	return 0;
 }
 
 const struct aty_dac_ops aty_dac_ct = {
-    set_dac:	(void *)dummy,
+	set_dac:(void *) dummy,
 };
 
 const struct aty_pll_ops aty_pll_ct = {
-    var_to_pll:	aty_var_to_pll_ct,
-    pll_to_var:	aty_pll_ct_to_var,
-    set_pll:	aty_set_pll_ct,
+	var_to_pll:aty_var_to_pll_ct,
+	pll_to_var:aty_pll_ct_to_var,
+	set_pll:aty_set_pll_ct,
 };
-
diff -Nru a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
--- a/drivers/video/aty/mach64_cursor.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/video/aty/mach64_cursor.c	Wed Jul 24 14:03:39 2002
@@ -18,7 +18,7 @@
 #include <asm/fbio.h>
 #endif
 
-#include "mach64.h"
+#include <video/mach64.h>
 #include "atyfb.h"
 
 
@@ -33,21 +33,20 @@
 static const u8 cursor_pixel_map[2] = { 0, 15 };
 static const u8 cursor_color_map[2] = { 0, 0xff };
 
-static const u8 cursor_bits_lookup[16] =
-{
+static const u8 cursor_bits_lookup[16] = {
 	0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
 	0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
 };
 
-static const u8 cursor_mask_lookup[16] =
-{
+static const u8 cursor_mask_lookup[16] = {
 	0xaa, 0x2a, 0x8a, 0x0a, 0xa2, 0x22, 0x82, 0x02,
 	0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00
 };
 
-void aty_set_cursor_color(struct fb_info_aty *fb)
+void aty_set_cursor_color(struct fb_info *info)
 {
-	struct aty_cursor *c = fb->cursor;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct aty_cursor *c = par->cursor;
 	const u8 *pixel = cursor_pixel_map;	/* ++Geert: Why?? */
 	const u8 *red = cursor_color_map;
 	const u8 *green = cursor_color_map;
@@ -58,26 +57,28 @@
 		return;
 
 #ifdef __sparc__
-	if (fb->mmaped && (!fb->fb_info.display_fg
-	    || fb->fb_info.display_fg->vc_num == fb->vtconsole))
+	if (par->mmaped && (!info->display_fg
+			   || info->display_fg->vc_num ==
+			   par->vtconsole))
 		return;
 #endif
 
 	for (i = 0; i < 2; i++) {
-		c->color[i] =  (u32)red[i] << 24;
-		c->color[i] |= (u32)green[i] << 16;
- 		c->color[i] |= (u32)blue[i] <<  8;
- 		c->color[i] |= (u32)pixel[i];
+		c->color[i] = (u32) red[i] << 24;
+		c->color[i] |= (u32) green[i] << 16;
+		c->color[i] |= (u32) blue[i] << 8;
+		c->color[i] |= (u32) pixel[i];
 	}
 
-	wait_for_fifo(2, fb);
-	aty_st_le32(CUR_CLR0, c->color[0], fb);
-	aty_st_le32(CUR_CLR1, c->color[1], fb);
+	wait_for_fifo(2, par);
+	aty_st_le32(CUR_CLR0, c->color[0], par);
+	aty_st_le32(CUR_CLR1, c->color[1], par);
 }
 
-void aty_set_cursor_shape(struct fb_info_aty *fb)
+void aty_set_cursor_shape(struct fb_info *info)
 {
-	struct aty_cursor *c = fb->cursor;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct aty_cursor *c = par->cursor;
 	u8 *ram, m, b;
 	int x, y;
 
@@ -85,8 +86,9 @@
 		return;
 
 #ifdef __sparc__
-	if (fb->mmaped && (!fb->fb_info.display_fg
-	    || fb->fb_info.display_fg->vc_num == fb->vtconsole))
+	if (par->mmaped && (!info->display_fg
+			   || info->display_fg->vc_num ==
+			   par->vtconsole))
 		return;
 #endif
 
@@ -95,26 +97,24 @@
 		for (x = 0; x < c->size.x >> 2; x++) {
 			m = c->mask[x][y];
 			b = c->bits[x][y];
-			fb_writeb (cursor_mask_lookup[m >> 4] |
-				   cursor_bits_lookup[(b & m) >> 4],
-				   ram++);
-			fb_writeb (cursor_mask_lookup[m & 0x0f] |
-				   cursor_bits_lookup[(b & m) & 0x0f],
-				   ram++);
+			fb_writeb(cursor_mask_lookup[m >> 4] |
+				  cursor_bits_lookup[(b & m) >> 4], ram++);
+			fb_writeb(cursor_mask_lookup[m & 0x0f] |
+				  cursor_bits_lookup[(b & m) & 0x0f],
+				  ram++);
 		}
-		for ( ; x < 8; x++) {
-			fb_writeb (0xaa, ram++);
-			fb_writeb (0xaa, ram++);
+		for (; x < 8; x++) {
+			fb_writeb(0xaa, ram++);
+			fb_writeb(0xaa, ram++);
 		}
 	}
-	fb_memset (ram, 0xaa, (64 - c->size.y) * 16);
+	fb_memset(ram, 0xaa, (64 - c->size.y) * 16);
 }
 
-static void
-aty_set_cursor(struct fb_info_aty *fb, int on)
+static void aty_set_cursor(struct fb_info *info, int on)
 {
-	struct atyfb_par *par = &fb->current_par;
-	struct aty_cursor *c = fb->cursor;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct aty_cursor *c = par->cursor;
 	u16 xoff, yoff;
 	int x, y;
 
@@ -122,8 +122,9 @@
 		return;
 
 #ifdef __sparc__
-	if (fb->mmaped && (!fb->fb_info.display_fg
-	    || fb->fb_info.display_fg->vc_num == fb->vtconsole))
+	if (par->mmaped && (!info->display_fg
+			   || info->display_fg->vc_num ==
+			   par->vtconsole))
 		return;
 #endif
 
@@ -144,67 +145,72 @@
 			yoff = 0;
 		}
 
-		wait_for_fifo(4, fb);
-		aty_st_le32(CUR_OFFSET, (c->offset >> 3) + (yoff << 1), fb);
+		wait_for_fifo(4, par);
+		aty_st_le32(CUR_OFFSET, (c->offset >> 3) + (yoff << 1),
+			    par);
 		aty_st_le32(CUR_HORZ_VERT_OFF,
-			    ((u32)(64 - c->size.y + yoff) << 16) | xoff, fb);
-		aty_st_le32(CUR_HORZ_VERT_POSN, ((u32)y << 16) | x, fb);
-		aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, fb)
-						       | HWCURSOR_ENABLE, fb);
+			    ((u32) (64 - c->size.y + yoff) << 16) | xoff,
+			    par);
+		aty_st_le32(CUR_HORZ_VERT_POSN, ((u32) y << 16) | x, par);
+		aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
+			    | HWCURSOR_ENABLE, par);
 	} else {
-		wait_for_fifo(1, fb);
+		wait_for_fifo(1, par);
 		aty_st_le32(GEN_TEST_CNTL,
-			    aty_ld_le32(GEN_TEST_CNTL, fb) & ~HWCURSOR_ENABLE,
-			    fb);
+			    aty_ld_le32(GEN_TEST_CNTL,
+					par) & ~HWCURSOR_ENABLE, par);
 	}
-	if (fb->blitter_may_be_busy)
-		wait_for_idle(fb);
+	if (par->blitter_may_be_busy)
+		wait_for_idle(par);
 }
 
-static void
-aty_cursor_timer_handler(unsigned long dev_addr)
+static void aty_cursor_timer_handler(unsigned long dev_addr)
 {
-	struct fb_info_aty *fb = (struct fb_info_aty *)dev_addr;
+	struct fb_info *info = (struct fb_info *) dev_addr;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
 
-	if (!fb->cursor)
+	if (!par->cursor)
 		return;
 
-	if (!fb->cursor->enable)
+	if (!par->cursor->enable)
 		goto out;
 
-	if (fb->cursor->vbl_cnt && --fb->cursor->vbl_cnt == 0) {
-		fb->cursor->on ^= 1;
-		aty_set_cursor(fb, fb->cursor->on);
-		fb->cursor->vbl_cnt = fb->cursor->blink_rate;
+	if (par->cursor->vbl_cnt && --par->cursor->vbl_cnt == 0) {
+		par->cursor->on ^= 1;
+		aty_set_cursor(info, par->cursor->on);
+		par->cursor->vbl_cnt = par->cursor->blink_rate;
 	}
 
-out:
-	fb->cursor->timer->expires = jiffies + (HZ / 50);
-	add_timer(fb->cursor->timer);
+      out:
+	par->cursor->timer->expires = jiffies + (HZ / 50);
+	add_timer(par->cursor->timer);
 }
 
 void atyfb_cursor(struct display *p, int mode, int x, int y)
 {
-	struct fb_info_aty *fb = (struct fb_info_aty *)p->fb_info;
-	struct aty_cursor *c = fb->cursor;
+	struct fb_info *info = p->fb_info;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct aty_cursor *c = par->cursor;
 
 	if (!c)
 		return;
 
 #ifdef __sparc__
-	if (fb->mmaped && (!fb->fb_info.display_fg
-	    || fb->fb_info.display_fg->vc_num == fb->vtconsole))
+	if (par->mmaped && (!info->display_fg
+			   || info->display_fg->vc_num ==
+			   par->vtconsole))
 		return;
 #endif
 
 	x *= fontwidth(p);
 	y *= fontheight(p);
-	if (c->pos.x == x && c->pos.y == y && (mode == CM_ERASE) == !c->enable)
+	if (c->pos.x == x && c->pos.y == y
+	    && (mode == CM_ERASE) == !c->enable)
 		return;
 
 	c->enable = 0;
 	if (c->on)
-		aty_set_cursor(fb, 0);
+		aty_set_cursor(info, 0);
 	c->pos.x = x;
 	c->pos.y = y;
 
@@ -216,7 +222,7 @@
 	case CM_DRAW:
 	case CM_MOVE:
 		if (c->on)
-			aty_set_cursor(fb, 1);
+			aty_set_cursor(info, 1);
 		else
 			c->vbl_cnt = CURSOR_DRAW_DELAY;
 		c->enable = 1;
@@ -224,7 +230,7 @@
 	}
 }
 
-struct aty_cursor * __init aty_init_cursor(struct fb_info_aty *fb)
+struct aty_cursor *__init aty_init_cursor(struct fb_info *info)
 {
 	struct aty_cursor *cursor;
 	unsigned long addr;
@@ -242,19 +248,19 @@
 	memset(cursor->timer, 0, sizeof(*cursor->timer));
 
 	cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
-	fb->total_vram -= PAGE_SIZE;
-	cursor->offset = fb->total_vram;
+	info->fix.smem_len -= PAGE_SIZE;
+	cursor->offset = info->fix.smem_len;
 
 #ifdef __sparc__
-	addr = fb->frame_buffer - 0x800000 + cursor->offset;
-	cursor->ram = (u8 *)addr;
+	addr = info->screen_base - 0x800000 + cursor->offset;
+	cursor->ram = (u8 *) addr;
 #else
 #ifdef __BIG_ENDIAN
-	addr = fb->frame_buffer_phys - 0x800000 + cursor->offset;
-	cursor->ram = (u8 *)ioremap(addr, 1024);
+	addr = info->fix.smem_start - 0x800000 + cursor->offset;
+	cursor->ram = (u8 *) ioremap(addr, 1024);
 #else
-	addr = fb->frame_buffer + cursor->offset;
-	cursor->ram = (u8 *)addr;
+	addr = (unsigned long) info->screen_base + cursor->offset;
+	cursor->ram = (u8 *) addr;
 #endif
 #endif
 
@@ -265,41 +271,42 @@
 
 	init_timer(cursor->timer);
 	cursor->timer->expires = jiffies + (HZ / 50);
-	cursor->timer->data = (unsigned long)fb;
+	cursor->timer->data = (unsigned long) info;
 	cursor->timer->function = aty_cursor_timer_handler;
 	add_timer(cursor->timer);
-
 	return cursor;
 }
 
 int atyfb_set_font(struct display *d, int width, int height)
 {
-    struct fb_info_aty *fb = (struct fb_info_aty *)d->fb_info;
-    struct aty_cursor *c = fb->cursor;
-    int i, j;
-
-    if (c) {
-	if (!width || !height) {
-	    width = 8;
-	    height = 16;
-	}
+	struct fb_info *info = d->fb_info;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct aty_cursor *c = par->cursor;
+	int i, j;
+
+	if (c) {
+		if (!width || !height) {
+			width = 8;
+			height = 16;
+		}
 
-	c->hot.x = 0;
-	c->hot.y = 0;
-	c->size.x = width;
-	c->size.y = height;
-
-	memset(c->bits, 0xff, sizeof(c->bits));
-	memset(c->mask, 0, sizeof(c->mask));
-
-	for (i = 0, j = width; j >= 0; j -= 8, i++) {
-	    c->mask[i][height-2] = (j >= 8) ? 0xff : (0xff << (8 - j));
-	    c->mask[i][height-1] = (j >= 8) ? 0xff : (0xff << (8 - j));
-	}
+		c->hot.x = 0;
+		c->hot.y = 0;
+		c->size.x = width;
+		c->size.y = height;
+
+		memset(c->bits, 0xff, sizeof(c->bits));
+		memset(c->mask, 0, sizeof(c->mask));
+
+		for (i = 0, j = width; j >= 0; j -= 8, i++) {
+			c->mask[i][height - 2] =
+			    (j >= 8) ? 0xff : (0xff << (8 - j));
+			c->mask[i][height - 1] =
+			    (j >= 8) ? 0xff : (0xff << (8 - j));
+		}
 
-	aty_set_cursor_color(fb);
-	aty_set_cursor_shape(fb);
-    }
-    return 1;
+		aty_set_cursor_color(info);
+		aty_set_cursor_shape(info);
+	}
+	return 1;
 }
-
diff -Nru a/drivers/video/aty/mach64_gx.c b/drivers/video/aty/mach64_gx.c
--- a/drivers/video/aty/mach64_gx.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/aty/mach64_gx.c	Wed Jul 24 14:03:36 2002
@@ -11,18 +11,18 @@
 
 #include <video/fbcon.h>
 
-#include "mach64.h"
+#include <video/mach64.h>
 #include "atyfb.h"
 
 /* Definitions for the ICS 2595 == ATI 18818_1 Clockchip */
 
-#define REF_FREQ_2595       1432  /*  14.33 MHz  (exact   14.31818) */
-#define REF_DIV_2595          46  /* really 43 on ICS 2595 !!!  */
-                                  /* ohne Prescaler */
-#define MAX_FREQ_2595      15938  /* 159.38 MHz  (really 170.486) */
-#define MIN_FREQ_2595       8000  /*  80.00 MHz  (        85.565) */
-                                  /* mit Prescaler 2, 4, 8 */
-#define ABS_MIN_FREQ_2595   1000  /*  10.00 MHz  (really  10.697) */
+#define REF_FREQ_2595       1432	/*  14.33 MHz  (exact   14.31818) */
+#define REF_DIV_2595          46	/* really 43 on ICS 2595 !!!  */
+				  /* ohne Prescaler */
+#define MAX_FREQ_2595      15938	/* 159.38 MHz  (really 170.486) */
+#define MIN_FREQ_2595       8000	/*  80.00 MHz  (        85.565) */
+				  /* mit Prescaler 2, 4, 8 */
+#define ABS_MIN_FREQ_2595   1000	/*  10.00 MHz  (really  10.697) */
 #define N_ADJ_2595           257
 
 #define STOP_BITS_2595     0x1800
@@ -42,26 +42,25 @@
      *  Support Functions
      */
 
-static void aty_dac_waste4(const struct fb_info_aty *info)
+static void aty_dac_waste4(const struct atyfb_par *par)
 {
-  (void)aty_ld_8(DAC_REGS, info);
+	(void) aty_ld_8(DAC_REGS, par);
 
-  (void)aty_ld_8(DAC_REGS + 2, info);
-  (void)aty_ld_8(DAC_REGS + 2, info);
-  (void)aty_ld_8(DAC_REGS + 2, info);
-  (void)aty_ld_8(DAC_REGS + 2, info);
+	(void) aty_ld_8(DAC_REGS + 2, par);
+	(void) aty_ld_8(DAC_REGS + 2, par);
+	(void) aty_ld_8(DAC_REGS + 2, par);
+	(void) aty_ld_8(DAC_REGS + 2, par);
 }
 
-static void aty_StrobeClock(const struct fb_info_aty *info)
+static void aty_StrobeClock(const struct atyfb_par *par)
 {
-    u8 tmp;
+	u8 tmp;
 
-    udelay(26);
+	udelay(26);
 
-    tmp = aty_ld_8(CLOCK_CNTL, info);
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, tmp | CLOCK_STROBE, info);
-
-    return;
+	tmp = aty_ld_8(CLOCK_CNTL, par);
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset, tmp | CLOCK_STROBE, par);
+	return;
 }
 
 
@@ -69,120 +68,136 @@
      *  IBM RGB514 DAC and Clock Chip
      */
 
-static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info)
+static void aty_st_514(int offset, u8 val, const struct atyfb_par *par)
 {
-    aty_st_8(DAC_CNTL, 1, info);
-    /* right addr byte */
-    aty_st_8(DAC_W_INDEX, offset & 0xff, info);
-    /* left addr byte */
-    aty_st_8(DAC_DATA, (offset >> 8) & 0xff, info);
-    aty_st_8(DAC_MASK, val, info);
-    aty_st_8(DAC_CNTL, 0, info);
+	aty_st_8(DAC_CNTL, 1, par);
+	/* right addr byte */
+	aty_st_8(DAC_W_INDEX, offset & 0xff, par);
+	/* left addr byte */
+	aty_st_8(DAC_DATA, (offset >> 8) & 0xff, par);
+	aty_st_8(DAC_MASK, val, par);
+	aty_st_8(DAC_CNTL, 0, par);
 }
 
-static int aty_set_dac_514(const struct fb_info_aty *info,
+static int aty_set_dac_514(const struct fb_info *info,
 			   const union aty_pll *pll, u32 bpp, u32 accel)
 {
-    static struct {
-	u8 pixel_dly;
-	u8 misc2_cntl;
-	u8 pixel_rep;
-	u8 pixel_cntl_index;
-	u8 pixel_cntl_v1;
-    } tab[3] = {
-	{ 0, 0x41, 0x03, 0x71, 0x45 },	/* 8 bpp */
-	{ 0, 0x45, 0x04, 0x0c, 0x01 },	/* 555 */
-	{ 0, 0x45, 0x06, 0x0e, 0x00 },	/* XRGB */
-    };
-    int i;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	static struct {
+		u8 pixel_dly;
+		u8 misc2_cntl;
+		u8 pixel_rep;
+		u8 pixel_cntl_index;
+		u8 pixel_cntl_v1;
+	} tab[3] = {
+		{
+		0, 0x41, 0x03, 0x71, 0x45},	/* 8 bpp */
+		{
+		0, 0x45, 0x04, 0x0c, 0x01},	/* 555 */
+		{
+		0, 0x45, 0x06, 0x0e, 0x00},	/* XRGB */
+	};
+	int i;
 
-    switch (bpp) {
+	switch (bpp) {
 	case 8:
 	default:
-	    i = 0;
-	    break;
+		i = 0;
+		break;
 	case 16:
-	    i = 1;
-	    break;
+		i = 1;
+		break;
 	case 32:
-	    i = 2;
-	    break;
-    }
-    aty_st_514(0x90, 0x00, info);		/* VRAM Mask Low */
-    aty_st_514(0x04, tab[i].pixel_dly, info);	/* Horizontal Sync Control */
-    aty_st_514(0x05, 0x00, info);		/* Power Management */
-    aty_st_514(0x02, 0x01, info);		/* Misc Clock Control */
-    aty_st_514(0x71, tab[i].misc2_cntl, info);	/* Misc Control 2 */
-    aty_st_514(0x0a, tab[i].pixel_rep, info);	/* Pixel Format */
-    aty_st_514(tab[i].pixel_cntl_index, tab[i].pixel_cntl_v1, info);
-			/* Misc Control 2 / 16 BPP Control / 32 BPP Control */
-    return 0;
+		i = 2;
+		break;
+	}
+	aty_st_514(0x90, 0x00, par);	/* VRAM Mask Low */
+	aty_st_514(0x04, tab[i].pixel_dly, par);	/* Horizontal Sync Control */
+	aty_st_514(0x05, 0x00, par);	/* Power Management */
+	aty_st_514(0x02, 0x01, par);	/* Misc Clock Control */
+	aty_st_514(0x71, tab[i].misc2_cntl, par);	/* Misc Control 2 */
+	aty_st_514(0x0a, tab[i].pixel_rep, par);	/* Pixel Format */
+	aty_st_514(tab[i].pixel_cntl_index, tab[i].pixel_cntl_v1, par);
+	/* Misc Control 2 / 16 BPP Control / 32 BPP Control */
+	return 0;
 }
 
-static int aty_var_to_pll_514(const struct fb_info_aty *info, u32 vclk_per,
+static int aty_var_to_pll_514(const struct fb_info *info, u32 vclk_per,
 			      u8 bpp, union aty_pll *pll)
 {
-    /*
-     *  FIXME: use real calculations instead of using fixed values from the old
-     *	       driver
-     */
-    static struct {
-	u32 limit;	/* pixlock rounding limit (arbitrary) */
-	u8 m;		/* (df<<6) | vco_div_count */
-	u8 n;		/* ref_div_count */
-    } RGB514_clocks[7] = {
-	{  8000, (3<<6) | 20, 9 },	/*  7395 ps / 135.2273 MHz */
-	{ 10000, (1<<6) | 19, 3 },	/*  9977 ps / 100.2273 MHz */
-	{ 13000, (1<<6) |  2, 3 },	/* 12509 ps /  79.9432 MHz */
-	{ 14000, (2<<6) |  8, 7 },	/* 13394 ps /  74.6591 MHz */
-	{ 16000, (1<<6) | 44, 6 },	/* 15378 ps /  65.0284 MHz */
-	{ 25000, (1<<6) | 15, 5 },	/* 17460 ps /  57.2727 MHz */
-	{ 50000, (0<<6) | 53, 7 },	/* 33145 ps /  30.1705 MHz */
-    };
-    int i;
-
-    for (i = 0; i < sizeof(RGB514_clocks)/sizeof(*RGB514_clocks); i++)
-	if (vclk_per <= RGB514_clocks[i].limit) {
-	    pll->ibm514.m = RGB514_clocks[i].m;
-	    pll->ibm514.n = RGB514_clocks[i].n;
-	    return 0;
-	}
-    return -EINVAL;
-}
-
-static u32 aty_pll_514_to_var(const struct fb_info_aty *info,
-	                      const union aty_pll *pll)
-{
-    u8 df, vco_div_count, ref_div_count;
-
-    df = pll->ibm514.m >> 6;
-    vco_div_count = pll->ibm514.m & 0x3f;
-    ref_div_count = pll->ibm514.n;
+	/*
+	 *  FIXME: use real calculations instead of using fixed values from the old
+	 *         driver
+	 */
+	static struct {
+		u32 limit;	/* pixlock rounding limit (arbitrary) */
+		u8 m;		/* (df<<6) | vco_div_count */
+		u8 n;		/* ref_div_count */
+	} RGB514_clocks[7] = {
+		{
+		8000, (3 << 6) | 20, 9},	/*  7395 ps / 135.2273 MHz */
+		{
+		10000, (1 << 6) | 19, 3},	/*  9977 ps / 100.2273 MHz */
+		{
+		13000, (1 << 6) | 2, 3},	/* 12509 ps /  79.9432 MHz */
+		{
+		14000, (2 << 6) | 8, 7},	/* 13394 ps /  74.6591 MHz */
+		{
+		16000, (1 << 6) | 44, 6},	/* 15378 ps /  65.0284 MHz */
+		{
+		25000, (1 << 6) | 15, 5},	/* 17460 ps /  57.2727 MHz */
+		{
+		50000, (0 << 6) | 53, 7},	/* 33145 ps /  30.1705 MHz */
+	};
+	int i;
+
+	for (i = 0; i < sizeof(RGB514_clocks) / sizeof(*RGB514_clocks);
+	     i++)
+		if (vclk_per <= RGB514_clocks[i].limit) {
+			pll->ibm514.m = RGB514_clocks[i].m;
+			pll->ibm514.n = RGB514_clocks[i].n;
+			return 0;
+		}
+	return -EINVAL;
+}
 
-    return ((info->ref_clk_per*ref_div_count)<<(3-df))/(vco_div_count+65);
+static u32 aty_pll_514_to_var(const struct fb_info *info,
+			      const union aty_pll *pll)
+{
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u8 df, vco_div_count, ref_div_count;
+
+	df = pll->ibm514.m >> 6;
+	vco_div_count = pll->ibm514.m & 0x3f;
+	ref_div_count = pll->ibm514.n;
+
+	return ((par->ref_clk_per * ref_div_count) << (3 - df))/
+	    		(vco_div_count + 65);
 }
 
-static void aty_set_pll_514(const struct fb_info_aty *info,
+static void aty_set_pll_514(const struct fb_info *info,
 			    const union aty_pll *pll)
 {
-    aty_st_514(0x06, 0x02, info);	/* DAC Operation */
-    aty_st_514(0x10, 0x01, info);	/* PLL Control 1 */
-    aty_st_514(0x70, 0x01, info);	/* Misc Control 1 */
-    aty_st_514(0x8f, 0x1f, info);	/* PLL Ref. Divider Input */
-    aty_st_514(0x03, 0x00, info);	/* Sync Control */
-    aty_st_514(0x05, 0x00, info);	/* Power Management */
-    aty_st_514(0x20, pll->ibm514.m, info);	/* F0 / M0 */
-    aty_st_514(0x21, pll->ibm514.n, info);	/* F1 / N0 */
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+
+	aty_st_514(0x06, 0x02, par);	/* DAC Operation */
+	aty_st_514(0x10, 0x01, par);	/* PLL Control 1 */
+	aty_st_514(0x70, 0x01, par);	/* Misc Control 1 */
+	aty_st_514(0x8f, 0x1f, par);	/* PLL Ref. Divider Input */
+	aty_st_514(0x03, 0x00, par);	/* Sync Control */
+	aty_st_514(0x05, 0x00, par);	/* Power Management */
+	aty_st_514(0x20, pll->ibm514.m, par);	/* F0 / M0 */
+	aty_st_514(0x21, pll->ibm514.n, par);	/* F1 / N0 */
 }
 
 const struct aty_dac_ops aty_dac_ibm514 = {
-    set_dac:	aty_set_dac_514,
+	set_dac:aty_set_dac_514,
 };
 
 const struct aty_pll_ops aty_pll_ibm514 = {
-    var_to_pll:	aty_var_to_pll_514,
-    pll_to_var:	aty_pll_514_to_var,
-    set_pll:	aty_set_pll_514,
+	var_to_pll:aty_var_to_pll_514,
+	pll_to_var:aty_pll_514_to_var,
+	set_pll:aty_set_pll_514,
 };
 
 
@@ -190,77 +205,82 @@
      *  ATI 68860-B DAC
      */
 
-static int aty_set_dac_ATI68860_B(const struct fb_info_aty *info,
-				  const union aty_pll *pll, u32 bpp, u32 accel)
+static int aty_set_dac_ATI68860_B(const struct fb_info *info,
+				  const union aty_pll *pll, u32 bpp,
+				  u32 accel)
 {
-    u32 gModeReg, devSetupRegA, temp, mask;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 gModeReg, devSetupRegA, temp, mask;
 
-    gModeReg = 0;
-    devSetupRegA = 0;
+	gModeReg = 0;
+	devSetupRegA = 0;
 
-    switch (bpp) {
+	switch (bpp) {
 	case 8:
-	    gModeReg = 0x83;
-	    devSetupRegA = 0x60 | 0x00 /*(info->mach64DAC8Bit ? 0x00 : 0x01) */;
-	    break;
+		gModeReg = 0x83;
+		devSetupRegA =
+		    0x60 | 0x00 /*(info->mach64DAC8Bit ? 0x00 : 0x01) */ ;
+		break;
 	case 15:
-	    gModeReg = 0xA0;
-	    devSetupRegA = 0x60;
-	    break;
+		gModeReg = 0xA0;
+		devSetupRegA = 0x60;
+		break;
 	case 16:
-	    gModeReg = 0xA1;
-	    devSetupRegA = 0x60;
-	    break;
+		gModeReg = 0xA1;
+		devSetupRegA = 0x60;
+		break;
 	case 24:
-	    gModeReg = 0xC0;
-	    devSetupRegA = 0x60;
-	    break;
+		gModeReg = 0xC0;
+		devSetupRegA = 0x60;
+		break;
 	case 32:
-	    gModeReg = 0xE3;
-	    devSetupRegA = 0x60;
-	    break;
-    }
-
-    if (!accel) {
-	gModeReg = 0x80;
-	devSetupRegA = 0x61;
-    }
-
-    temp = aty_ld_8(DAC_CNTL, info);
-    aty_st_8(DAC_CNTL, (temp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3, info);
-
-    aty_st_8(DAC_REGS + 2, 0x1D, info);
-    aty_st_8(DAC_REGS + 3, gModeReg, info);
-    aty_st_8(DAC_REGS, 0x02, info);
-
-    temp = aty_ld_8(DAC_CNTL, info);
-    aty_st_8(DAC_CNTL, temp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, info);
-
-    if (info->total_vram < MEM_SIZE_1M)
-	mask = 0x04;
-    else if (info->total_vram == MEM_SIZE_1M)
-	mask = 0x08;
-    else
-	mask = 0x0C;
-
-    /* The following assumes that the BIOS has correctly set R7 of the
-     * Device Setup Register A at boot time.
-     */
-#define A860_DELAY_L	0x80
+		gModeReg = 0xE3;
+		devSetupRegA = 0x60;
+		break;
+	}
 
-    temp = aty_ld_8(DAC_REGS, info);
-    aty_st_8(DAC_REGS, (devSetupRegA | mask) | (temp & A860_DELAY_L), info);
-    temp = aty_ld_8(DAC_CNTL, info);
-    aty_st_8(DAC_CNTL, (temp & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3)), info);
+	if (!accel) {
+		gModeReg = 0x80;
+		devSetupRegA = 0x61;
+	}
 
-    aty_st_le32(BUS_CNTL, 0x890e20f1, info);
-    aty_st_le32(DAC_CNTL, 0x47052100, info);
+	temp = aty_ld_8(DAC_CNTL, par);
+	aty_st_8(DAC_CNTL, (temp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3,
+		 par);
+
+	aty_st_8(DAC_REGS + 2, 0x1D, par);
+	aty_st_8(DAC_REGS + 3, gModeReg, par);
+	aty_st_8(DAC_REGS, 0x02, par);
+
+	temp = aty_ld_8(DAC_CNTL, par);
+	aty_st_8(DAC_CNTL, temp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, par);
+
+	if (info->fix.smem_len < MEM_SIZE_1M)
+		mask = 0x04;
+	else if (info->fix.smem_len == MEM_SIZE_1M)
+		mask = 0x08;
+	else
+		mask = 0x0C;
+
+	/* The following assumes that the BIOS has correctly set R7 of the
+	 * Device Setup Register A at boot time.
+	 */
+#define A860_DELAY_L	0x80
 
-    return 0;
+	temp = aty_ld_8(DAC_REGS, par);
+	aty_st_8(DAC_REGS, (devSetupRegA | mask) | (temp & A860_DELAY_L),
+		 par);
+	temp = aty_ld_8(DAC_CNTL, par);
+	aty_st_8(DAC_CNTL, (temp & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3)),
+		 par);
+
+	aty_st_le32(BUS_CNTL, 0x890e20f1, par);
+	aty_st_le32(DAC_CNTL, 0x47052100, par);
+	return 0;
 }
 
 const struct aty_dac_ops aty_dac_ati68860b = {
-    set_dac:	aty_set_dac_ATI68860_B,
+	set_dac:aty_set_dac_ATI68860_B,
 };
 
 
@@ -268,50 +288,52 @@
      *  AT&T 21C498 DAC
      */
 
-static int aty_set_dac_ATT21C498(const struct fb_info_aty *info,
-				 const union aty_pll *pll, u32 bpp, u32 accel)
-{
-    u32 dotClock;
-    int muxmode = 0;
-    int DACMask = 0;
+static int aty_set_dac_ATT21C498(const struct fb_info *info,
+				 const union aty_pll *pll, u32 bpp,
+				 u32 accel)
+{
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 dotClock;
+	int muxmode = 0;
+	int DACMask = 0;
 
-    dotClock = 100000000 / pll->ics2595.period_in_ps;
+	dotClock = 100000000 / pll->ics2595.period_in_ps;
 
-    switch (bpp) {
+	switch (bpp) {
 	case 8:
-	    if (dotClock > 8000) {
-		DACMask = 0x24;
-		muxmode = 1;
-	    } else
-		DACMask = 0x04;
-	    break;
+		if (dotClock > 8000) {
+			DACMask = 0x24;
+			muxmode = 1;
+		} else
+			DACMask = 0x04;
+		break;
 	case 15:
-	    DACMask = 0x16;
-	    break;
+		DACMask = 0x16;
+		break;
 	case 16:
-	    DACMask = 0x36;
-	    break;
+		DACMask = 0x36;
+		break;
 	case 24:
-	    DACMask = 0xE6;
-	    break;
+		DACMask = 0xE6;
+		break;
 	case 32:
-	    DACMask = 0xE6;
-	    break;
-    }
-
-    if (1 /* info->mach64DAC8Bit */)
-	DACMask |= 0x02;
-
-    aty_dac_waste4(info);
-    aty_st_8(DAC_REGS + 2, DACMask, info);
-
-    aty_st_le32(BUS_CNTL, 0x890e20f1, info);
-    aty_st_le32(DAC_CNTL, 0x00072000, info);
-    return muxmode;
+		DACMask = 0xE6;
+		break;
+	}
+
+	if (1 /* info->mach64DAC8Bit */ )
+		DACMask |= 0x02;
+
+	aty_dac_waste4(par);
+	aty_st_8(DAC_REGS + 2, DACMask, par);
+
+	aty_st_le32(BUS_CNTL, 0x890e20f1, par);
+	aty_st_le32(DAC_CNTL, 0x00072000, par);
+	return muxmode;
 }
 
 const struct aty_dac_ops aty_dac_att21c498 = {
-    set_dac:	aty_set_dac_ATT21C498,
+	set_dac:	aty_set_dac_ATT21C498,
 };
 
 
@@ -319,154 +341,155 @@
      *  ATI 18818 / ICS 2595 Clock Chip
      */
 
-static int aty_var_to_pll_18818(const struct fb_info_aty *info, u32 vclk_per,
-				u8 bpp, union aty_pll *pll)
+static int aty_var_to_pll_18818(const struct fb_info *info,
+				u32 vclk_per, u8 bpp, union aty_pll *pll)
 {
-    u32 MHz100;		/* in 0.01 MHz */
-    u32 program_bits;
-    u32 post_divider;
-
-    /* Calculate the programming word */
-    MHz100 = 100000000 / vclk_per;
-
-    program_bits = -1;
-    post_divider = 1;
-
-    if (MHz100 > MAX_FREQ_2595) {
-	MHz100 = MAX_FREQ_2595;
-	return -EINVAL;
-    } else if (MHz100 < ABS_MIN_FREQ_2595) {
-	program_bits = 0;	/* MHz100 = 257 */
-	return -EINVAL;
-    } else {
-	while (MHz100 < MIN_FREQ_2595) {
-	    MHz100 *= 2;
-	    post_divider *= 2;
+	u32 MHz100;		/* in 0.01 MHz */
+	u32 program_bits;
+	u32 post_divider;
+
+	/* Calculate the programming word */
+	MHz100 = 100000000 / vclk_per;
+
+	program_bits = -1;
+	post_divider = 1;
+
+	if (MHz100 > MAX_FREQ_2595) {
+		MHz100 = MAX_FREQ_2595;
+		return -EINVAL;
+	} else if (MHz100 < ABS_MIN_FREQ_2595) {
+		program_bits = 0;	/* MHz100 = 257 */
+		return -EINVAL;
+	} else {
+		while (MHz100 < MIN_FREQ_2595) {
+			MHz100 *= 2;
+			post_divider *= 2;
+		}
 	}
-    }
-    MHz100 *= 1000;
-    MHz100 = (REF_DIV_2595 * MHz100) / REF_FREQ_2595;
-
-    MHz100 += 500;    /* + 0.5 round */
-    MHz100 /= 1000;
-
-    if (program_bits == -1) {
-	program_bits = MHz100 - N_ADJ_2595;
-	switch (post_divider) {
-	    case 1:
-		program_bits |= 0x0600;
-		break;
-	    case 2:
-		program_bits |= 0x0400;
-		break;
-	    case 4:
-		program_bits |= 0x0200;
-		break;
-	    case 8:
-	    default:
-		break;
+	MHz100 *= 1000;
+	MHz100 = (REF_DIV_2595 * MHz100) / REF_FREQ_2595;
+ 
+	MHz100 += 500;		/* + 0.5 round */
+	MHz100 /= 1000;
+
+	if (program_bits == -1) {
+		program_bits = MHz100 - N_ADJ_2595;
+		switch (post_divider) {
+		case 1:
+			program_bits |= 0x0600;
+			break;
+		case 2:
+			program_bits |= 0x0400;
+			break;
+		case 4:
+			program_bits |= 0x0200;
+			break;
+		case 8:
+		default:
+			break;
+		}
 	}
-    }
 
-    program_bits |= STOP_BITS_2595;
+	program_bits |= STOP_BITS_2595;
 
-    pll->ics2595.program_bits = program_bits;
-    pll->ics2595.locationAddr = 0;
-    pll->ics2595.post_divider = post_divider;
-    pll->ics2595.period_in_ps = vclk_per;
+	pll->ics2595.program_bits = program_bits;
+	pll->ics2595.locationAddr = 0;
+	pll->ics2595.post_divider = post_divider;
+	pll->ics2595.period_in_ps = vclk_per;
 
-    return 0;
+	return 0;
 }
 
-static u32 aty_pll_18818_to_var(const struct fb_info_aty *info,
+static u32 aty_pll_18818_to_var(const struct fb_info *info,
 				const union aty_pll *pll)
 {
-    return(pll->ics2595.period_in_ps);  /* default for now */
+	return (pll->ics2595.period_in_ps);	/* default for now */
 }
 
-static void aty_ICS2595_put1bit(u8 data, const struct fb_info_aty *info)
+static void aty_ICS2595_put1bit(u8 data, const struct atyfb_par *par)
 {
-    u8 tmp;
+	u8 tmp;
 
-    data &= 0x01;
-    tmp = aty_ld_8(CLOCK_CNTL, info);
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x04) | (data << 2),
-	     info);
+	data &= 0x01;
+	tmp = aty_ld_8(CLOCK_CNTL, par);
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset,
+		 (tmp & ~0x04) | (data << 2), par);
 
-    tmp = aty_ld_8(CLOCK_CNTL, info);
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x08) | (0 << 3), info);
+	tmp = aty_ld_8(CLOCK_CNTL, par);
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset, (tmp & ~0x08) | (0 << 3),
+		 par);
 
-    aty_StrobeClock(info);
+	aty_StrobeClock(par);
 
-    tmp = aty_ld_8(CLOCK_CNTL, info);
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x08) | (1 << 3), info);
+	tmp = aty_ld_8(CLOCK_CNTL, par);
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset, (tmp & ~0x08) | (1 << 3),
+		 par);
 
-    aty_StrobeClock(info);
-
-    return;
+	aty_StrobeClock(par);
+	return;
 }
 
-static void aty_set_pll18818(const struct fb_info_aty *info,
+static void aty_set_pll18818(const struct fb_info *info,
 			     const union aty_pll *pll)
 {
-    u32 program_bits;
-    u32 locationAddr;
-
-    u32 i;
-
-    u8 old_clock_cntl;
-    u8 old_crtc_ext_disp;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 program_bits;
+	u32 locationAddr;
 
-    old_clock_cntl = aty_ld_8(CLOCK_CNTL, info);
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);
+	u32 i;
 
-    old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
-    aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
-	     info);
+	u8 old_clock_cntl;
+	u8 old_crtc_ext_disp;
 
-    mdelay(15); /* delay for 50 (15) ms */
+	old_clock_cntl = aty_ld_8(CLOCK_CNTL, par);
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset, 0, par);
 
-    program_bits = pll->ics2595.program_bits;
-    locationAddr = pll->ics2595.locationAddr;
+	old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, par);
+	aty_st_8(CRTC_GEN_CNTL + 3,
+		 old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24), par);
 
-    /* Program the clock chip */
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);  /* Strobe = 0 */
-    aty_StrobeClock(info);
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 1, info);  /* Strobe = 0 */
-    aty_StrobeClock(info);
+	mdelay(15);		/* delay for 50 (15) ms */
 
-    aty_ICS2595_put1bit(1, info);    /* Send start bits */
-    aty_ICS2595_put1bit(0, info);    /* Start bit */
-    aty_ICS2595_put1bit(0, info);    /* Read / ~Write */
+	program_bits = pll->ics2595.program_bits;
+	locationAddr = pll->ics2595.locationAddr;
 
-    for (i = 0; i < 5; i++) {	/* Location 0..4 */
-	aty_ICS2595_put1bit(locationAddr & 1, info);
-	locationAddr >>= 1;
-    }
+	/* Program the clock chip */
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset, 0, par);	/* Strobe = 0 */
+	aty_StrobeClock(par);
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset, 1, par);	/* Strobe = 0 */
+	aty_StrobeClock(par);
 
-    for (i = 0; i < 8 + 1 + 2 + 2; i++) {
-	aty_ICS2595_put1bit(program_bits & 1, info);
-	program_bits >>= 1;
-    }
+	aty_ICS2595_put1bit(1, par);	/* Send start bits */
+	aty_ICS2595_put1bit(0, par);	/* Start bit */
+	aty_ICS2595_put1bit(0, par);	/* Read / ~Write */
 
-    mdelay(1); /* delay for 1 ms */
+	for (i = 0; i < 5; i++) {	/* Location 0..4 */
+		aty_ICS2595_put1bit(locationAddr & 1, par);
+		locationAddr >>= 1;
+	}
 
-    (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
-    aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, old_clock_cntl | CLOCK_STROBE,
-	     info);
+	for (i = 0; i < 8 + 1 + 2 + 2; i++) {
+		aty_ICS2595_put1bit(program_bits & 1, par);
+		program_bits >>= 1;
+	}
 
-    mdelay(50); /* delay for 50 (15) ms */
-    aty_st_8(CLOCK_CNTL + info->clk_wr_offset,
-	     ((pll->ics2595.locationAddr & 0x0F) | CLOCK_STROBE), info);
+	mdelay(1);		/* delay for 1 ms */
 
-    return;
+	(void) aty_ld_8(DAC_REGS, par);	/* Clear DAC Counter */
+	aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, par);
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset,
+		 old_clock_cntl | CLOCK_STROBE, par);
+
+	mdelay(50);		/* delay for 50 (15) ms */
+	aty_st_8(CLOCK_CNTL + par->clk_wr_offset,
+		 ((pll->ics2595.locationAddr & 0x0F) | CLOCK_STROBE), par);
+	return;
 }
 
 const struct aty_pll_ops aty_pll_ati18818_1 = {
-    var_to_pll:	aty_var_to_pll_18818,
-    pll_to_var:	aty_pll_18818_to_var,
-    set_pll:	aty_set_pll18818,
+	var_to_pll:aty_var_to_pll_18818,
+	pll_to_var:aty_pll_18818_to_var,
+	set_pll:aty_set_pll18818,
 };
 
 
@@ -474,112 +497,115 @@
      *  STG 1703 Clock Chip
      */
 
-static int aty_var_to_pll_1703(const struct fb_info_aty *info, u32 vclk_per,
-			       u8 bpp, union aty_pll *pll)
+static int aty_var_to_pll_1703(const struct fb_info *info,
+			       u32 vclk_per, u8 bpp, union aty_pll *pll)
 {
-    u32 mhz100;			/* in 0.01 MHz */
-    u32 program_bits;
-    /* u32 post_divider; */
-    u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
-    u32 temp, tempB;
-    u16 remainder, preRemainder;
-    short divider = 0, tempA;
-
-    /* Calculate the programming word */
-    mhz100 = 100000000 / vclk_per;
-    mach64MinFreq = MIN_FREQ_2595;
-    mach64MaxFreq = MAX_FREQ_2595;
-    mach64RefFreq = REF_FREQ_2595;	/* 14.32 MHz */
-
-    /* Calculate program word */
-    if (mhz100 == 0)
-	program_bits = 0xE0;
-    else {
-	if (mhz100 < mach64MinFreq)
-	    mhz100 = mach64MinFreq;
-	if (mhz100 > mach64MaxFreq)
-	    mhz100 = mach64MaxFreq;
-
-	divider = 0;
-	while (mhz100 < (mach64MinFreq << 3)) {
-	    mhz100 <<= 1;
-	    divider += 0x20;
-	}
-
-	temp = (unsigned int)(mhz100);
-	temp = (unsigned int)(temp * (MIN_N_1703 + 2));
-	temp -= (short)(mach64RefFreq << 1);
-
-	tempA = MIN_N_1703;
-	preRemainder = 0xffff;
-
-	do {
-	    tempB = temp;
-	    remainder = tempB % mach64RefFreq;
-	    tempB = tempB / mach64RefFreq;
-
-	    if ((tempB & 0xffff) <= 127 && (remainder <= preRemainder)) {
-		preRemainder = remainder;
-		divider &= ~0x1f;
-		divider |= tempA;
-		divider = (divider & 0x00ff) + ((tempB & 0xff) << 8);
-	    }
-
-	    temp += mhz100;
-	    tempA++;
-	} while (tempA <= (MIN_N_1703 << 1));
-
-	program_bits = divider;
-    }
-
-      pll->ics2595.program_bits = program_bits;
-      pll->ics2595.locationAddr = 0;
-      pll->ics2595.post_divider = divider;  /* fuer nix */
-      pll->ics2595.period_in_ps = vclk_per;
+	u32 mhz100;		/* in 0.01 MHz */
+	u32 program_bits;
+	/* u32 post_divider; */
+	u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
+	u32 temp, tempB;
+	u16 remainder, preRemainder;
+	short divider = 0, tempA;
+
+	/* Calculate the programming word */
+	mhz100 = 100000000 / vclk_per;
+	mach64MinFreq = MIN_FREQ_2595;
+	mach64MaxFreq = MAX_FREQ_2595;
+	mach64RefFreq = REF_FREQ_2595;	/* 14.32 MHz */
+
+	/* Calculate program word */
+	if (mhz100 == 0)
+		program_bits = 0xE0;
+	else {
+		if (mhz100 < mach64MinFreq)
+			mhz100 = mach64MinFreq;
+		if (mhz100 > mach64MaxFreq)
+			mhz100 = mach64MaxFreq;
+
+		divider = 0;
+		while (mhz100 < (mach64MinFreq << 3)) {
+			mhz100 <<= 1;
+			divider += 0x20;
+		}
+
+		temp = (unsigned int) (mhz100);
+		temp = (unsigned int) (temp * (MIN_N_1703 + 2));
+		temp -= (short) (mach64RefFreq << 1);
+
+		tempA = MIN_N_1703;
+		preRemainder = 0xffff;
+
+		do {
+			tempB = temp;
+			remainder = tempB % mach64RefFreq;
+			tempB = tempB / mach64RefFreq;
+
+			if ((tempB & 0xffff) <= 127
+			    && (remainder <= preRemainder)) {
+				preRemainder = remainder;
+				divider &= ~0x1f;
+				divider |= tempA;
+				divider =
+				    (divider & 0x00ff) +
+				    ((tempB & 0xff) << 8);
+			}
+
+			temp += mhz100;
+			tempA++;
+		} while (tempA <= (MIN_N_1703 << 1));
+
+		program_bits = divider;
+	}
+
+	pll->ics2595.program_bits = program_bits;
+	pll->ics2595.locationAddr = 0;
+	pll->ics2595.post_divider = divider;	/* fuer nix */
+	pll->ics2595.period_in_ps = vclk_per;
 
-      return 0;
+	return 0;
 }
 
-static u32 aty_pll_1703_to_var(const struct fb_info_aty *info,
+static u32 aty_pll_1703_to_var(const struct fb_info *info,
 			       const union aty_pll *pll)
 {
-    return(pll->ics2595.period_in_ps);  /* default for now */
+	return (pll->ics2595.period_in_ps);	/* default for now */
 }
 
-static void aty_set_pll_1703(const struct fb_info_aty *info,
+static void aty_set_pll_1703(const struct fb_info *info,
 			     const union aty_pll *pll)
 {
-    u32 program_bits;
-    u32 locationAddr;
-
-    char old_crtc_ext_disp;
-
-    old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
-    aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
-	     info);
-
-    program_bits = pll->ics2595.program_bits;
-    locationAddr = pll->ics2595.locationAddr;
-
-    /* Program clock */
-    aty_dac_waste4(info);
-
-    (void)aty_ld_8(DAC_REGS + 2, info);
-    aty_st_8(DAC_REGS+2, (locationAddr << 1) + 0x20, info);
-    aty_st_8(DAC_REGS+2, 0, info);
-    aty_st_8(DAC_REGS+2, (program_bits & 0xFF00) >> 8, info);
-    aty_st_8(DAC_REGS+2, (program_bits & 0xFF), info);
-
-    (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
-    aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
-
-    return;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 program_bits;
+	u32 locationAddr;
+
+	char old_crtc_ext_disp;
+
+	old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, par);
+	aty_st_8(CRTC_GEN_CNTL + 3,
+		 old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24), par);
+
+	program_bits = pll->ics2595.program_bits;
+	locationAddr = pll->ics2595.locationAddr;
+
+	/* Program clock */
+	aty_dac_waste4(par);
+
+	(void) aty_ld_8(DAC_REGS + 2, par);
+	aty_st_8(DAC_REGS + 2, (locationAddr << 1) + 0x20, par);
+	aty_st_8(DAC_REGS + 2, 0, par);
+	aty_st_8(DAC_REGS + 2, (program_bits & 0xFF00) >> 8, par);
+	aty_st_8(DAC_REGS + 2, (program_bits & 0xFF), par);
+
+	(void) aty_ld_8(DAC_REGS, par);	/* Clear DAC Counter */
+	aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, par);
+	return;
 }
 
 const struct aty_pll_ops aty_pll_stg1703 = {
-    var_to_pll:	aty_var_to_pll_1703,
-    pll_to_var:	aty_pll_1703_to_var,
-    set_pll:	aty_set_pll_1703,
+	var_to_pll:aty_var_to_pll_1703,
+	pll_to_var:aty_pll_1703_to_var,
+	set_pll:aty_set_pll_1703,
 };
 
 
@@ -587,126 +613,123 @@
      *  Chrontel 8398 Clock Chip
      */
 
-static int aty_var_to_pll_8398(const struct fb_info_aty *info, u32 vclk_per,
-			       u8 bpp, union aty_pll *pll)
+static int aty_var_to_pll_8398(const struct fb_info *info,
+			       u32 vclk_per, u8 bpp, union aty_pll *pll)
 {
-    u32 tempA, tempB, fOut, longMHz100, diff, preDiff;
+	u32 tempA, tempB, fOut, longMHz100, diff, preDiff;
 
-    u32 mhz100;				/* in 0.01 MHz */
-    u32 program_bits;
-    /* u32 post_divider; */
-    u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
-    u16 m, n, k=0, save_m, save_n, twoToKth;
-
-    /* Calculate the programming word */
-    mhz100 = 100000000 / vclk_per;
-    mach64MinFreq = MIN_FREQ_2595;
-    mach64MaxFreq = MAX_FREQ_2595;
-    mach64RefFreq = REF_FREQ_2595;	/* 14.32 MHz */
-
-    save_m = 0;
-    save_n = 0;
-
-    /* Calculate program word */
-    if (mhz100 == 0)
-	program_bits = 0xE0;
-    else
-    {
-	if (mhz100 < mach64MinFreq)
-	    mhz100 = mach64MinFreq;
-	if (mhz100 > mach64MaxFreq)
-	    mhz100 = mach64MaxFreq;
-
-	longMHz100 = mhz100 * 256 / 100;   /* 8 bit scale this */
-
-	while (mhz100 < (mach64MinFreq << 3))
-        {
-	    mhz100 <<= 1;
-	    k++;
-	}
-
-	twoToKth = 1 << k;
-	diff = 0;
-	preDiff = 0xFFFFFFFF;
-
-	for (m = MIN_M; m <= MAX_M; m++)
-        {
-	    for (n = MIN_N; n <= MAX_N; n++)
-            {
-		tempA = (14.31818 * 65536);
-		tempA *= (n + 8);  /* 43..256 */
-		tempB = twoToKth * 256;
-		tempB *= (m + 2);  /* 4..32 */
-		fOut = tempA / tempB;  /* 8 bit scale */
-
-		if (longMHz100 > fOut)
-		    diff = longMHz100 - fOut;
-		else
-		    diff = fOut - longMHz100;
-
-		if (diff < preDiff)
-                {
-		    save_m = m;
-		    save_n = n;
-		    preDiff = diff;
+	u32 mhz100;		/* in 0.01 MHz */
+	u32 program_bits;
+	/* u32 post_divider; */
+	u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
+	u16 m, n, k = 0, save_m, save_n, twoToKth;
+
+	/* Calculate the programming word */
+	mhz100 = 100000000 / vclk_per;
+	mach64MinFreq = MIN_FREQ_2595;
+	mach64MaxFreq = MAX_FREQ_2595;
+	mach64RefFreq = REF_FREQ_2595;	/* 14.32 MHz */
+
+	save_m = 0;
+	save_n = 0;
+
+	/* Calculate program word */
+	if (mhz100 == 0)
+		program_bits = 0xE0;
+	else {
+		if (mhz100 < mach64MinFreq)
+			mhz100 = mach64MinFreq;
+		if (mhz100 > mach64MaxFreq)
+			mhz100 = mach64MaxFreq;
+
+		longMHz100 = mhz100 * 256 / 100;	/* 8 bit scale this */
+
+		while (mhz100 < (mach64MinFreq << 3)) {
+			mhz100 <<= 1;
+			k++;
 		}
-	    }
-	}
 
-	program_bits = (k << 6) + (save_m) + (save_n << 8);
-    }
+		twoToKth = 1 << k;
+		diff = 0;
+		preDiff = 0xFFFFFFFF;
+
+		for (m = MIN_M; m <= MAX_M; m++) {
+			for (n = MIN_N; n <= MAX_N; n++) {
+				tempA = (14.31818 * 65536);
+				tempA *= (n + 8);	/* 43..256 */
+				tempB = twoToKth * 256;
+				tempB *= (m + 2);	/* 4..32 */
+				fOut = tempA / tempB;	/* 8 bit scale */
+
+				if (longMHz100 > fOut)
+					diff = longMHz100 - fOut;
+				else
+					diff = fOut - longMHz100;
+
+				if (diff < preDiff) {
+					save_m = m;
+					save_n = n;
+					preDiff = diff;
+				}
+			}
+		}
 
-    pll->ics2595.program_bits = program_bits;
-    pll->ics2595.locationAddr = 0;
-    pll->ics2595.post_divider = 0;
-    pll->ics2595.period_in_ps = vclk_per;
+		program_bits = (k << 6) + (save_m) + (save_n << 8);
+	}
 
-    return 0;
+	pll->ics2595.program_bits = program_bits;
+	pll->ics2595.locationAddr = 0;
+	pll->ics2595.post_divider = 0;
+	pll->ics2595.period_in_ps = vclk_per;
+
+	return 0;
 }
 
-static u32 aty_pll_8398_to_var(const struct fb_info_aty *info,
+static u32 aty_pll_8398_to_var(const struct fb_info *info,
 			       const union aty_pll *pll)
 {
-    return(pll->ics2595.period_in_ps);  /* default for now */
+	return (pll->ics2595.period_in_ps);	/* default for now */
 }
 
-static void aty_set_pll_8398(const struct fb_info_aty *info,
+static void aty_set_pll_8398(const struct fb_info *info,
 			     const union aty_pll *pll)
 {
-    u32 program_bits;
-    u32 locationAddr;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 program_bits;
+	u32 locationAddr;
 
-    char old_crtc_ext_disp;
-    char tmp;
+	char old_crtc_ext_disp;
+	char tmp;
 
-    old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
-    aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
-	     info);
+	old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, par);
+	aty_st_8(CRTC_GEN_CNTL + 3,
+		 old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24), par);
 
-    program_bits = pll->ics2595.program_bits;
-    locationAddr = pll->ics2595.locationAddr;
+	program_bits = pll->ics2595.program_bits;
+	locationAddr = pll->ics2595.locationAddr;
 
-    /* Program clock */
-    tmp = aty_ld_8(DAC_CNTL, info);
-    aty_st_8(DAC_CNTL, tmp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, info);
+	/* Program clock */
+	tmp = aty_ld_8(DAC_CNTL, par);
+	aty_st_8(DAC_CNTL, tmp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, par);
 
-    aty_st_8(DAC_REGS, locationAddr, info);
-    aty_st_8(DAC_REGS+1, (program_bits & 0xff00) >> 8, info);
-    aty_st_8(DAC_REGS+1, (program_bits & 0xff), info);
+	aty_st_8(DAC_REGS, locationAddr, par);
+	aty_st_8(DAC_REGS + 1, (program_bits & 0xff00) >> 8, par);
+	aty_st_8(DAC_REGS + 1, (program_bits & 0xff), par);
 
-    tmp = aty_ld_8(DAC_CNTL, info);
-    aty_st_8(DAC_CNTL, (tmp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3, info);
+	tmp = aty_ld_8(DAC_CNTL, par);
+	aty_st_8(DAC_CNTL, (tmp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3,
+		 par);
 
-    (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
-    aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
+	(void) aty_ld_8(DAC_REGS, par);	/* Clear DAC Counter */
+	aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, par);
 
-    return;
+	return;
 }
 
 const struct aty_pll_ops aty_pll_ch8398 = {
-    var_to_pll:	aty_var_to_pll_8398,
-    pll_to_var:	aty_pll_8398_to_var,
-    set_pll:	aty_set_pll_8398,
+	var_to_pll:aty_var_to_pll_8398,
+	pll_to_var:aty_pll_8398_to_var,
+	set_pll:aty_set_pll_8398,
 };
 
 
@@ -714,143 +737,146 @@
      *  AT&T 20C408 Clock Chip
      */
 
-static int aty_var_to_pll_408(const struct fb_info_aty *info, u32 vclk_per,
+static int aty_var_to_pll_408(const struct fb_info *info, u32 vclk_per,
 			      u8 bpp, union aty_pll *pll)
 {
-    u32 mhz100;		/* in 0.01 MHz */
-    u32 program_bits;
-    /* u32 post_divider; */
-    u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
-    u32 temp, tempB;
-    u16 remainder, preRemainder;
-    short divider = 0, tempA;
-
-    /* Calculate the programming word */
-    mhz100 = 100000000 / vclk_per;
-    mach64MinFreq = MIN_FREQ_2595;
-    mach64MaxFreq = MAX_FREQ_2595;
-    mach64RefFreq = REF_FREQ_2595;	/* 14.32 MHz */
-
-    /* Calculate program word */
-    if (mhz100 == 0)
-	program_bits = 0xFF;
-    else {
-	if (mhz100 < mach64MinFreq)
-	    mhz100 = mach64MinFreq;
-	if (mhz100 > mach64MaxFreq)
-	    mhz100 = mach64MaxFreq;
-
-	while (mhz100 < (mach64MinFreq << 3)) {
-	    mhz100 <<= 1;
-	    divider += 0x40;
-	}
-
-	temp = (unsigned int)mhz100;
-	temp = (unsigned int)(temp * (MIN_N_408 + 2));
-	temp -= ((short)(mach64RefFreq << 1));
-
-	tempA = MIN_N_408;
-	preRemainder = 0xFFFF;
-
-	do {
-	    tempB = temp;
-	    remainder = tempB % mach64RefFreq;
-	    tempB = tempB / mach64RefFreq;
-	    if (((tempB & 0xFFFF) <= 255) && (remainder <= preRemainder)) {
-		preRemainder = remainder;
-		divider &= ~0x3f;
-		divider |= tempA;
-		divider = (divider & 0x00FF) + ((tempB & 0xFF) << 8);
-	    }
-	    temp += mhz100;
-	    tempA++;
-	} while(tempA <= 32);
-
-	program_bits = divider;
-    }
-
-    pll->ics2595.program_bits = program_bits;
-    pll->ics2595.locationAddr = 0;
-    pll->ics2595.post_divider = divider;	/* fuer nix */
-    pll->ics2595.period_in_ps = vclk_per;
+	u32 mhz100;		/* in 0.01 MHz */
+	u32 program_bits;
+	/* u32 post_divider; */
+	u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
+	u32 temp, tempB;
+	u16 remainder, preRemainder;
+	short divider = 0, tempA;
+
+	/* Calculate the programming word */
+	mhz100 = 100000000 / vclk_per;
+	mach64MinFreq = MIN_FREQ_2595;
+	mach64MaxFreq = MAX_FREQ_2595;
+	mach64RefFreq = REF_FREQ_2595;	/* 14.32 MHz */
+
+	/* Calculate program word */
+	if (mhz100 == 0)
+		program_bits = 0xFF;
+	else {
+		if (mhz100 < mach64MinFreq)
+			mhz100 = mach64MinFreq;
+		if (mhz100 > mach64MaxFreq)
+			mhz100 = mach64MaxFreq;
+
+		while (mhz100 < (mach64MinFreq << 3)) {
+			mhz100 <<= 1;
+			divider += 0x40;
+		}
+
+		temp = (unsigned int) mhz100;
+		temp = (unsigned int) (temp * (MIN_N_408 + 2));
+		temp -= ((short) (mach64RefFreq << 1));
+
+		tempA = MIN_N_408;
+		preRemainder = 0xFFFF;
+
+		do {
+			tempB = temp;
+			remainder = tempB % mach64RefFreq;
+			tempB = tempB / mach64RefFreq;
+			if (((tempB & 0xFFFF) <= 255)
+			    && (remainder <= preRemainder)) {
+				preRemainder = remainder;
+				divider &= ~0x3f;
+				divider |= tempA;
+				divider =
+				    (divider & 0x00FF) +
+				    ((tempB & 0xFF) << 8);
+			}
+			temp += mhz100;
+			tempA++;
+		} while (tempA <= 32);
+
+		program_bits = divider;
+	}
 
-    return 0;
+	pll->ics2595.program_bits = program_bits;
+	pll->ics2595.locationAddr = 0;
+	pll->ics2595.post_divider = divider;	/* fuer nix */
+	pll->ics2595.period_in_ps = vclk_per;
+
+	return 0;
 }
 
-static u32 aty_pll_408_to_var(const struct fb_info_aty *info,
+static u32 aty_pll_408_to_var(const struct fb_info *info,
 			      const union aty_pll *pll)
 {
-    return(pll->ics2595.period_in_ps);  /* default for now */
+	return (pll->ics2595.period_in_ps);	/* default for now */
 }
 
-static void aty_set_pll_408(const struct fb_info_aty *info,
+static void aty_set_pll_408(const struct fb_info *info,
 			    const union aty_pll *pll)
 {
-    u32 program_bits;
-    u32 locationAddr;
-
-    u8 tmpA, tmpB, tmpC;
-    char old_crtc_ext_disp;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 program_bits;
+	u32 locationAddr;
 
-    old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
-    aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
-	     info);
+	u8 tmpA, tmpB, tmpC;
+	char old_crtc_ext_disp;
 
-    program_bits = pll->ics2595.program_bits;
-    locationAddr = pll->ics2595.locationAddr;
+	old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, par);
+	aty_st_8(CRTC_GEN_CNTL + 3,
+		 old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24), par);
 
-    /* Program clock */
-    aty_dac_waste4(info);
-    tmpB = aty_ld_8(DAC_REGS + 2, info) | 1;
-    aty_dac_waste4(info);
-    aty_st_8(DAC_REGS + 2, tmpB, info);
+	program_bits = pll->ics2595.program_bits;
+	locationAddr = pll->ics2595.locationAddr;
 
-    tmpA = tmpB;
-    tmpC = tmpA;
-    tmpA |= 8;
-    tmpB = 1;
+	/* Program clock */
+	aty_dac_waste4(par);
+	tmpB = aty_ld_8(DAC_REGS + 2, par) | 1;
+	aty_dac_waste4(par);
+	aty_st_8(DAC_REGS + 2, tmpB, par);
 
-    aty_st_8(DAC_REGS, tmpB, info);
-    aty_st_8(DAC_REGS + 2, tmpA, info);
+	tmpA = tmpB;
+	tmpC = tmpA;
+	tmpA |= 8;
+	tmpB = 1;
 
-    udelay(400); /* delay for 400 us */
+	aty_st_8(DAC_REGS, tmpB, par);
+	aty_st_8(DAC_REGS + 2, tmpA, par);
 
-    locationAddr = (locationAddr << 2) + 0x40;
-    tmpB = locationAddr;
-    tmpA = program_bits >> 8;
+	udelay(400);		/* delay for 400 us */
 
-    aty_st_8(DAC_REGS, tmpB, info);
-    aty_st_8(DAC_REGS + 2, tmpA, info);
+	locationAddr = (locationAddr << 2) + 0x40;
+	tmpB = locationAddr;
+	tmpA = program_bits >> 8;
 
-    tmpB = locationAddr + 1;
-    tmpA = (u8)program_bits;
+	aty_st_8(DAC_REGS, tmpB, par);
+	aty_st_8(DAC_REGS + 2, tmpA, par);
 
-    aty_st_8(DAC_REGS, tmpB, info);
-    aty_st_8(DAC_REGS + 2, tmpA, info);
+	tmpB = locationAddr + 1;
+	tmpA = (u8) program_bits;
 
-    tmpB = locationAddr + 2;
-    tmpA = 0x77;
+	aty_st_8(DAC_REGS, tmpB, par);
+	aty_st_8(DAC_REGS + 2, tmpA, par);
 
-    aty_st_8(DAC_REGS, tmpB, info);
-    aty_st_8(DAC_REGS + 2, tmpA, info);
+	tmpB = locationAddr + 2;
+	tmpA = 0x77;
 
-    udelay(400); /* delay for 400 us */
-    tmpA = tmpC & (~(1 | 8));
-    tmpB = 1;
+	aty_st_8(DAC_REGS, tmpB, par);
+	aty_st_8(DAC_REGS + 2, tmpA, par);
 
-    aty_st_8(DAC_REGS, tmpB, info);
-    aty_st_8(DAC_REGS + 2, tmpA, info);
+	udelay(400);		/* delay for 400 us */
+	tmpA = tmpC & (~(1 | 8));
+	tmpB = 1;
 
-    (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
-    aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
+	aty_st_8(DAC_REGS, tmpB, par);
+	aty_st_8(DAC_REGS + 2, tmpA, par);
 
-    return;
+	(void) aty_ld_8(DAC_REGS, par);	/* Clear DAC Counter */
+	aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, par);
+	return;
 }
 
 const struct aty_pll_ops aty_pll_att20c408 = {
-    var_to_pll:	aty_var_to_pll_408,
-    pll_to_var:	aty_pll_408_to_var,
-    set_pll:	aty_set_pll_408,
+	var_to_pll:aty_var_to_pll_408,
+	pll_to_var:aty_pll_408_to_var,
+	set_pll:aty_set_pll_408,
 };
 
 
@@ -858,30 +884,31 @@
      *  Unsupported DAC and Clock Chip
      */
 
-static int aty_set_dac_unsupported(const struct fb_info_aty *info,
+static int aty_set_dac_unsupported(const struct fb_info *info,
 				   const union aty_pll *pll, u32 bpp,
 				   u32 accel)
 {
-    aty_st_le32(BUS_CNTL, 0x890e20f1, info);
-    aty_st_le32(DAC_CNTL, 0x47052100, info);
-    /* new in 2.2.3p1 from Geert. ???????? */
-    aty_st_le32(BUS_CNTL, 0x590e10ff, info);
-    aty_st_le32(DAC_CNTL, 0x47012100, info);
-    return 0;
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+
+	aty_st_le32(BUS_CNTL, 0x890e20f1, par);
+	aty_st_le32(DAC_CNTL, 0x47052100, par);
+	/* new in 2.2.3p1 from Geert. ???????? */
+	aty_st_le32(BUS_CNTL, 0x590e10ff, par);
+	aty_st_le32(DAC_CNTL, 0x47012100, par);
+	return 0;
 }
 
 static int dummy(void)
 {
-    return 0;
+	return 0;
 }
 
 const struct aty_dac_ops aty_dac_unsupported = {
-    set_dac:	aty_set_dac_unsupported,
+	set_dac:aty_set_dac_unsupported,
 };
 
 const struct aty_pll_ops aty_pll_unsupported = {
-    var_to_pll:	(void *)dummy,
-    pll_to_var:	(void *)dummy,
-    set_pll:	(void *)dummy,
+	var_to_pll:(void *) dummy,
+	pll_to_var:(void *) dummy,
+	set_pll:(void *) dummy,
 };
-
diff -Nru a/drivers/video/aty128.h b/drivers/video/aty128.h
--- a/drivers/video/aty128.h	Wed Jul 24 14:03:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,352 +0,0 @@
-/*  $Id: aty128.h,v 1.1 1999/10/12 11:00:40 geert Exp $
- *  linux/drivers/video/aty128.h
- *  Register definitions for ATI Rage128 boards
- *
- *  Anthony Tong <atong@uiuc.edu>, 1999
- *  Brad Douglas <brad@neruo.com>, 2000
- */
-
-#ifndef REG_RAGE128_H
-#define REG_RAGE128_H
-
-#define CLOCK_CNTL_INDEX			0x0008
-#define CLOCK_CNTL_DATA				0x000c
-#define BIOS_0_SCRATCH				0x0010
-#define BUS_CNTL				0x0030
-#define GEN_INT_CNTL				0x0040
-#define CRTC_GEN_CNTL				0x0050
-#define CRTC_EXT_CNTL				0x0054
-#define DAC_CNTL				0x0058
-#define I2C_CNTL_1				0x0094
-#define PALETTE_INDEX				0x00b0
-#define PALETTE_DATA				0x00b4
-#define CONFIG_CNTL				0x00e0
-#define GEN_RESET_CNTL				0x00f0
-#define CONFIG_MEMSIZE				0x00f8
-#define MEM_CNTL				0x0140
-#define AGP_BASE				0x0170
-#define AGP_CNTL				0x0174
-#define AGP_APER_OFFSET				0x0178
-#define PCI_GART_PAGE				0x017c
-#define PC_NGUI_MODE				0x0180
-#define PC_NGUI_CTLSTAT				0x0184
-#define MPP_TB_CONFIG				0x01C0
-#define MPP_GP_CONFIG				0x01C8
-#define VIPH_CONTROL				0x01D0
-#define CRTC_H_TOTAL_DISP			0x0200
-#define CRTC_H_SYNC_STRT_WID			0x0204
-#define CRTC_V_TOTAL_DISP			0x0208
-#define CRTC_V_SYNC_STRT_WID			0x020c
-#define CRTC_OFFSET				0x0224
-#define CRTC_OFFSET_CNTL			0x0228
-#define CRTC_PITCH				0x022c
-#define OVR_CLR					0x0230
-#define OVR_WID_LEFT_RIGHT			0x0234
-#define OVR_WID_TOP_BOTTOM			0x0238
-#define LVDS_GEN_CNTL				0x02d0
-#define DDA_CONFIG				0x02e0
-#define DDA_ON_OFF				0x02e4
-#define VGA_DDA_CONFIG				0x02e8
-#define VGA_DDA_ON_OFF				0x02ec
-#define OV0_SCALE_CNTL				0x0420
-#define SUBPIC_CNTL				0x0540
-#define PM4_BUFFER_OFFSET			0x0700
-#define PM4_BUFFER_CNTL				0x0704
-#define PM4_BUFFER_WM_CNTL			0x0708
-#define PM4_BUFFER_DL_RPTR_ADDR			0x070c
-#define PM4_BUFFER_DL_RPTR			0x0710
-#define PM4_BUFFER_DL_WPTR			0x0714
-#define PM4_VC_FPU_SETUP			0x071c
-#define PM4_FPU_CNTL				0x0720
-#define PM4_VC_FORMAT				0x0724
-#define PM4_VC_CNTL				0x0728
-#define PM4_VC_I01				0x072c
-#define PM4_VC_VLOFF				0x0730
-#define PM4_VC_VLSIZE				0x0734
-#define PM4_IW_INDOFF				0x0738
-#define PM4_IW_INDSIZE				0x073c
-#define PM4_FPU_FPX0				0x0740
-#define PM4_FPU_FPY0				0x0744
-#define PM4_FPU_FPX1				0x0748
-#define PM4_FPU_FPY1				0x074c
-#define PM4_FPU_FPX2				0x0750
-#define PM4_FPU_FPY2				0x0754
-#define PM4_FPU_FPY3				0x0758
-#define PM4_FPU_FPY4				0x075c
-#define PM4_FPU_FPY5				0x0760
-#define PM4_FPU_FPY6				0x0764
-#define PM4_FPU_FPR				0x0768
-#define PM4_FPU_FPG				0x076c
-#define PM4_FPU_FPB				0x0770
-#define PM4_FPU_FPA				0x0774
-#define PM4_FPU_INTXY0				0x0780
-#define PM4_FPU_INTXY1				0x0784
-#define PM4_FPU_INTXY2				0x0788
-#define PM4_FPU_INTARGB				0x078c
-#define PM4_FPU_FPTWICEAREA			0x0790
-#define PM4_FPU_DMAJOR01			0x0794
-#define PM4_FPU_DMAJOR12			0x0798
-#define PM4_FPU_DMAJOR02			0x079c
-#define PM4_FPU_STAT				0x07a0
-#define PM4_STAT				0x07b8
-#define PM4_TEST_CNTL				0x07d0
-#define PM4_MICROCODE_ADDR			0x07d4
-#define PM4_MICROCODE_RADDR			0x07d8
-#define PM4_MICROCODE_DATAH			0x07dc
-#define PM4_MICROCODE_DATAL			0x07e0
-#define PM4_CMDFIFO_ADDR			0x07e4
-#define PM4_CMDFIFO_DATAH			0x07e8
-#define PM4_CMDFIFO_DATAL			0x07ec
-#define PM4_BUFFER_ADDR				0x07f0
-#define PM4_BUFFER_DATAH			0x07f4
-#define PM4_BUFFER_DATAL			0x07f8
-#define PM4_MICRO_CNTL				0x07fc
-#define CAP0_TRIG_CNTL				0x0950
-#define CAP1_TRIG_CNTL				0x09c0
-
-/******************************************************************************
- *                  GUI Block Memory Mapped Registers                         *
- *                     These registers are FIFOed.                            *
- *****************************************************************************/
-#define PM4_FIFO_DATA_EVEN			0x1000
-#define PM4_FIFO_DATA_ODD			0x1004
-
-#define DST_OFFSET				0x1404
-#define DST_PITCH				0x1408
-#define DST_WIDTH				0x140c
-#define DST_HEIGHT				0x1410
-#define SRC_X					0x1414
-#define SRC_Y					0x1418
-#define DST_X					0x141c
-#define DST_Y					0x1420
-#define SRC_PITCH_OFFSET			0x1428
-#define DST_PITCH_OFFSET			0x142c
-#define SRC_Y_X					0x1434
-#define DST_Y_X					0x1438
-#define DST_HEIGHT_WIDTH			0x143c
-#define DP_GUI_MASTER_CNTL			0x146c
-#define BRUSH_SCALE				0x1470
-#define BRUSH_Y_X				0x1474
-#define DP_BRUSH_BKGD_CLR			0x1478
-#define DP_BRUSH_FRGD_CLR			0x147c
-#define DST_WIDTH_X				0x1588
-#define DST_HEIGHT_WIDTH_8			0x158c
-#define SRC_X_Y					0x1590
-#define DST_X_Y					0x1594
-#define DST_WIDTH_HEIGHT			0x1598
-#define DST_WIDTH_X_INCY			0x159c
-#define DST_HEIGHT_Y				0x15a0
-#define DST_X_SUB				0x15a4
-#define DST_Y_SUB				0x15a8
-#define SRC_OFFSET				0x15ac
-#define SRC_PITCH				0x15b0
-#define DST_HEIGHT_WIDTH_BW			0x15b4
-#define CLR_CMP_CNTL				0x15c0
-#define CLR_CMP_CLR_SRC				0x15c4
-#define CLR_CMP_CLR_DST				0x15c8
-#define CLR_CMP_MASK				0x15cc
-#define DP_SRC_FRGD_CLR				0x15d8
-#define DP_SRC_BKGD_CLR				0x15dc
-#define DST_BRES_ERR				0x1628
-#define DST_BRES_INC				0x162c
-#define DST_BRES_DEC				0x1630
-#define DST_BRES_LNTH				0x1634
-#define DST_BRES_LNTH_SUB			0x1638
-#define SC_LEFT					0x1640
-#define SC_RIGHT				0x1644
-#define SC_TOP					0x1648
-#define SC_BOTTOM				0x164c
-#define SRC_SC_RIGHT				0x1654
-#define SRC_SC_BOTTOM				0x165c
-#define GUI_DEBUG0				0x16a0
-#define GUI_DEBUG1				0x16a4
-#define GUI_TIMEOUT				0x16b0
-#define GUI_TIMEOUT0				0x16b4
-#define GUI_TIMEOUT1				0x16b8
-#define GUI_PROBE				0x16bc
-#define DP_CNTL					0x16c0
-#define DP_DATATYPE				0x16c4
-#define DP_MIX					0x16c8
-#define DP_WRITE_MASK				0x16cc
-#define DP_CNTL_XDIR_YDIR_YMAJOR		0x16d0
-#define DEFAULT_OFFSET				0x16e0
-#define DEFAULT_PITCH				0x16e4
-#define DEFAULT_SC_BOTTOM_RIGHT			0x16e8
-#define SC_TOP_LEFT				0x16ec
-#define SC_BOTTOM_RIGHT				0x16f0
-#define SRC_SC_BOTTOM_RIGHT			0x16f4
-#define WAIT_UNTIL				0x1720
-#define CACHE_CNTL				0x1724
-#define GUI_STAT				0x1740
-#define PC_GUI_MODE				0x1744
-#define PC_GUI_CTLSTAT				0x1748
-#define PC_DEBUG_MODE				0x1760
-#define BRES_DST_ERR_DEC			0x1780
-#define TRAIL_BRES_T12_ERR_DEC			0x1784
-#define TRAIL_BRES_T12_INC			0x1788
-#define DP_T12_CNTL				0x178c
-#define DST_BRES_T1_LNTH			0x1790
-#define DST_BRES_T2_LNTH			0x1794
-#define SCALE_SRC_HEIGHT_WIDTH			0x1994
-#define SCALE_OFFSET_0				0x1998
-#define SCALE_PITCH				0x199c
-#define SCALE_X_INC				0x19a0
-#define SCALE_Y_INC				0x19a4
-#define SCALE_HACC				0x19a8
-#define SCALE_VACC				0x19ac
-#define SCALE_DST_X_Y				0x19b0
-#define SCALE_DST_HEIGHT_WIDTH			0x19b4
-#define SCALE_3D_CNTL				0x1a00
-#define SCALE_3D_DATATYPE			0x1a20
-#define SETUP_CNTL				0x1bc4
-#define SOLID_COLOR				0x1bc8
-#define WINDOW_XY_OFFSET			0x1bcc
-#define DRAW_LINE_POINT				0x1bd0
-#define SETUP_CNTL_PM4				0x1bd4
-#define DST_PITCH_OFFSET_C			0x1c80
-#define DP_GUI_MASTER_CNTL_C			0x1c84
-#define SC_TOP_LEFT_C				0x1c88
-#define SC_BOTTOM_RIGHT_C			0x1c8c
-
-#define CLR_CMP_MASK_3D				0x1A28
-#define MISC_3D_STATE_CNTL_REG			0x1CA0
-#define MC_SRC1_CNTL				0x19D8
-#define TEX_CNTL				0x1800
-
-/* CONSTANTS */
-#define GUI_ACTIVE				0x80000000
-#define ENGINE_IDLE				0x0
-
-#define PLL_WR_EN				0x00000080
-
-#define CLK_PIN_CNTL				0x0001
-#define PPLL_CNTL				0x0002
-#define PPLL_REF_DIV				0x0003
-#define PPLL_DIV_0				0x0004
-#define PPLL_DIV_1				0x0005
-#define PPLL_DIV_2				0x0006
-#define PPLL_DIV_3				0x0007
-#define VCLK_ECP_CNTL				0x0008
-#define HTOTAL_CNTL				0x0009
-#define X_MPLL_REF_FB_DIV			0x000a
-#define XPLL_CNTL				0x000b
-#define XDLL_CNTL				0x000c
-#define XCLK_CNTL				0x000d
-#define MPLL_CNTL				0x000e
-#define MCLK_CNTL				0x000f
-#define AGP_PLL_CNTL				0x0010
-#define FCP_CNTL				0x0012
-#define PLL_TEST_CNTL				0x0013
-
-#define PPLL_RESET				0x01
-#define PPLL_ATOMIC_UPDATE_EN			0x10000
-#define PPLL_VGA_ATOMIC_UPDATE_EN		0x20000
-#define PPLL_REF_DIV_MASK			0x3FF
-#define PPLL_FB3_DIV_MASK			0x7FF
-#define PPLL_POST3_DIV_MASK			0x70000
-#define PPLL_ATOMIC_UPDATE_R			0x8000
-#define PPLL_ATOMIC_UPDATE_W			0x8000
-#define MEM_CFG_TYPE_MASK			0x3
-#define XCLK_SRC_SEL_MASK			0x7
-#define XPLL_FB_DIV_MASK			0xFF00
-#define X_MPLL_REF_DIV_MASK			0xFF
-
-/* CRTC control values (CRTC_GEN_CNTL) */
-#define CRTC_CSYNC_EN				0x00000010
-
-#define CRTC_PIX_WIDTH_MASK			0x00000700
-#define CRTC_PIX_WIDTH_4BPP			0x00000100
-#define CRTC_PIX_WIDTH_8BPP			0x00000200
-#define CRTC_PIX_WIDTH_15BPP			0x00000300
-#define CRTC_PIX_WIDTH_16BPP			0x00000400
-#define CRTC_PIX_WIDTH_24BPP			0x00000500
-#define CRTC_PIX_WIDTH_32BPP			0x00000600
-
-/* DAC_CNTL bit constants */                       
-#define DAC_8BIT_EN				0x00000100
-#define DAC_MASK				0xFF000000
-#define DAC_BLANKING				0x00000004
-#define DAC_RANGE_CNTL				0x00000003
-#define DAC_RANGE_CNTL				0x00000003
-#define DAC_PALETTE_ACCESS_CNTL			0x00000020
-#define DAC_PDWN				0x00008000
-
-/* GEN_RESET_CNTL bit constants */
-#define SOFT_RESET_GUI				0x00000001
-#define SOFT_RESET_VCLK				0x00000100
-#define SOFT_RESET_PCLK				0x00000200
-#define SOFT_RESET_ECP				0x00000400
-#define SOFT_RESET_DISPENG_XCLK			0x00000800
-
-/* PC_GUI_CTLSTAT bit constants */
-#define PC_BUSY_INIT				0x10000000                 
-#define PC_BUSY_GUI				0x20000000                 
-#define PC_BUSY_NGUI				0x40000000
-#define PC_BUSY					0x80000000
-
-#define BUS_MASTER_DIS				0x00000040
-#define PM4_BUFFER_CNTL_NONPM4			0x00000000
-
-/* DP_DATATYPE bit constants */
-#define DST_8BPP				0x00000002
-#define DST_15BPP				0x00000003
-#define DST_16BPP				0x00000004
-#define DST_24BPP				0x00000005
-#define DST_32BPP				0x00000006
-
-#define BRUSH_SOLIDCOLOR			0x00000d00
-
-/* DP_GUI_MASTER_CNTL bit constants */
-#define	GMC_SRC_PITCH_OFFSET_DEFAULT		0x00000000
-#define GMC_DST_PITCH_OFFSET_DEFAULT		0x00000000
-#define GMC_SRC_CLIP_DEFAULT			0x00000000
-#define GMC_DST_CLIP_DEFAULT			0x00000000
-#define GMC_BRUSH_SOLIDCOLOR			0x000000d0
-#define GMC_SRC_DSTCOLOR			0x00003000
-#define GMC_BYTE_ORDER_MSB_TO_LSB		0x00000000
-#define GMC_DP_SRC_RECT				0x02000000
-#define GMC_3D_FCN_EN_CLR			0x00000000
-#define GMC_AUX_CLIP_CLEAR			0x20000000
-#define GMC_DST_CLR_CMP_FCN_CLEAR		0x10000000
-#define GMC_WRITE_MASK_SET			0x40000000
-#define GMC_DP_CONVERSION_TEMP_6500		0x00000000
-
-/* DP_GUI_MASTER_CNTL ROP3 named constants */
-#define	ROP3_PATCOPY				0x00f00000
-#define ROP3_SRCCOPY				0x00cc0000
-
-#define SRC_DSTCOLOR				0x00030000
-
-/* DP_CNTL bit constants */
-#define DST_X_RIGHT_TO_LEFT			0x00000000
-#define DST_X_LEFT_TO_RIGHT			0x00000001
-#define DST_Y_BOTTOM_TO_TOP			0x00000000
-#define DST_Y_TOP_TO_BOTTOM			0x00000002
-#define DST_X_MAJOR				0x00000000
-#define DST_Y_MAJOR				0x00000004
-#define DST_X_TILE				0x00000008
-#define DST_Y_TILE				0x00000010
-#define DST_LAST_PEL				0x00000020
-#define DST_TRAIL_X_RIGHT_TO_LEFT		0x00000000
-#define DST_TRAIL_X_LEFT_TO_RIGHT		0x00000040
-#define DST_TRAP_FILL_RIGHT_TO_LEFT		0x00000000
-#define DST_TRAP_FILL_LEFT_TO_RIGHT		0x00000080
-#define DST_BRES_SIGN				0x00000100
-#define DST_HOST_BIG_ENDIAN_EN			0x00000200
-#define DST_POLYLINE_NONLAST			0x00008000
-#define DST_RASTER_STALL			0x00010000
-#define DST_POLY_EDGE				0x00040000
-
-/* DP_MIX bit constants */
-#define DP_SRC_RECT				0x00000200
-#define DP_SRC_HOST				0x00000300
-#define DP_SRC_HOST_BYTEALIGN			0x00000400
-
-/* LVDS_GEN_CNTL constants */
-#define LVDS_BL_MOD_LEVEL_MASK			0x0000ff00
-#define LVDS_BL_MOD_LEVEL_SHIFT			8
-#define LVDS_BL_MOD_EN				0x00010000
-#define LVDS_DIGION				0x00040000
-#define LVDS_BLON				0x00080000
-
-#endif /* REG_RAGE128_H */
diff -Nru a/drivers/video/aty128fb.c b/drivers/video/aty128fb.c
--- a/drivers/video/aty128fb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/aty128fb.c	Wed Jul 24 14:03:38 2002
@@ -67,9 +67,6 @@
 #include <asm/backlight.h>
 #endif
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-#endif
 #ifdef CONFIG_BOOTX_TEXT
 #include <asm/btext.h>
 #endif /* CONFIG_BOOTX_TEXT */
@@ -84,7 +81,7 @@
 #include <asm/mtrr.h>
 #endif
 
-#include "aty128.h"
+#include <video/aty128.h>
 
 /* Debug flag */
 #undef DEBUG
@@ -1231,27 +1228,6 @@
     if (par->accel_flags & FB_ACCELF_TEXT)
         aty128_init_engine(par, info);
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-    if (!console_fb_info || console_fb_info == &info->fb_info) {
-        struct fb_var_screeninfo var;
-        int cmode, vmode;
-
-	display_info.height = ((par->crtc.v_total >> 16) & 0x7ff) + 1;
-	display_info.width = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;
-	display_info.depth = par->crtc.bpp;
-	display_info.pitch = (par->crtc.vxres * par->crtc.bpp) >> 3;
-        aty128_encode_var(&var, par, info);
-	if (mac_var_to_vmode(&var, &vmode, &cmode))
-	    display_info.mode = 0;
-	else
-	    display_info.mode = vmode;
-	strcpy(display_info.name, aty128fb_name);
-	display_info.fb_address = info->frame_buffer_phys;
-	display_info.cmap_adr_address = 0;
-	display_info.cmap_data_address = 0;
-	display_info.disp_reg_address = info->regbase_phys;
-    }
-#endif /* CONFIG_FB_COMPAT_XPMAC */
 #if defined(CONFIG_BOOTX_TEXT)
 	btext_update_display(info->frame_buffer_phys,
 			(((par->crtc.h_total>>16) & 0xff)+1)*8,
@@ -1772,7 +1748,7 @@
 
     board_list = aty128_board_list_add(board_list, info);
 
-    size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 32;
+    size = (var.bits_per_pixel <= 8) ? 256 : 32;
     fb_alloc_cmap(info->fb_info.cmap, size, 0);	
 
     if (register_framebuffer(&info->fb_info) < 0)
@@ -1927,12 +1903,6 @@
 		printk(KERN_INFO "aty128fb: Rage128 MTRR set to ON\n");
 	}
 #endif /* CONFIG_MTRR */
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-    if (!console_fb_info)
-	console_fb_info = &info->fb_info;
-#endif
-
 	return 0;
 
 err_out:
diff -Nru a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
--- a/drivers/video/chipsfb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/chipsfb.c	Wed Jul 24 14:03:38 2002
@@ -31,10 +31,6 @@
 #include <linux/pci.h>
 #include <asm/io.h>
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-#include <asm/pci-bridge.h>
-#endif
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
 #endif
@@ -359,11 +355,6 @@
 	disp->visual = fix->visual;
 	disp->var = *var;
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-	display_info.depth = bpp;
-	display_info.pitch = fix->line_length;
-#endif
-	
 	if (p->info.changevar)
 		(*p->info.changevar)(con);
 
@@ -574,26 +565,6 @@
 		GET_FB_IDX(p->info.node), p->fix.smem_len / 1024);
 
 	chips_hw_init(p);
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-	if (!console_fb_info) {
-		unsigned long iobase;
-
-		display_info.height = p->var.yres;
-		display_info.width = p->var.xres;
-		display_info.depth = 8;
-		display_info.pitch = p->fix.line_length;
-		display_info.mode = VMODE_800_600_60;
-		strncpy(display_info.name, "chips65550",
-			sizeof(display_info.name));
-		display_info.fb_address = p->frame_buffer_phys;
-		iobase = pci_bus_io_base_phys(p->pdev->bus->number);
-		display_info.cmap_adr_address = iobase + 0x3c8;
-		display_info.cmap_data_address = iobase + 0x3c9;
-		display_info.disp_reg_address = p->blitter_regs_phys;
-		console_fb_info = &p->info;
-	}
-#endif /* CONFIG_FB_COMPAT_XPMAC */
 
 #ifdef CONFIG_PMAC_PBOOK
 	if (all_chips == NULL)
diff -Nru a/drivers/video/controlfb.c b/drivers/video/controlfb.c
--- a/drivers/video/controlfb.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/controlfb.c	Wed Jul 24 14:03:36 2002
@@ -43,9 +43,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/nvram.h>
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-#endif
 #include <linux/adb.h>
 #include <linux/cuda.h>
 #include <asm/io.h>
@@ -707,24 +704,6 @@
 	/* Turn on display */
 	out_le32(CNTRL_REG(p,ctrl), par->ctrl);
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-	/* And let the world know the truth. */
-	if (!console_fb_info || console_fb_info == &p->info) {
-		display_info.height = p->par.yres;
-		display_info.width = p->par.xres;
-		display_info.depth = (cmode == CMODE_32) ? 32 :
-			((cmode == CMODE_16) ? 16 : 8);
-		display_info.pitch = p->par.pitch;
-		display_info.mode = p->par.vmode;
-		strncpy(display_info.name, "control",
-			sizeof(display_info.name));
-		display_info.fb_address = p->frame_buffer_phys + CTRLFB_OFF;
-		display_info.cmap_adr_address = p->cmap_regs_phys;
-		display_info.cmap_data_address = p->cmap_regs_phys + 0x30;
-		display_info.disp_reg_address = p->control_regs_phys;
-		console_fb_info = &p->info;
-	}
-#endif /* CONFIG_FB_COMPAT_XPMAC */
 #ifdef CONFIG_BOOTX_TEXT
 	btext_update_display(p->frame_buffer_phys + CTRLFB_OFF,
 			     p->par.xres, p->par.yres,
diff -Nru a/drivers/video/dnfb.c b/drivers/video/dnfb.c
--- a/drivers/video/dnfb.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/dnfb.c	Wed Jul 24 14:03:37 2002
@@ -115,7 +115,7 @@
 
 /* frame buffer operations */
 
-static int dn_fb_blank(int blank, struct fb_info *info);
+static int dnfb_blank(int blank, struct fb_info *info);
 static void dnfb_copyarea(struct fb_info *info, struct fb_copyarea *area);
 
 static struct fb_ops dn_fb_ops = {
@@ -165,7 +165,6 @@
 {
 
 	int incr, y_delta, pre_read = 0, x_end, x_word_count;
-	int x_count, y_count;
 	ushort *src, dummy;
 	uint start_mask, end_mask, dest;
 	short i, j;
@@ -173,13 +172,13 @@
 	incr = (area->dy <= area->sy) ? 1 : -1;
 
 	src =
-	    (ushort *) (info->screen_base + area->sy * info->fix.next_line +
+	    (ushort *) (info->screen_base + area->sy * info->fix.line_length +
 			(area->sx >> 4));
-	dest = area->dy * (info->fix.next_line >> 1) + (area->dx >> 4);
+	dest = area->dy * (info->fix.line_length >> 1) + (area->dx >> 4);
 
 	if (incr > 0) {
-		y_delta = (info->fix.next_line * 8) - area->sx - x_count;
-		x_end = area->dx + x_count - 1;
+		y_delta = (info->fix.line_length * 8) - area->sx - area->width;
+		x_end = area->dx + area->width - 1;
 		x_word_count = (x_end >> 4) - (area->dx >> 4) + 1;
 		start_mask = 0xffff0000 >> (area->dx & 0xf);
 		end_mask = 0x7ffff >> (x_end & 0xf);
@@ -188,8 +187,8 @@
 		if ((area->dx & 0xf) < (area->sx & 0xf))
 			pre_read = 1;
 	} else {
-		y_delta = -((info->fix.next_line * 8) - area->sx - x_count);
-		x_end = area->dx - x_count + 1;
+		y_delta = -((info->fix.line_length * 8) - area->sx - area->width);
+		x_end = area->dx - area->width + 1;
 		x_word_count = (area->dx >> 4) - (x_end >> 4) + 1;
 		start_mask = 0x7ffff >> (area->dx & 0xf);
 		end_mask = 0xffff0000 >> (x_end & 0xf);
@@ -199,7 +198,7 @@
 			pre_read = 1;
 	}
 
-	for (i = 0; i < y_count; i++) {
+	for (i = 0; i < area->height; i++) {
 
 		outb(0xc | (dest >> 16), AP_CONTROL_3A);
 
@@ -242,7 +241,7 @@
 {
 	int err;
 
-	strcpy(&fb_info.modename, dnfb_fix);
+	strcpy(fb_info.modename, dnfb_fix.id);
 	fb_info.changevar = NULL;
 	fb_info.fontname[0] = 0;
 	fb_info.disp = &disp;
diff -Nru a/drivers/video/fbcon-mac.c b/drivers/video/fbcon-mac.c
--- a/drivers/video/fbcon-mac.c	Wed Jul 24 14:03:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,483 +0,0 @@
-/*
- *  linux/drivers/video/fbcon-mac.c -- Low level frame buffer operations for 
- *				       x bpp packed pixels, font width != 8
- *
- *	Created 26 Dec 1997 by Michael Schmitz
- *	Based on the old macfb.c 6x11 code by Randy Thelen
- *
- *	This driver is significantly slower than the 8bit font drivers 
- *	and would probably benefit from splitting into drivers for each depth.
- *
- *  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
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-#include <linux/delay.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-mac.h>
-
-
-    /*
-     *  variable bpp packed pixels
-     */
-
-static void plot_pixel_mac(struct display *p, int bw, int pixel_x,
-			   int pixel_y);
-static int get_pixel_mac(struct display *p, int pixel_x, int pixel_y);
-
-void fbcon_mac_setup(struct display *p)
-{
-    if (p->line_length)
-	p->next_line = p->line_length;
-    else
-    	p->next_line = p->var.xres_virtual>>3;
-    p->next_plane = 0;
-}
-
-
-   /*
-    *    Macintosh
-    */
-#define PIXEL_BLACK_MAC          0
-#define PIXEL_WHITE_MAC          1
-#define PIXEL_INVERT_MAC         2
-
-void fbcon_mac_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		     int height, int width)
-{
-   int i, j;
-   u8 *dest, *src;
-   int l,r,t,b,w,lo,s;
-   int dl,dr,dt,db,dw,dlo;
-   int move_up;
-
-   src = (u8 *) (p->fb_info->screen_base + sy * fontheight(p) * p->next_line);
-   dest = (u8 *) (p->fb_info->screen_base + dy * fontheight(p) * p->next_line);
-
-   if( sx == 0 && width == p->conp->vc_cols) {
-     s = height * fontheight(p) * p->next_line;
-     fb_memmove(dest, src, s);
-     return;
-   }
-   
-   l = sx * fontwidth(p);
-   r = l + width * fontwidth(p);
-   t = sy * fontheight(p);
-   b = t + height * fontheight(p);
-
-   dl = dx * fontwidth(p);
-   dr = dl + width * fontwidth(p);
-   dt = dy * fontheight(p);
-   db = dt + height * fontheight(p);
-
-   /* w is the # pixels between two long-aligned points, left and right */
-   w = (r&~31) - ((l+31)&~31);
-   dw = (dr&~31) - ((dl+31)&~31);
-   /* lo is the # pixels between the left edge and a long-aligned left pixel */
-   lo = ((l+31)&~31) - l;
-   dlo = ((dl+31)&~31) - dl;
-   
-   /* if dx != sx then, logic has to align the left and right edges for fast moves */
-   if (lo != dlo) {
-     lo = ((l+7)&~7) - l;
-     dlo = ((dl+7)&~7) - dl;
-     w = (r&~7) - ((l+7)&~7);
-     dw = (dr&~7) - ((dl+7)&~7);
-     if (lo != dlo) {
-       unsigned char err_str[128];
-       unsigned short err_buf[256];
-       unsigned long cnt, len;
-       sprintf( err_str, "ERROR: Shift algorithm: sx=%d,sy=%d,dx=%d,dy=%d,w=%d,h=%d,bpp=%d",
-		sx,sy,dx,dy,width,height,p->var.bits_per_pixel);
-       len = strlen(err_str);
-       for (cnt = 0; cnt < len; cnt++)
-         err_buf[cnt] = 0x700 | err_str[cnt];
-       fbcon_mac_putcs(p->conp, p, err_buf, len, 0, 0);
-       /* pause for the user */
-       printk( "ERROR: shift algorithm...\n" );
-       mdelay(5000);
-       return;
-     }
-   }
-
-   s = 0;
-   switch (p->var.bits_per_pixel) {
-   case 1:
-     s = w >> 3;
-     src += lo >> 3;
-     dest += lo >> 3;
-     break;
-   case 2:
-     s = w >> 2;
-     src += lo >> 2;
-     dest += lo >> 2;
-     break;
-   case 4:
-     s = w >> 1;
-     src += lo >> 1;
-     dest += lo >> 1;
-     break;
-   case 8:
-     s = w;
-     src += lo;
-     dest += lo;
-     break;
-   case 16:
-     s = w << 1;
-     src += lo << 1;
-     dest += lo << 1;
-     break;
-   case 32:
-     s = w << 2;
-     src += lo << 2;
-     dest += lo << 2;
-     break;
-   }
-
-   if (sy <= sx) {
-     i = b;
-     move_up = 0;
-     src += height * fontheight(p);
-     dest += height * fontheight(p);
-   } else {
-     i = t;
-     move_up = 1;
-   }
-
-   while (1) {
-     for (i = t; i < b; i++) {
-       j = l;
-
-       for (; j & 31 && j < r; j++)
-	 plot_pixel_mac(p, get_pixel_mac(p, j+(dx-sx), i+(dy-sy)), j, i);
-
-       if (j < r) {
-	 fb_memmove(dest, src, s);
-	 if (move_up) {
-	   dest += p->next_line;
-	   src += p->next_line;
-	 } else {
-	   dest -= p->next_line;
-	   src -= p->next_line;
-	 }
-	 j += w;
-       }
-     
-       for (; j < r; j++)
-	 plot_pixel_mac(p, get_pixel_mac(p, j+(dx-sx), i+(dy-sy)), j, i);
-     }
-
-     if (move_up) {
-       i++;
-       if (i >= b)
-	 break;
-     } else {
-       i--;
-       if (i < t)
-	 break;
-     }
-   }
-}
-
-
-void fbcon_mac_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		     int height, int width)
-{
-   int pixel;
-   int i, j;
-   int inverse;
-   u8 *dest;
-   int l,r,t,b,w,lo,s;
-
-   inverse = conp ? attr_reverse(p,conp->vc_attr) : 0;
-   pixel = inverse ? PIXEL_WHITE_MAC : PIXEL_BLACK_MAC;
-   dest = (u8 *) (p->fb_info->screen_base + sy * fontheight(p) * p->next_line);
-
-   if( sx == 0 && width == p->conp->vc_cols) {
-     s = height * fontheight(p) * p->next_line;
-     if (inverse)
-       fb_memclear(dest, s);
-     else
-       fb_memset255(dest, s);
-   }
-   
-   l = sx * fontwidth(p);
-   r = l + width * fontwidth(p);
-   t = sy * fontheight(p);
-   b = t + height * fontheight(p);
-   /* w is the # pixels between two long-aligned points, left and right */
-   w = (r&~31) - ((l+31)&~31);
-   /* lo is the # pixels between the left edge and a long-aligned left pixel */
-   lo = ((l+31)&~31) - l;
-   s = 0;
-   switch (p->var.bits_per_pixel) {
-   case 1:
-     s = w >> 3;
-     dest += lo >> 3;
-     break;
-   case 2:
-     s = w >> 2;
-     dest += lo >> 2;
-     break;
-   case 4:
-     s = w >> 1;
-     dest += lo >> 1;
-     break;
-   case 8:
-     s = w;
-     dest += lo;
-     break;
-   case 16:
-     s = w << 1;
-     dest += lo << 1;
-     break;
-   case 32:
-     s = w << 2;
-     dest += lo << 2;
-     break;
-   }
-
-   for (i = t; i < b; i++) {
-     j = l;
-
-     for (; j & 31 && j < r; j++)
-       plot_pixel_mac(p, pixel, j, i);
-
-     if (j < r) {
-       if (PIXEL_WHITE_MAC == pixel)
-	 fb_memclear(dest, s);
-       else
-	 fb_memset255(dest, s);
-       dest += p->next_line;
-       j += w;
-     }
-     
-     for (; j < r; j++)
-       plot_pixel_mac(p, pixel, j, i);
-   }
-}
-
-
-void fbcon_mac_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		    int xx)
-{
-   u8 *cdat;
-   u_int rows, bold, ch_reverse, ch_underline;
-   u8 d;
-   int j;
-
-   cdat = p->fontdata+(c&p->charmask)*fontheight(p);
-   bold = attr_bold(p,c);
-   ch_reverse = attr_reverse(p,c);
-   ch_underline = attr_underline(p,c);
-
-   for (rows = 0; rows < fontheight(p); rows++) {
-      d = *cdat++;
-      if (!conp->vc_can_do_color) {
-	if (ch_underline && rows == (fontheight(p)-2))
-	  d = 0xff;
-	else if (bold)
-	  d |= d>>1;
-	if (ch_reverse)
-	  d = ~d;
-      }
-      for (j = 0; j < fontwidth(p); j++) {
-	plot_pixel_mac(p, (d & 0x80) >> 7, (xx*fontwidth(p)) + j, (yy*fontheight(p)) + rows);
-	d <<= 1;
-      }
-   }
-}
-
-
-void fbcon_mac_putcs(struct vc_data *conp, struct display *p, 
-		     const unsigned short *s, int count, int yy, int xx)
-{
-   u16 c;
-
-   while (count--) {
-      c = scr_readw(s++);
-      fbcon_mac_putc(conp, p, c, yy, xx++);
-   }
-}
-
-
-void fbcon_mac_revc(struct display *p, int xx, int yy)
-{
-   u_int rows, j;
-
-   for (rows = 0; rows < fontheight(p); rows++) {
-     for (j = 0; j < fontwidth(p); j++) {
-       plot_pixel_mac (p, PIXEL_INVERT_MAC, (xx*fontwidth(p))+j, (yy*fontheight(p))+rows);
-     }
-   }
-}
-
-static inline void plot_helper(u8 *dest, u8 bit, int bw)
-{
-    switch (bw) {
-    case PIXEL_BLACK_MAC:
-      fb_writeb( fb_readb(dest) | bit, dest );
-      break;
-    case PIXEL_WHITE_MAC:
-      fb_writeb( fb_readb(dest) & (~bit), dest );
-      break;
-    case PIXEL_INVERT_MAC:
-      fb_writeb( fb_readb(dest) ^ bit, dest );
-      break;
-    default:
-      printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
-    }
-}
-
-/*
- * plot_pixel_mac
- */
-static void plot_pixel_mac(struct display *p, int bw, int pixel_x, int pixel_y)
-{
-  u8 *dest, bit;
-  u16 *dest16, pix16;
-  u32 *dest32, pix32;
-
-  /* There *are* 68k Macs that support more than 832x624, you know :-) */
-  if (pixel_x < 0 || pixel_y < 0 || pixel_x >= p->var.xres || pixel_y >= p->var.yres) {
-    printk ("ERROR: pixel_x == %d, pixel_y == %d", pixel_x, pixel_y);
-    mdelay(1000);
-    return;
-  }
-
-  switch (p->var.bits_per_pixel) {
-  case 1:
-    dest = (u8 *) ((pixel_x >> 3) + p->fb_info->screen_base + pixel_y * p->next_line);
-    bit = 0x80 >> (pixel_x & 7);
-    plot_helper(dest, bit, bw);
-    break;
-
-  case 2:
-    dest = (u8 *) ((pixel_x >> 2) + p->fb_info->screen_base + pixel_y * p->next_line);
-    bit = 0xC0 >> ((pixel_x & 3) << 1);
-    plot_helper(dest, bit, bw);
-    break;
-
-  case 4:
-    dest = (u8 *) ((pixel_x >> 1) + p->fb_info->screen_base + pixel_y * p->next_line);
-    bit = 0xF0 >> ((pixel_x & 1) << 2);
-    plot_helper(dest, bit, bw);
-    break;
-
-  case 8:
-    dest = (u8 *) (pixel_x + p->fb_info->screen_base + pixel_y * p->next_line);
-    bit = 0xFF;
-    plot_helper(dest, bit, bw);
-    break;
-
-/* FIXME: You can't access framebuffer directly like this! */
-  case 16:
-    dest16 = (u16 *) ((pixel_x *2) + p->fb_info->screen_base + pixel_y * p->next_line);
-    pix16 = 0xFFFF;
-    switch (bw) {
-    case PIXEL_BLACK_MAC:  *dest16 = ~pix16; break;
-    case PIXEL_WHITE_MAC:  *dest16 = pix16;  break;
-    case PIXEL_INVERT_MAC: *dest16 ^= pix16; break;
-    default: printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
-    }
-    break;
-
-  case 32:
-    dest32 = (u32 *) ((pixel_x *4) + p->fb_info->screen_base + pixel_y * p->next_line);
-    pix32 = 0xFFFFFFFF;
-    switch (bw) {
-    case PIXEL_BLACK_MAC:  *dest32 = ~pix32; break;
-    case PIXEL_WHITE_MAC:  *dest32 = pix32;  break;
-    case PIXEL_INVERT_MAC: *dest32 ^= pix32; break;
-    default: printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
-    }
-    break;
-  }
-}
-
-static int get_pixel_mac(struct display *p, int pixel_x, int pixel_y)
-{
-  u8 *dest, bit;
-  u16 *dest16;
-  u32 *dest32;
-  u8 pixel=0;
-
-  switch (p->var.bits_per_pixel) {
-  case 1:
-    dest = (u8 *) ((pixel_x / 8) + p->fb_info->screen_base + pixel_y * p->next_line);
-    bit = 0x80 >> (pixel_x & 7);
-    pixel = *dest & bit;
-    break;
-  case 2:
-    dest = (u8 *) ((pixel_x / 4) + p->fb_info->screen_base + pixel_y * p->next_line);
-    bit = 0xC0 >> (pixel_x & 3);
-    pixel = *dest & bit;
-    break;
-  case 4:
-    dest = (u8 *) ((pixel_x / 2) + p->fb_info->screen_base + pixel_y * p->next_line);
-    bit = 0xF0 >> (pixel_x & 1);
-    pixel = *dest & bit;
-    break;
-  case 8:
-    dest = (u8 *) (pixel_x + p->fb_info->screen_base + pixel_y * p->next_line);
-    pixel = *dest;
-    break;
-  case 16:
-    dest16 = (u16 *) ((pixel_x *2) + p->fb_info->screen_base + pixel_y * p->next_line);
-    pixel = *dest16 ? 1 : 0;
-    break;
-  case 32:
-    dest32 = (u32 *) ((pixel_x *4) + p->fb_info->screen_base + pixel_y * p->next_line);
-    pixel = *dest32 ? 1 : 0;
-    break;
-  }
-
-  return pixel ? PIXEL_BLACK_MAC : PIXEL_WHITE_MAC;
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_mac = {
-    setup:		fbcon_mac_setup,
-    bmove:		fbcon_redraw_bmove,
-    clear:		fbcon_redraw_clear,
-    putc:		fbcon_mac_putc,
-    putcs:		fbcon_mac_putcs,
-    revc:		fbcon_mac_revc,
-    fontwidthmask:	FONTWIDTHRANGE(1,8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-    return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
-    /*
-     *  Visible symbols for modules
-     */
-
-EXPORT_SYMBOL(fbcon_mac);
-EXPORT_SYMBOL(fbcon_mac_setup);
-EXPORT_SYMBOL(fbcon_mac_bmove);
-EXPORT_SYMBOL(fbcon_mac_clear);
-EXPORT_SYMBOL(fbcon_mac_putc);
-EXPORT_SYMBOL(fbcon_mac_putcs);
-EXPORT_SYMBOL(fbcon_mac_revc);
diff -Nru a/drivers/video/fbcon-vga.c b/drivers/video/fbcon-vga.c
--- a/drivers/video/fbcon-vga.c	Wed Jul 24 14:03:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,213 +0,0 @@
-/*
- *  linux/drivers/video/fbcon-vga.c -- Low level frame buffer operations for
- *				       VGA characters/attributes
- *
- *	Created 28 Mar 1998 by Geert Uytterhoeven
- *	Monochrome attributes added May 1998 by Andrew Apted
- *
- *  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/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <asm/io.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-vga.h>
-
-
-    /*
-     *  VGA screen access
-     */ 
-
-static inline void vga_writew(u16 val, u16 *addr)
-{
-#ifdef __powerpc__
-    st_le16(addr, val);
-#else
-    writew(val, (unsigned long)addr);
-#endif /* !__powerpc__ */
-}
-
-static inline u16 vga_readw(u16 *addr)
-{
-#ifdef __powerpc__
-    return ld_le16(addr);
-#else
-    return readw((unsigned long)addr);
-#endif /* !__powerpc__ */	
-}
-
-static inline void vga_memsetw(void *s, u16 c, unsigned int count)
-{
-    u16 *addr = (u16 *)s;
-
-    while (count) {
-	count--;
-	vga_writew(c, addr++);
-    }
-}
-
-static inline void vga_memmovew(u16 *to, u16 *from, unsigned int count)
-{
-    if (to < from) {
-	while (count) {
-	    count--;
-	    vga_writew(vga_readw(from++), to++);
-	}
-    } else {
-	from += count;
-	to += count;
-	while (count) {
-	    count--;
-	    vga_writew(vga_readw(--from), --to);
-	}
-    }
-}
-
-
-    /*
-     *  VGA characters/attributes
-     */
-
-static inline u16 fbcon_vga_attr(struct display *p,
-				 unsigned short s)
-{
-        /* Underline and reverse-video are mutually exclusive on MDA.
-         * Since reverse-video is used for cursors and selected areas, 
-	 * it takes precedence.
-         */
-
-	return (attr_reverse(p, s) ? 0x7000 :
-		(attr_underline(p, s) ? 0x0100 : 0x0700)) |
-	       (attr_bold(p, s) ? 0x0800 : 0) |
-	       (attr_blink(p, s) ? 0x8000 : 0);
-}
-
-void fbcon_vga_setup(struct display *p)
-{
-    p->next_line = p->line_length;
-    p->next_plane = 0;
-}
-
-void fbcon_vga_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		     int height, int width)
-{
-    u16 *src, *dst;
-    int rows;
-
-    if (sx == 0 && dx == 0 && width == p->next_line/2) {
-	src = (u16 *)(p->fb_info->screen_base+sy*p->next_line);
-	dst = (u16 *)(p->fb_info->screen_base+dy*p->next_line);
-	vga_memmovew(dst, src, height*width);
-    } else if (dy < sy || (dy == sy && dx < sx)) {
-	src = (u16 *)(p->fb_info->screen_base+sy*p->next_line+sx*2);
-	dst = (u16 *)(p->fb_info->screen_base+dy*p->next_line+dx*2);
-	for (rows = height; rows-- ;) {
-	    vga_memmovew(dst, src, width);
-	    src += p->next_line/2;
-	    dst += p->next_line/2;
-	}
-    } else {
-	src = (u16 *)(p->fb_info->screen_base+(sy+height-1)*p->next_line+sx*2);
-	dst = (u16 *)(p->fb_info->screen_base+(dy+height-1)*p->next_line+dx*2);
-	for (rows = height; rows-- ;) {
-	    vga_memmovew(dst, src, width);
-	    src -= p->next_line/2;
-	    dst -= p->next_line/2;
-	}
-    }
-}
-
-void fbcon_vga_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		     int height, int width)
-{
-    u16 *dest = (u16 *)(p->fb_info->screen_base+sy*p->next_line+sx*2);
-    int rows;
-
-    if (sx == 0 && width*2 == p->next_line)      
-	vga_memsetw(dest, conp->vc_video_erase_char, height*width);
-    else
-	for (rows = height; rows-- ; dest += p->next_line/2)
-	    vga_memsetw(dest, conp->vc_video_erase_char, width);
-}
-
-void fbcon_vga_putc(struct vc_data *conp, struct display *p, int c, int y,
-		    int x)
-{
-    u16 *dst = (u16 *)(p->fb_info->screen_base+y*p->next_line+x*2);
-    if (conp->vc_can_do_color)
-    	vga_writew(c, dst);
-    else
-    	vga_writew(fbcon_vga_attr(p, c) | (c & 0xff), dst);
-}
-
-void fbcon_vga_putcs(struct vc_data *conp, struct display *p, 
-		     const unsigned short *s, int count, int y, int x)
-{
-    u16 *dst = (u16 *)(p->fb_info->screen_base+y*p->next_line+x*2);
-    u16 sattr;
-    if (conp->vc_can_do_color)
-    	while (count--)
-    	    vga_writew(scr_readw(s++), dst++);
-    else {
-        sattr = fbcon_vga_attr(p, scr_readw(s));
-        while (count--)
-	    vga_writew(sattr | ((int) (scr_readw(s++)) & 0xff), dst++);
-    }
-}
-
-void fbcon_vga_revc(struct display *p, int x, int y)
-{
-    u16 *dst = (u16 *)(p->fb_info->screen_base+y*p->next_line+x*2);
-    u16 val = vga_readw(dst);
-    val = (val & 0x88ff) | ((val<<4) & 0x7000) | ((val>>4) & 0x0700);
-    vga_writew(val, dst);
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_vga = {
-    setup:		fbcon_vga_setup,
-    bmove:		fbcon_vga_bmove,
-    clear:		fbcon_vga_clear,
-    putc:		fbcon_vga_putc,
-    putcs:		fbcon_vga_putcs,
-    revc:		fbcon_vga_revc,
-    fontwidthmask:	FONTWIDTH(8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-    return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
-    /*
-     *  Visible symbols for modules
-     */
-
-EXPORT_SYMBOL(fbcon_vga);
-EXPORT_SYMBOL(fbcon_vga_setup);
-EXPORT_SYMBOL(fbcon_vga_bmove);
-EXPORT_SYMBOL(fbcon_vga_clear);
-EXPORT_SYMBOL(fbcon_vga_putc);
-EXPORT_SYMBOL(fbcon_vga_putcs);
-EXPORT_SYMBOL(fbcon_vga_revc);
diff -Nru a/drivers/video/fbcon.c b/drivers/video/fbcon.c
--- a/drivers/video/fbcon.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/fbcon.c	Wed Jul 24 14:03:36 2002
@@ -624,7 +624,7 @@
     }
     
     if (!fontwidthvalid(p,fontwidth(p))) {
-#ifdef CONFIG_MAC
+#ifdef CONFIG_FBCON_MAC
 	if (MACH_IS_MAC)
 	    /* ++Geert: hack to make 6x11 fonts work on mac */
 	    p->dispsw = &fbcon_mac;
@@ -2401,7 +2401,7 @@
 		else
 		    dst = fb + y1*line + x/8;
 		for( x1 = 0; x1 < LOGO_LINE; ++x1 )
-		    fb_writeb(fb_readb(src++) ^ inverse, dst++);
+		    fb_writeb(*src++ ^ inverse, dst++);
 	    }
 	    done = 1;
 	}
diff -Nru a/drivers/video/fbgen.c b/drivers/video/fbgen.c
--- a/drivers/video/fbgen.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/fbgen.c	Wed Jul 24 14:03:38 2002
@@ -30,133 +30,18 @@
 #include <video/fbcon-cfb32.h>
 #include "fbcon-accel.h"
 
-/* ---- `Generic' versions of the frame buffer device operations ----------- */
-
-
-/**
- *	fbgen_get_fix - get fixed part of display
- *	@fix: fb_fix_screeninfo structure
- *	@con: virtual console number
- *	@info: frame buffer info structure
- *
- *	Get the fixed information part of the display and place it
- *	into @fix for virtual console @con on device @info.
- *
- *	Returns negative errno on error, or zero on success.
- *
- */
-
-int fbgen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
-{
-    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
-    struct fbgen_hwswitch *fbhw = info2->fbhw;
-    char par[info2->parsize];
-
-    if (con == -1)
-	fbhw->get_par(&par, info2);
-    else {
-	int err;
-
-	if ((err = fbhw->decode_var(&fb_display[con].var, &par, info2)))
-	    return err;
-    }
-    memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-    return fbhw->encode_fix(fix, &par, info2);
-}
-
 int gen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
 {
 	*fix = info->fix;
 	return 0;	
 }
 
-/**
- *	fbgen_get_var - get user defined part of display
- *	@var: fb_var_screeninfo structure
- *	@con: virtual console number
- *	@info: frame buffer info structure
- *
- *	Get the user defined part of the display and place it into @var
- *	for virtual console @con on device @info.
- *
- *	Returns negative errno on error, or zero for success.
- *
- */
-
-int fbgen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
-    struct fbgen_hwswitch *fbhw = info2->fbhw;
-    char par[info2->parsize];
-
-    if (con == -1) {
-	fbhw->get_par(&par, info2);
-	fbhw->encode_var(var, &par, info2);
-    } else
-	*var = fb_display[con].var;
-    return 0;
-}
-
 int gen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
 {
 	*var = info->var;
 	return 0;	
 }
 
-/**
- *	fbgen_set_var - set the user defined part of display
- *	@var: fb_var_screeninfo user defined part of the display
- *	@con: virtual console number
- *	@info: frame buffer info structure
- *
- *	Set the user defined part of the display as dictated by @var
- *	for virtual console @con on device @info.
- *
- *	Returns negative errno on error, or zero for success.
- *
- */
-
-int fbgen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
-    int err;
-    int oldxres, oldyres, oldbpp, oldxres_virtual, oldyres_virtual, oldyoffset;
-    struct fb_bitfield oldred, oldgreen, oldblue;
-
-    if ((err = fbgen_do_set_var(var, con == info->currcon, info2)))
-	return err;
-    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-	oldxres = fb_display[con].var.xres;
-	oldyres = fb_display[con].var.yres;
-	oldxres_virtual = fb_display[con].var.xres_virtual;
-	oldyres_virtual = fb_display[con].var.yres_virtual;
-	oldbpp = fb_display[con].var.bits_per_pixel;
-	oldred = fb_display[con].var.red;
-	oldgreen = fb_display[con].var.green;
-	oldblue = fb_display[con].var.blue;
-	oldyoffset = fb_display[con].var.yoffset;
-	fb_display[con].var = *var;
-	if (oldxres != var->xres || oldyres != var->yres ||
-	    oldxres_virtual != var->xres_virtual ||
-	    oldyres_virtual != var->yres_virtual ||
-	    oldbpp != var->bits_per_pixel ||
-	    (!(memcmp(&oldred, &(var->red), sizeof(struct fb_bitfield)))) || 
-	    (!(memcmp(&oldgreen, &(var->green), sizeof(struct fb_bitfield)))) ||
-	    (!(memcmp(&oldblue, &(var->blue), sizeof(struct fb_bitfield)))) ||
-	    oldyoffset != var->yoffset) {
-	    fbgen_set_disp(con, info2);
-	    if (info->changevar)
-		(*info->changevar)(con);
-	    if ((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0)))
-		return err;
-	    do_install_cmap(con, info);
-	}
-    }
-    var->activate = 0;
-    return 0;
-}
-
-
 int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
 {
 	int err;
@@ -191,75 +76,12 @@
 	return 0;
 }
 
-/**
- *	fbgen_get_cmap - get the colormap
- *	@cmap: frame buffer colormap structure
- *	@kspc: boolean, 0 copy local, 1 put_user() function
- *	@con: virtual console number
- *	@info: frame buffer info structure
- *
- *	Gets the colormap for virtual console @con and places it into
- *	@cmap for device @info.
- *
- *	Returns negative errno on error, or zero for success.
- *
- */
-
-int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-		   struct fb_info *info)
-{
-    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
-    struct fbgen_hwswitch *fbhw = info2->fbhw;
-
-    if (con == info->currcon)			/* current console ? */
-	return fb_get_cmap(cmap, kspc, fbhw->getcolreg, info);
-    else
-	if (fb_display[con].cmap.len)	/* non default colormap ? */
-	    fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-	else {
-	    int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256;
-	    fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
-	}
-    return 0;
-}
-
 int gen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
 {
 	fb_copy_cmap (&info->cmap, cmap, kspc ? 0 : 2);
 	return 0;
 }
 
-/**
- *	fbgen_set_cmap - set the colormap
- *	@cmap: frame buffer colormap structure
- *	@kspc: boolean, 0 copy local, 1 get_user() function
- *	@con: virtual console number
- *	@info: frame buffer info structure
- *
- *	Sets the colormap @cmap for virtual console @con on
- *	device @info.
- *
- *	Returns negative errno on error, or zero for success.
- *
- */
-
-int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-		   struct fb_info *info)
-{
-    int err;
-
-    if (!fb_display[con].cmap.len) {	/* no colormap allocated ? */
-	int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256;
-	if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))
-	    return err;
-    }
-    if (con == info->currcon)			/* current console ? */
-	return fb_set_cmap(cmap, kspc, info);
-    else
-	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
-    return 0;
-}
-
 int gen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
 		 struct fb_info *info)
 {
@@ -285,141 +107,39 @@
 	return err;
 }
 
-/**
- *	fbgen_pan_display - pan or wrap the display
- *	@var: frame buffer user defined part of display
- *	@con: virtual console number
- *	@info: frame buffer info structure
- *
- *	Pan or wrap virtual console @con for device @info.
- *
- *	This call looks only at xoffset, yoffset and the
- *	FB_VMODE_YWRAP flag in @var.
- *
- *	Returns negative errno on error, or zero for success.
- *
- */
-
 int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
 		      struct fb_info *info)
 {
-    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
-    struct fbgen_hwswitch *fbhw = info2->fbhw;
     int xoffset = var->xoffset;
     int yoffset = var->yoffset;
     int err;
 
-    if (xoffset < 0 ||
-	xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
-	yoffset < 0 ||
-	yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)
+    if (xoffset < 0 || yoffset < 0 || 
+	xoffset + info->var.xres > info->var.xres_virtual ||
+	yoffset + info->var.yres > info->var.yres_virtual)
 	return -EINVAL;
     if (con == info->currcon) {
-	if (fbhw->pan_display) {
-	    if ((err = fbhw->pan_display(var, info2)))
+	if (info->fbops->fb_pan_display) {
+	    if ((err = info->fbops->fb_pan_display(var, con, info)))
 		return err;
 	} else
 	    return -EINVAL;
     }
-    fb_display[con].var.xoffset = var->xoffset;
-    fb_display[con].var.yoffset = var->yoffset;
+    info->var.xoffset = var->xoffset;
+    info->var.yoffset = var->yoffset;
     if (var->vmode & FB_VMODE_YWRAP)
-	fb_display[con].var.vmode |= FB_VMODE_YWRAP;
+	info->var.vmode |= FB_VMODE_YWRAP;
     else
-	fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
-
+	info->var.vmode &= ~FB_VMODE_YWRAP;
     return 0;
 }
 
 
 /* ---- Helper functions --------------------------------------------------- */
 
-
-/**
- *	fbgen_do_set_var - change the video mode
- *	@var: frame buffer user defined part of display
- *	@isactive: boolean, 0 inactive, 1 active
- *	@info: generic frame buffer info structure
- *
- *	Change the video mode settings for device @info.  If @isactive
- *	is non-zero, the changes will be activated immediately.
- *
- *	Return negative errno on error, or zero for success.
- *
- */
-
-int fbgen_do_set_var(struct fb_var_screeninfo *var, int isactive,
-		     struct fb_info_gen *info)
-{
-    struct fbgen_hwswitch *fbhw = info->fbhw;
-    int err, activate;
-    char par[info->parsize];
-
-    if ((err = fbhw->decode_var(var, &par, info)))
-	return err;
-    activate = var->activate;
-    if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive)
-	fbhw->set_par(&par, info);
-    fbhw->encode_var(var, &par, info);
-    var->activate = activate;
-    return 0;
-}
-
-/**
- *	fbgen_set_disp - set generic display
- *	@con: virtual console number
- *	@info: generic frame buffer info structure
- *
- *	Sets a display on virtual console @con for device @info.
- *
- */
-
-void fbgen_set_disp(int con, struct fb_info_gen *info)
-{
-    struct fbgen_hwswitch *fbhw = info->fbhw;
-    struct fb_fix_screeninfo fix;
-    char par[info->parsize];
-    struct display *display;
-
-    if (con >= 0)
-	display = &fb_display[con];
-    else
-	display = info->info.disp;	/* used during initialization */
-
-    if (con == -1)
-	fbhw->get_par(&par, info);
-    else
-	fbhw->decode_var(&fb_display[con].var, &par, info);
-    memset(&fix, 0, sizeof(struct fb_fix_screeninfo));
-    fbhw->encode_fix(&fix, &par, info);
-
-    display->visual = fix.visual;
-    display->type = fix.type;
-    display->type_aux = fix.type_aux;
-    display->ypanstep = fix.ypanstep;
-    display->ywrapstep = fix.ywrapstep;
-    display->line_length = fix.line_length;
-    if (info->fbhw->blank || fix.visual == FB_VISUAL_PSEUDOCOLOR ||
-	fix.visual == FB_VISUAL_DIRECTCOLOR)
-	display->can_soft_blank = 1;
-    else
-	display->can_soft_blank = 0;
-    fbhw->set_disp(&par, display, info);
-#if 0 /* FIXME: generic inverse is not supported yet */
-    display->inverse = (fix.visual == FB_VISUAL_MONO01 ? !inverse : inverse);
-#else
-    display->inverse = fix.visual == FB_VISUAL_MONO01;
-#endif
-}
-
 void gen_set_disp(int con, struct fb_info *info)
 {
-	struct display *display;
-
-	if (con >= 0)
-		display = fb_display + con;
-	else
-		display = info->disp;
+	struct display *display = (con < 0) ? info->disp : (fb_display + con);
 
 	display->visual = info->fix.visual;
 	display->type	= info->fix.type;
@@ -481,38 +201,15 @@
     }
 }
 
-
-/**
- *	fbgen_update_var - update user defined part of display
- *	@con: virtual console number
- *	@info: frame buffer info structure
- *
- *	Updates the user defined part of the display ('var'
- *	structure) on virtual console @con for device @info.
- *	This function is called by fbcon.c.
- *
- *	Returns negative errno on error, or zero for success.
- *
- */
-
-int fbgen_update_var(int con, struct fb_info *info)
-{
-    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
-    struct fbgen_hwswitch *fbhw = info2->fbhw;
-    int err;
-
-    if (fbhw->pan_display) {
-        if ((err = fbhw->pan_display(&fb_display[con].var, info2)))
-            return err;
-    }
-    return 0;
-}
-
 int gen_update_var(int con, struct fb_info *info)
 {
+	struct display *disp = (con < 0) ? info->disp : (fb_display + con);
 	int err;
     
 	if (con == info->currcon) {
+		info->var.xoffset = disp->var.xoffset;
+		info->var.yoffset = disp->var.yoffset;
+		info->var.vmode	= disp->var.vmode;	
 		if (info->fbops->fb_pan_display) {
 			if ((err = info->fbops->fb_pan_display(&info->var, con, info)))
 				return err;
@@ -521,35 +218,6 @@
 	return 0;
 }
 
-
-/**
- *	fbgen_switch - switch to a different virtual console.
- *	@con: virtual console number
- *	@info: frame buffer info structure
- *
- *	Switch to virtuall console @con on device @info.
- *
- *	Returns zero.
- *
- */
-
-int fbgen_switch(int con, struct fb_info *info)
-{
-    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
-    struct fbgen_hwswitch *fbhw = info2->fbhw;
-
-    /* Do we have to save the colormap ? */
-    if (fb_display[info->currcon].cmap.len)
-	fb_get_cmap(&fb_display[info->currcon].cmap, 1, fbhw->getcolreg,
-		    &info2->info);
-    fbgen_do_set_var(&fb_display[con].var, 1, info2);
-    info->currcon = con;
-    /* Install new colormap */
-    do_install_cmap(con, info);
-    return 0;
-}
-
-
 int gen_switch(int con, struct fb_info *info)
 {
 	struct display *disp;
@@ -601,12 +269,10 @@
 
 int fbgen_blank(int blank, struct fb_info *info)
 {
-    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
-    struct fbgen_hwswitch *fbhw = info2->fbhw;
-    u16 black[16];
     struct fb_cmap cmap;
-
-    if (fbhw->blank && !fbhw->blank(blank, info2))
+    u16 black[16];
+    
+    if (info->fbops->fb_blank && !info->fbops->fb_blank(blank, info))
 	return 0;
     if (blank) {
 	memset(black, 0, 16*sizeof(u16));
@@ -623,24 +289,15 @@
 }
 
 /* generic frame buffer operations */
-EXPORT_SYMBOL(fbgen_get_fix);
 EXPORT_SYMBOL(gen_get_fix);
-EXPORT_SYMBOL(fbgen_get_var);
 EXPORT_SYMBOL(gen_get_var);
-EXPORT_SYMBOL(fbgen_set_var);
 EXPORT_SYMBOL(gen_set_var);
-EXPORT_SYMBOL(fbgen_get_cmap);
 EXPORT_SYMBOL(gen_get_cmap);
-EXPORT_SYMBOL(fbgen_set_cmap);
 EXPORT_SYMBOL(gen_set_cmap);
 EXPORT_SYMBOL(fbgen_pan_display);
 /* helper functions */
-EXPORT_SYMBOL(fbgen_do_set_var);
-EXPORT_SYMBOL(fbgen_set_disp);
 EXPORT_SYMBOL(do_install_cmap);
-EXPORT_SYMBOL(fbgen_update_var);
 EXPORT_SYMBOL(gen_update_var);
-EXPORT_SYMBOL(fbgen_switch);
 EXPORT_SYMBOL(gen_switch);
 EXPORT_SYMBOL(fbgen_blank);
 
diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c
--- a/drivers/video/fbmem.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/video/fbmem.c	Wed Jul 24 14:03:35 2002
@@ -132,7 +132,7 @@
 extern int pmagbbfb_init(void);
 extern void maxinefb_init(void);
 extern int tx3912fb_init(void);
-extern int tx3912fb_setup(char*);
+extern void tx3912fb_setup(char*);
 extern int radeonfb_init(void);
 extern int radeonfb_setup(char*);
 extern int e1355fb_init(void);
diff -Nru a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
--- a/drivers/video/fm2fb.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/fm2fb.c	Wed Jul 24 14:03:37 2002
@@ -198,8 +198,9 @@
 	if (!blank)
 		t |= FRAMEMASTER_ENABLE | FRAMEMASTER_NOLACE;
 	fm2fb_reg[0] = t;
+	return 0;
 }
-    
+
     /*
      *  Set a single color register. The values supplied are already
      *  rounded down to the hardware's capabilities (according to the
diff -Nru a/drivers/video/fonts.c b/drivers/video/fonts.c
--- a/drivers/video/fonts.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/fonts.c	Wed Jul 24 14:03:37 2002
@@ -33,7 +33,7 @@
     &font_vga_8x16,
 #endif
 #ifdef CONFIG_FONT_6x11
-#if defined(CONFIG_FBCON_MAC) || defined(CONFIG_FB_SBUS)
+#if defined(CONFIG_FBCON_ACCEL) || defined(CONFIG_FB_SBUS)
 #undef NO_FONTS
 #endif
     &font_vga_6x11,
@@ -43,7 +43,7 @@
     &font_sun_8x16,
 #endif
 #ifdef CONFIG_FONT_SUN12x22
-#if defined(CONFIG_FB_SBUS) || defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || defined(CONFIG_FBCON_CFB32)
+#if defined(CONFIG_FB_SBUS) || defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FBCON_ACCEL)
 #undef NO_FONTS
 #endif
     &font_sun_12x22,
diff -Nru a/drivers/video/hpfb.c b/drivers/video/hpfb.c
--- a/drivers/video/hpfb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/hpfb.c	Wed Jul 24 14:03:38 2002
@@ -49,6 +49,7 @@
 	visual:		FB_VISUAL_PSEUDOCOLOR,
 	line_length:	1024,
 	accel:		FB_ACCEL_NONE,
+};
 
 static struct fb_var_screeninfo hpfb_defined = {
 	xres:		1024,
@@ -163,7 +164,7 @@
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 	fb_info.var   = hpfb_defined;
 	fb_info.fix   = hpfb_fix;
-	fb_info.screen_base = hpfb_fix.smem_start;
+	fb_info.screen_base = (char *)hpfb_fix.smem_start;	// FIXME
 
 	/* The below feilds will go away !!!! */
 	fb_info.currcon		= -1;
diff -Nru a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
--- a/drivers/video/imsttfb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/imsttfb.c	Wed Jul 24 14:03:38 2002
@@ -1177,48 +1177,6 @@
 };
 #endif
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-
-extern struct vc_mode display_info;
-extern struct fb_info *console_fb_info;
-
-static void
-set_display_info (struct display *disp)
-{
-	display_info.width = disp->var.xres;
-	display_info.height = disp->var.yres;
-	display_info.depth = disp->var.bits_per_pixel;
-	display_info.pitch = disp->line_length;
-
-	switch (disp->var.xres) {
-		case 512:
-			display_info.mode = 2;
-			break;
-		case 640:
-			display_info.mode = 6;
-			break;
-		case 800:
-			display_info.mode = 12;
-			break;
-		case 832:
-			display_info.mode = 13;
-			break;
-		case 1024:
-			display_info.mode = 17;
-			break;
-		case 1152:
-			display_info.mode = 18;
-			break;
-		case 1280:
-			display_info.mode = disp->var.yres == 960 ? 19 : 20;
-			break;
-		default:
-			display_info.mode = 0;
-	}
-}
-#endif
-
 static int
 imsttfb_getcolreg (u_int regno, u_int *red, u_int *green,
 		   u_int *blue, u_int *transp, struct fb_info *info)
@@ -1385,10 +1343,6 @@
 		p->dispsw.cursor = 0;
 		p->dispsw.set_font = 0;
 	}
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-	set_display_info(disp);
-#endif
 }
 
 static void
@@ -1864,16 +1818,6 @@
 	tmp = (in_le32(&p->dc_regs[SSTATUS]) & 0x0f00) >> 8;
 	printk("fb%u: %s frame buffer; %uMB vram; chip version %u\n",
 		i, p->fix.id, p->total_vram >> 20, tmp);
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-	strncpy(display_info.name, "IMS,tt128mb", sizeof(display_info.name));
-	display_info.fb_address = p->frame_buffer_phys;
-	display_info.cmap_adr_address = p->cmap_regs_phys + PADDRW;
-	display_info.cmap_data_address = p->cmap_regs_phys + PDATA;
-	display_info.disp_reg_address = p->dc_regs_phys;
-	if (!console_fb_info)
-		console_fb_info = &p->info;
-#endif /* CONFIG_FB_COMPAT_XPMAC */
 }
 
 static int __devinit
diff -Nru a/drivers/video/macfb.c b/drivers/video/macfb.c
--- a/drivers/video/macfb.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/macfb.c	Wed Jul 24 14:03:36 2002
@@ -41,15 +41,6 @@
 #include <asm/machw.h>
 
 #include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-#include <video/fbcon-cfb2.h>
-#include <video/fbcon-cfb4.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-
-#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB4) || defined(FBCON_HAS_CFB2)
 
 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
 #define DAC_BASE 0x50f24000
@@ -151,191 +142,35 @@
 	unsigned char lut;
 };
 
-#endif
-
 #define PIXEL_TO_MM(a)	(((a)*10)/28)	/* width in mm at 72 dpi */	
 
-static char* video_base;
-static int   video_size;
-static char* video_vbase;        /* mapped */
-
 /* mode */
-static int  video_bpp;
-static int  video_width;
-static int  video_height;
-static int  video_type = FB_TYPE_PACKED_PIXELS;
-static int  video_visual;
-static int  video_linelength;
-static int  video_cmap_len;
 static int  video_slot = 0;
 
-static struct fb_var_screeninfo macfb_defined={
-	0,0,0,0,	/* W,H, W, H (virtual) load xres,xres_virtual*/
-	0,0,		/* virtual -> visible no offset */
-	8,		/* depth -> load bits_per_pixel */
-	0,		/* greyscale ? */
-	{0,0,0},	/* R */
-	{0,0,0},	/* G */
-	{0,0,0},	/* B */
-	{0,0,0},	/* transparency */
-	0,		/* standard pixel format */
-	FB_ACTIVATE_NOW,
-	-1, -1,
-	FB_ACCEL_NONE,	/* The only way to accelerate a mac is .. */
-	0L,0L,0L,0L,0L,
-	0L,0L,0,	/* No sync info */
-	FB_VMODE_NONINTERLACED,
-	{0,0,0,0,0,0}
+static struct fb_var_screeninfo macfb_defined = {
+	bits_per_pixel:	8,	
+	activae:	FB_ACTIVATE_NOW,
+	width:		-1,
+	height:		-1,
+	right_margin:	32,
+	upper_margin:	16,
+	lower_margin:	4,
+	vsync_len:	4,
+	vmode:		FB_VMODE_NONINTERLACED,
+};
+
+static struct fb_fix_screeninfo vesafb_fix = {
+	id:	"Macintosh ",
+	type:	FB_TYPE_PACKED_PIXELS,
+	accel:	FB_ACCEL_NONE,
 };
 
 static struct display disp;
 static struct fb_info fb_info;
-static struct { u_short blue, green, red, pad; } palette[256];
-static union {
-#ifdef FBCON_HAS_CFB16
-    u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB24
-    u32 cfb24[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-    u32 cfb32[16];
-#endif
-} fbcon_cmap;
-
+static u32 pseudo_palette[17];
 static int             inverse   = 0;
 static int             vidtest   = 0;
 
-static int macfb_update_var(int con, struct fb_info *info)
-{
-	return 0;
-}
-
-static int macfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info)
-{
-	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-	strcpy(fix->id, "Mac Generic");
-
-	fix->smem_start = video_base;
-	fix->smem_len = video_size;
-	fix->type = video_type;
-	fix->visual = video_visual;
-	fix->xpanstep = 0;
-	fix->ypanstep = 0;
-	fix->line_length=video_linelength;
-	return 0;
-}
-
-static int macfb_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
-{
-	if(con==-1)
-		memcpy(var, &macfb_defined, sizeof(struct fb_var_screeninfo));
-	else
-		*var=fb_display[con].var;
-	return 0;
-}
-
-static void macfb_set_disp(int con)
-{
-	struct fb_fix_screeninfo fix;
-	struct display *display;
-	
-	if (con >= 0)
-		display = &fb_display[con];
-	else
-		display = &disp;	/* used during initialization */
-
-	macfb_get_fix(&fix, con, &fb_info);
-
-	memset(display, 0, sizeof(struct display));
-	display->visual = fix.visual;
-	display->type = fix.type;
-	display->type_aux = fix.type_aux;
-	display->ypanstep = fix.ypanstep;
-	display->ywrapstep = fix.ywrapstep;
-	display->line_length = fix.line_length;
-	display->next_line = fix.line_length;
-	display->can_soft_blank = 0;
-	display->inverse = inverse;
-	display->scrollmode = SCROLL_YREDRAW;
-	macfb_get_var(&display->var, -1, &fb_info);
-
-	switch (video_bpp) {
-#ifdef FBCON_HAS_MFB
-	case 1:
-		display->dispsw = &fbcon_mfb;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB2
-	case 2:
-		display->dispsw = &fbcon_cfb2;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB4
-	case 4:
-		display->dispsw = &fbcon_cfb4;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB8
-	case 8:
-		display->dispsw = &fbcon_cfb8;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB16
-	case 15:
-	case 16:
-		display->dispsw = &fbcon_cfb16;
-		display->dispsw_data = fbcon_cmap.cfb16;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB24
-	case 24:
-		display->dispsw = &fbcon_cfb24;
-		display->dispsw_data = fbcon_cmap.cfb24;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	case 32:
-		display->dispsw = &fbcon_cfb32;
-		display->dispsw_data = fbcon_cmap.cfb32;
-		break;
-#endif
-	default:
-		display->dispsw = &fbcon_dummy;
-		return;
-	}
-}
-
-static int macfb_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
-{
-	static int first = 1;
-
-	if (var->xres           != macfb_defined.xres           ||
-	    var->yres           != macfb_defined.yres           ||
-	    var->xres_virtual   != macfb_defined.xres_virtual   ||
-	    var->yres_virtual   != macfb_defined.yres           ||
-	    var->xoffset                                        ||
-	    var->bits_per_pixel != macfb_defined.bits_per_pixel ||
-	    var->nonstd) {
-		if (first) {
-			printk("macfb does not support changing the video mode\n");
-			first = 0;
-		}
-		return -EINVAL;
-	}
-
-	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
-		return 0;
-
-	if (var->yoffset)
-		return -EINVAL;
-	return 0;
-}
-
-#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB4) || defined(FBCON_HAS_CFB2)
 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
 				unsigned int green, unsigned int blue)
 {
@@ -349,15 +184,15 @@
 	cli();
 	
 	/* tell clut which address to fill */
-	writeb(regno, &valkyrie_cmap_regs->addr);
+	nubus_writeb(regno, &valkyrie_cmap_regs->addr);
 	nop();
 
 	/* send one color channel at a time */
-	writeb(red, &valkyrie_cmap_regs->lut);
+	nubus_writeb(red, &valkyrie_cmap_regs->lut);
 	nop();
-	writeb(green, &valkyrie_cmap_regs->lut);
+	nubus_writeb(green, &valkyrie_cmap_regs->lut);
 	nop();
-	writeb(blue, &valkyrie_cmap_regs->lut);
+	nubus_writeb(blue, &valkyrie_cmap_regs->lut);
 
 	restore_flags(flags);
 
@@ -389,25 +224,25 @@
 		int i;
 		
 		/* Stab in the dark trying to reset the CLUT pointer */
-		writel(0, &dafb_cmap_regs->reset);
+		nubus_writel(0, &dafb_cmap_regs->reset);
 		nop();
 		
 		/* Loop until we get to the register we want */
 		for (i = 0; i < regno; i++) {
-			writeb(palette[i].red >> 8, &dafb_cmap_regs->lut);
+			nubus_writeb(palette[i].red >> 8, &dafb_cmap_regs->lut);
 			nop();
-			writeb(palette[i].green >> 8, &dafb_cmap_regs->lut);
+			nubus_writeb(palette[i].green >> 8, &dafb_cmap_regs->lut);
 			nop();
-			writeb(palette[i].blue >> 8, &dafb_cmap_regs->lut);
+			nubus_writeb(palette[i].blue >> 8, &dafb_cmap_regs->lut);
 			nop();
 		}
 	}
 		
-	writeb(red, &dafb_cmap_regs->lut);
+	nubus_writeb(red, &dafb_cmap_regs->lut);
 	nop();
-	writeb(green, &dafb_cmap_regs->lut);
+	nubus_writeb(green, &dafb_cmap_regs->lut);
 	nop();
-	writeb(blue, &dafb_cmap_regs->lut);
+	nubus_writeb(blue, &dafb_cmap_regs->lut);
 	
 	restore_flags(flags);
 	
@@ -425,7 +260,7 @@
 	unsigned char _regno;
 	unsigned long flags;
 
-	if (video_bpp>8) return 1; /* failsafe */
+	if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
 
 	save_flags(flags);
 	cli();
@@ -438,13 +273,13 @@
 	   In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
 	   
 	   In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */
-  	_regno = (regno<<(8-video_bpp)) | (0xFF>>video_bpp);
-	writeb(_regno, &v8_brazil_cmap_regs->addr); nop();
+  	_regno = (regno<<(8 - info->var.bits_per_pixel)) | (0xFF >> info->var.vits_per_pixel);
+	nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop();
 
 	/* send one color channel at a time */
-	writeb(_red, &v8_brazil_cmap_regs->lut); nop();
-	writeb(_green, &v8_brazil_cmap_regs->lut); nop();
-	writeb(_blue, &v8_brazil_cmap_regs->lut);
+	nubus_writeb(_red, &v8_brazil_cmap_regs->lut); nop();
+	nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop();
+	nubus_writeb(_blue, &v8_brazil_cmap_regs->lut);
 
 	restore_flags(flags);
 	
@@ -461,7 +296,7 @@
 	unsigned char _regno;
 	unsigned long flags;
 
-	if (video_bpp>8) return 1; /* failsafe */
+	if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
 
 	save_flags(flags);
 	cli();
@@ -470,18 +305,18 @@
 	 * regno #254 and #255 are the important ones for 1-bit color,
 	 * regno #252-255 are the important ones for 2-bit color, etc.
 	 */
-	_regno = regno + (256-(1<<video_bpp));
+	_regno = regno + (256-(1 << info->var.bits_per_pixel));
 
 	/* reset clut? (VideoToolbox sez "not necessary") */
-	writeb(0xFF, &rbv_cmap_regs->cntl); nop();
+	nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
 	
 	/* tell clut which address to use. */
-	writeb(_regno, &rbv_cmap_regs->addr); nop();
+	nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
 	
 	/* send one color channel at a time. */
-	writeb(_red,   &rbv_cmap_regs->lut); nop();
-	writeb(_green, &rbv_cmap_regs->lut); nop();
-	writeb(_blue,  &rbv_cmap_regs->lut);
+	nubus_writeb(_red,   &rbv_cmap_regs->lut); nop();
+	nubus_writeb(_green, &rbv_cmap_regs->lut); nop();
+	nubus_writeb(_blue,  &rbv_cmap_regs->lut);
 	
 	restore_flags(flags);
 	/* done. */
@@ -505,10 +340,10 @@
 	cli();
 	
 	/* the nop's are there to order writes. */
-	writeb(_regno, &cmap_regs->addr); nop();
-	writeb(_red, &cmap_regs->lut);    nop();
-	writeb(_green, &cmap_regs->lut);  nop();
-	writeb(_blue, &cmap_regs->lut);
+	nubus_writeb(_regno, &cmap_regs->addr); nop();
+	nubus_writeb(_red, &cmap_regs->lut);    nop();
+	nubus_writeb(_green, &cmap_regs->lut);  nop();
+	nubus_writeb(_blue, &cmap_regs->lut);
 
 	restore_flags(flags);
 	return 0;
@@ -524,16 +359,16 @@
 	unsigned char _red  =~(red>>8);
 	unsigned char _green=~(green>>8);
 	unsigned char _blue =~(blue>>8);
-	unsigned char _regno = (regno<<(8-video_bpp)) | (0xFF>>video_bpp);
+	unsigned char _regno = (regno << (8 - info->var.bits_per_pixel)) | (0xFF >> info->var.bits_per_pixel);
 	unsigned long flags;
 
 	save_flags(flags);
 	cli();
 	
-	writeb(_regno, &cmap_regs->addr); nop();
-	writeb(_red, &cmap_regs->lut);    nop();
-	writeb(_green, &cmap_regs->lut);  nop();
-	writeb(_blue, &cmap_regs->lut);
+	nubus_writeb(_regno, &cmap_regs->addr); nop();
+	nubus_writeb(_red, &cmap_regs->lut);    nop();
+	nubus_writeb(_green, &cmap_regs->lut);  nop();
+	nubus_writeb(_blue, &cmap_regs->lut);
 
 	restore_flags(flags);
 	return 0;
@@ -554,10 +389,10 @@
 	save_flags(flags);
 	cli();
 	
-	writeb(regno, &cmap_regs->addr); nop();
-	writeb(_red, &cmap_regs->lut); nop();
-	writeb(_green, &cmap_regs->lut); nop();
-	writeb(_blue, &cmap_regs->lut);
+	nubus_writeb(regno, &cmap_regs->addr); nop();
+	nubus_writeb(_red, &cmap_regs->lut); nop();
+	nubus_writeb(_green, &cmap_regs->lut); nop();
+	nubus_writeb(_blue, &cmap_regs->lut);
 
 	restore_flags(flags);
 	return 0;
@@ -581,7 +416,7 @@
 	unsigned long flags;
 	int clut_status;
 	
-	if (video_bpp > 8) return 1; /* failsafe */
+	if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
 
 	red   >>= 8;
 	green >>= 8;
@@ -593,7 +428,7 @@
 	/*
 	 * Set the register address
 	 */
-	writeb(regno, &civic_cmap_regs->addr); nop();
+	nubus_writeb(regno, &civic_cmap_regs->addr); nop();
 
 	/*
 	 * Wait for VBL interrupt here;
@@ -618,42 +453,42 @@
 	 * Grab a status word and do some checking;
 	 * Then finally write the clut!
 	 */
-	clut_status =  readb(&civic_cmap_regs->status2);
+	clut_status =  nubus_readb(&civic_cmap_regs->status2);
 
 	if ((clut_status & 0x0008) == 0)
 	{
 #if 0
 		if ((clut_status & 0x000D) != 0)
 		{
-			writeb(0x00, &civic_cmap_regs->lut); nop();
-			writeb(0x00, &civic_cmap_regs->lut); nop();
+			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
+			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
 		}
 #endif
 
-		writeb(  red, &civic_cmap_regs->lut); nop();
-		writeb(green, &civic_cmap_regs->lut); nop();
-		writeb( blue, &civic_cmap_regs->lut); nop();
-		writeb( 0x00, &civic_cmap_regs->lut); nop();
+		nubus_writeb(  red, &civic_cmap_regs->lut); nop();
+		nubus_writeb(green, &civic_cmap_regs->lut); nop();
+		nubus_writeb( blue, &civic_cmap_regs->lut); nop();
+		nubus_writeb( 0x00, &civic_cmap_regs->lut); nop();
 	}
 	else
 	{
 		unsigned char junk;
 
-		junk = readb(&civic_cmap_regs->lut); nop();
-		junk = readb(&civic_cmap_regs->lut); nop();
-		junk = readb(&civic_cmap_regs->lut); nop();
-		junk = readb(&civic_cmap_regs->lut); nop();
+		junk = nubus_readb(&civic_cmap_regs->lut); nop();
+		junk = nubus_readb(&civic_cmap_regs->lut); nop();
+		junk = nubus_readb(&civic_cmap_regs->lut); nop();
+		junk = nubus_readb(&civic_cmap_regs->lut); nop();
 
 		if ((clut_status & 0x000D) != 0)
 		{
-			writeb(0x00, &civic_cmap_regs->lut); nop();
-			writeb(0x00, &civic_cmap_regs->lut); nop();
+			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
+			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
 		}
 
-		writeb(  red, &civic_cmap_regs->lut); nop();
-		writeb(green, &civic_cmap_regs->lut); nop();
-		writeb( blue, &civic_cmap_regs->lut); nop();
-		writeb( junk, &civic_cmap_regs->lut); nop();
+		nubus_writeb(  red, &civic_cmap_regs->lut); nop();
+		nubus_writeb(green, &civic_cmap_regs->lut); nop();
+		nubus_writeb( blue, &civic_cmap_regs->lut); nop();
+		nubus_writeb( junk, &civic_cmap_regs->lut); nop();
 	}
 
 	restore_flags(flags);
@@ -679,27 +514,6 @@
 	return 0;
 }
 
-#endif /* FBCON_HAS_CFB8 || FBCON_HAS_CFB4 || FBCON_HAS_CFB2 */
-
-static int macfb_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-			   unsigned *blue, unsigned *transp,
-			   struct fb_info *fb_info)
-{
-	/*
-	 *  Read a single color register and split it into colors/transparent.
-	 *  Return != 0 for invalid regno.
-	 */
-
-	if (regno >= video_cmap_len)
-		return 1;
-
-	*red   = palette[regno].red;
-	*green = palette[regno].green;
-	*blue  = palette[regno].blue;
-	*transp = 0;
-	return 0;
-}
-
 static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
 			   unsigned blue, unsigned transp,
 			   struct fb_info *fb_info)
@@ -711,103 +525,82 @@
 	 *  != 0 for invalid regno.
 	 */
 	
-	if (regno >= video_cmap_len)
+	if (regno >= info->cmap.len)
 		return 1;
 
-	palette[regno].red   = red;
-	palette[regno].green = green;
-	palette[regno].blue  = blue;
-
-	switch (video_bpp) {
-#ifdef FBCON_HAS_MFB
+	switch (info->var.bits_per_pixel) {
 	case 1:
 		/* We shouldn't get here */
 		break;
-#endif
-#ifdef FBCON_HAS_CFB2
 	case 2:
 		if (macfb_setpalette)
 			macfb_setpalette(regno, red, green, blue);
 		else
 			return 1;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB4
 	case 4:
 		if (macfb_setpalette)
 			macfb_setpalette(regno, red, green, blue);
 		else
 			return 1;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB8
 	case 8:
 		if (macfb_setpalette)
 			macfb_setpalette(regno, red, green, blue);
 		else
 			return 1;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB16
-	case 15:
 	case 16:
-		/* 1:5:5:5 */
-		fbcon_cmap.cfb16[regno] =
-			((red   & 0xf800) >>  1) |
-			((green & 0xf800) >>  6) |
-			((blue  & 0xf800) >> 11) |
-			((transp != 0) << 15);
-		break;
-#endif
+		if (info->var.red.offset == 10) {
+			/* 1:5:5:5 */
+			((u32*) (info->pseudo_palette))[regno] =
+					((red   & 0xf800) >>  1) |
+					((green & 0xf800) >>  6) |
+					((blue  & 0xf800) >> 11) |
+					((transp != 0) << 15);
+		} else {
+			/* 0:5:6:5 */
+			((u32*) (info->pseudo_palette))[regno] =
+					((red   & 0xf800)      ) |
+					((green & 0xfc00) >>  5) |
+					((blue  & 0xf800) >> 11);
+		}
+		break;	
 		/* I'm pretty sure that one or the other of these
 		   doesn't exist on 68k Macs */
-#ifdef FBCON_HAS_CFB24
 	case 24:
 		red   >>= 8;
 		green >>= 8;
 		blue  >>= 8;
-		fbcon_cmap.cfb24[regno] =
-			(red   << macfb_defined.red.offset)   |
-			(green << macfb_defined.green.offset) |
-			(blue  << macfb_defined.blue.offset);
+		((u32 *)(info->pseudo_palette))[regno] =
+			(red   << info->var.red.offset)   |
+			(green << info->var.green.offset) |
+			(blue  << info->var.blue.offset);
 		break;
-#endif
-#ifdef FBCON_HAS_CFB32
 	case 32:
 		red   >>= 8;
 		green >>= 8;
 		blue  >>= 8;
-		fbcon_cmap.cfb32[regno] =
-			(red   << macfb_defined.red.offset)   |
-			(green << macfb_defined.green.offset) |
-			(blue  << macfb_defined.blue.offset);
+		((u32 *)(info->pseudo_palette))[regno] =
+			(red   << info->var.red.offset)   |
+			(green << info->var.green.offset) |
+			(blue  << info->var.blue.offset);
 		break;
-#endif
     }
     return 0;
 }
 
-static int macfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info)
-{
-	if (con == info->currcon) /* current console? */
-		return fb_get_cmap(cmap, kspc, macfb_getcolreg, info);
-	else if (fb_display[con].cmap.len) /* non default colormap? */
-		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-	else
-		fb_copy_cmap(fb_default_cmap(video_cmap_len),
-		     cmap, kspc ? 0 : 2);
-	return 0;
-}
-
 static struct fb_ops macfb_ops = {
 	owner:		THIS_MODULE,
-	fb_get_fix:	macfb_get_fix,
-	fb_get_var:	macfb_get_var,
-	fb_set_var:	macfb_set_var,
-	fb_get_cmap:	macfb_get_cmap,
+	fb_get_fix:	gen_get_fix,
+	fb_get_var:	gen_get_var,
+	fb_set_var:	gen_set_var,
+	fb_get_cmap:	gen_get_cmap,
 	fb_set_cmap:	gen_set_cmap,
 	fb_setcolreg:	macfb_setcolreg,
+	fb_fillrect:	cfb_fillrect,
+	fb_copyarea:	cfb_copyarea,
+	fb_imageblit:	cfb_imageblit,
 };
 
 void __init macfb_setup(char *options, int *ints)
@@ -832,88 +625,67 @@
 	}
 }
 
-static int macfb_switch(int con, struct fb_info *info)
-{
-	/* Do we have to save the colormap? */
-	if (fb_display[info->currcon].cmap.len)
-		fb_get_cmap(&fb_display[info->currcon].cmap, 1, macfb_getcolreg,
-			    info);
-	
-	info->currcon = con;
-	/* Install new colormap */
-	do_install_cmap(con, info);
-	macfb_update_var(con, info);
-	return 1;
-}
-
 void __init macfb_init(void)
 {
+	int video_cmap_len, video_is_nubus = 0;
 	struct nubus_dev* ndev = NULL;
-	int video_is_nubus = 0;
 
 	if (!MACH_IS_MAC) 
 		return;
 
 	/* There can only be one internal video controller anyway so
 	   we're not too worried about this */
-	video_width      = mac_bi_data.dimensions & 0xFFFF;
-	video_height     = mac_bi_data.dimensions >> 16;
-	video_bpp        = mac_bi_data.videodepth;
-	video_linelength = mac_bi_data.videorow;
-	video_size       = video_linelength * video_height;
+	macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
+	macfb_defined.yres = mac_bi_data.dimensions >> 16;
+	macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
+	macfb_fix.line_length = mac_bi_data.videorow;
+	macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
 	/* Note: physical address (since 2.1.127) */
-	video_base       = (void*) mac_bi_data.videoaddr;
+	macfb_fix.smem_start = mac_bi_data.videoaddr;
 	/* This is actually redundant with the initial mappings.
 	   However, there are some non-obvious aspects to the way
 	   those mappings are set up, so this is in fact the safest
 	   way to ensure that this driver will work on every possible
 	   Mac */
-	video_vbase	 = ioremap(mac_bi_data.videoaddr, video_size);
+	fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
 	
-	printk("macfb: framebuffer at 0x%p, mapped to 0x%p, size %dk\n",
-	       video_base, video_vbase, video_size/1024);
+	printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
+	       macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
 	printk("macfb: mode is %dx%dx%d, linelength=%d\n",
-	       video_width, video_height, video_bpp, video_linelength);
+	       macfb_defined.xres, macfb_defined.yres/, macfb_defined.bits_per_pixel, macfb_fix.line_length);
 	
 	/*
 	 *	Fill in the available video resolution
 	 */
 	 
-	macfb_defined.xres           = video_width;
-	macfb_defined.yres           = video_height;
-	macfb_defined.xres_virtual   = video_width;
-	macfb_defined.yres_virtual   = video_height;
-	macfb_defined.bits_per_pixel = video_bpp;
+	macfb_defined.xres_virtual   = macfb_defined.xres;
+	macfb_defined.yres_virtual   = macfb_defined.yres;
 	macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
 	macfb_defined.width  = PIXEL_TO_MM(macfb_defined.xres);	 
 
 	printk("macfb: scrolling: redraw\n");
-	macfb_defined.yres_virtual = video_height;
+	macfb_defined.yres_virtual = macfb_defined.yres;
 
 	/* some dummy values for timing to make fbset happy */
-	macfb_defined.pixclock     = 10000000 / video_width * 1000 / video_height;
-	macfb_defined.left_margin  = (video_width / 8) & 0xf8;
-	macfb_defined.right_margin = 32;
-	macfb_defined.upper_margin = 16;
-	macfb_defined.lower_margin = 4;
-	macfb_defined.hsync_len    = (video_width / 8) & 0xf8;
-	macfb_defined.vsync_len    = 4;
+	macfb_defined.pixclock     = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
+	macfb_defined.left_margin  = (macfb_defined.xres / 8) & 0xf8;
+	macfb_defined.hsync_len    = (macfb_defined.xres / 8) & 0xf8;
 
-	switch (video_bpp) {
+	switch (macfb_defined.bits_per_pixel) {
 	case 1:
 		/* XXX: I think this will catch any program that tries
 		   to do FBIO_PUTCMAP when the visual is monochrome */
 		video_cmap_len = 0;
-		video_visual = FB_VISUAL_MONO01;
+		macfb_fix.visual = FB_VISUAL_MONO01;
 		break;
 	case 2:
 	case 4:
 	case 8:
-		macfb_defined.red.length = video_bpp;
-		macfb_defined.green.length = video_bpp;
-		macfb_defined.blue.length = video_bpp;
-		video_cmap_len = 1 << video_bpp;
-		video_visual = FB_VISUAL_PSEUDOCOLOR;
+		macfb_defined.red.length = macfb_defined.bits_per_pixel;
+		macfb_defined.green.length = macfb_defined.bits_per_pixel;
+		macfb_defined.blue.length = macfb_defined.bits_per_pixel;
+		video_cmap_len = 1 << macfb_defined.bits_per_pixel;
+		macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
 		break;
 	case 16:
 		macfb_defined.transp.offset = 15;
@@ -929,7 +701,7 @@
 		video_cmap_len = 16;
 		/* Should actually be FB_VISUAL_DIRECTCOLOR, but this
 		   works too */
-		video_visual = FB_VISUAL_TRUECOLOR;
+		macfb_fix.visual = FB_VISUAL_TRUECOLOR;
 		break;
 	case 24:
 	case 32:
@@ -944,11 +716,11 @@
 		printk("macfb: truecolor: "
 		       "size=0:8:8:8, shift=0:16:8:0\n");
 		video_cmap_len = 16;
-		video_visual = FB_VISUAL_TRUECOLOR;
+		macfb_fix.visual = FB_VISUAL_TRUECOLOR;
 	default:
 		video_cmap_len = 0;
-		video_visual = FB_VISUAL_MONO01;
-		printk("macfb: unknown or unsupported bit depth: %d\n", video_bpp);
+		macfb_fix.visual = FB_VISUAL_MONO01;
+		printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
 		break;
 	}
 	
@@ -974,22 +746,22 @@
 
 		switch(ndev->dr_hw) {
 		case NUBUS_DRHW_APPLE_MDC:
-			strcpy( fb_info.modename, "Macintosh Display Card" );
+			strcat( macfb_fix.id, "Display Card" );
 			macfb_setpalette = mdc_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
 			break;
 		case NUBUS_DRHW_APPLE_TFB:
-			strcpy( fb_info.modename, "Toby" );
+			strcat( macfb_fix.id, "Toby" );
 			macfb_setpalette = toby_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
 			break;
 		case NUBUS_DRHW_APPLE_JET:
-			strcpy(fb_info.modename, "Jet");
+			strcat( macfb_fix.id, "Jet");
 			macfb_setpalette = jet_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
 			break;			
 		default:
-			strcpy( fb_info.modename, "Generic NuBus" );
+			strcat( macfb_fix.id, "Generic NuBus" );
 			break;
 		}
 	}
@@ -1007,14 +779,14 @@
 		case MAC_MODEL_IIX:
 		case MAC_MODEL_IICX:
 		case MAC_MODEL_IIFX:
-			strcpy( fb_info.modename, "Generic NuBus" );
+			strcat( macfb_fix.id, "Generic NuBus" );
 			break;
 
 			/* Valkyrie Quadras */
 		case MAC_MODEL_Q630:
 			/* I'm not sure about this one */
 		case MAC_MODEL_P588:
-			strcpy( fb_info.modename, "Valkyrie built-in" );
+			strcat( macfb_fix.id, "Valkyrie built-in" );
 			macfb_setpalette = valkyrie_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
 			valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
@@ -1037,7 +809,7 @@
 		case MAC_MODEL_Q700:
 		case MAC_MODEL_Q900:
 		case MAC_MODEL_Q950:
-			strcpy( fb_info.modename, "DAFB built-in" );
+			strcat( macfb_fix.id, "DAFB built-in" );
 			macfb_setpalette = dafb_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
 			dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
@@ -1045,7 +817,7 @@
 
 			/* LC II uses the V8 framebuffer */
 		case MAC_MODEL_LCII:
-			strcpy( fb_info.modename, "V8 built-in" );
+			strcat( macfb_fix.id, "V8 built-in" );
 			macfb_setpalette = v8_brazil_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
 			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
@@ -1057,7 +829,7 @@
 		case MAC_MODEL_IIVI:
 		case MAC_MODEL_IIVX:
 		case MAC_MODEL_P600:
-			strcpy( fb_info.modename, "Brazil built-in" );
+			strcat( macfb_fix.id, "Brazil built-in" );
 			macfb_setpalette = v8_brazil_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
 			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
@@ -1074,7 +846,7 @@
 		case MAC_MODEL_P460:
 			macfb_setpalette = v8_brazil_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
-			strcpy( fb_info.modename, "Sonora built-in" );
+			strcat( macfb_fix.id, "Sonora built-in" );
 			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 			break;
 
@@ -1085,7 +857,7 @@
 		case MAC_MODEL_IISI:
 			macfb_setpalette = rbv_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
-			strcpy( fb_info.modename, "RBV built-in" );
+			strcat( macfb_fix.id, "RBV built-in" );
 			rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
 			break;
 
@@ -1094,7 +866,7 @@
 		case MAC_MODEL_C660:
 			macfb_setpalette = civic_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
-			strcpy( fb_info.modename, "Civic built-in" );
+			strcat( macfb_fix.id, "Civic built-in" );
 			civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
 			break;
 
@@ -1115,7 +887,7 @@
 				v8_brazil_cmap_regs =
 					ioremap(DAC_BASE, 0x1000);
 			}
-			strcpy( fb_info.modename, "LC built-in" );
+			strcat( macfb_fix.id, "LC built-in" );
 			break;
 			/* We think this may be like the LC II */
 		case MAC_MODEL_CCL:
@@ -1125,18 +897,18 @@
 				v8_brazil_cmap_regs =
 					ioremap(DAC_BASE, 0x1000);
 			}
-			strcpy( fb_info.modename, "Color Classic built-in" );
+			strcat( macfb_fix.id, "Color Classic built-in" );
 			break;
 
 			/* And we *do* mean "weirdos" */
 		case MAC_MODEL_TV:
-			strcpy( fb_info.modename, "Mac TV built-in" );
+			strcat( macfb_fix.id, "Mac TV built-in" );
 			break;
 
 			/* These don't have colour, so no need to worry */
 		case MAC_MODEL_SE30:
 		case MAC_MODEL_CLII:
-			strcpy( fb_info.modename, "Monochrome built-in" );
+			strcat( macfb_fix.id, "Monochrome built-in" );
 			break;
 
 			/* Powerbooks are particularly difficult.  Many of
@@ -1149,7 +921,7 @@
 		case MAC_MODEL_PB140:
 		case MAC_MODEL_PB145:
 		case MAC_MODEL_PB170:
-			strcpy( fb_info.modename, "DDC built-in" );
+			strcat( macfb_fix.id, "DDC built-in" );
 			break;
 
 			/* Internal is GSC, External (if present) is ViSC */
@@ -1159,13 +931,13 @@
 		case MAC_MODEL_PB180:
 		case MAC_MODEL_PB210:
 		case MAC_MODEL_PB230:
-			strcpy( fb_info.modename, "GSC built-in" );
+			strcat( macfb_fix.id, "GSC built-in" );
 			break;
 
 			/* Internal is TIM, External is ViSC */
 		case MAC_MODEL_PB165C:
 		case MAC_MODEL_PB180C:
-			strcpy( fb_info.modename, "TIM built-in" );
+			strcat( macfb_fix.id, "TIM built-in" );
 			break;
 
 			/* Internal is CSC, External is Keystone+Ariel. */
@@ -1177,31 +949,36 @@
 		case MAC_MODEL_PB280C:
 			macfb_setpalette = csc_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
-			strcpy( fb_info.modename, "CSC built-in" );
+			strcat( macfb_fix.id, "CSC built-in" );
 			csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
 			break;
 		
 		default:
-			strcpy( fb_info.modename, "Unknown/Unsupported built-in" );
+			strcat( macfb_fix.id, "Unknown/Unsupported built-in" );
 			break;
 		}
-	
-	fb_info.changevar   = NULL;
-	fb_info.node        = NODEV;
-	fb_info.fbops       = &macfb_ops;
-	fb_info.screen_base = video_vbase;
-	fb_info.disp        = &disp;
-	fb_info.switch_con  = &macfb_switch;
-	fb_info.updatevar   = &macfb_update_var;
-	fb_info.flags       = FBINFO_FLAG_DEFAULT;
-	macfb_set_disp(-1);
-	do_install_cmap(0, &fb_info);
+
+	strcpy(fb_info.modename, macfb_fix.id);	
+	fb_info.changevar	= NULL;
+	fb_info.node		= NODEV;
+	fb_info.fbops		= &macfb_ops;
+	fb_info.var		= macfb_defined;
+	fb_info.fix		= macfb_fix;
+	fb_info.currcon		= -1;	
+	fb_info.disp		= &disp;
+	fb_info.switch_con	= gen_switch;
+	fb_info.updatevar	= gen_update_var;
+	fb_info.pseudo_palatte	= pseudo_palette;
+	fb_info.flags		= FBINFO_FLAG_DEFAULT;
+
+	fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
+	gen_set_disp(-1, info);
 	
 	if (register_framebuffer(&fb_info) < 0)
 		return;
 
 	printk("fb%d: %s frame buffer device\n",
-	       GET_FB_IDX(fb_info.node), fb_info.modename);
+	       GET_FB_IDX(fb_info.node), fb_info.fix.id);
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/macmodes.c b/drivers/video/macmodes.c
--- a/drivers/video/macmodes.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/video/macmodes.c	Wed Jul 24 14:03:39 2002
@@ -20,14 +20,9 @@
 #include <linux/fb.h>
 #include <linux/string.h>
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-#endif
-
 #include <video/fbcon.h>
 #include <video/macmodes.h>
 
-
     /*
      *  MacOS video mode definitions
      *
@@ -207,171 +202,6 @@
     { -1,    VMODE_640_480_60 },	/* catch-all, must be last */
 };
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-struct fb_info *console_fb_info = NULL;
-struct vc_mode display_info;
-
-static u16 palette_red[16];
-static u16 palette_green[16];
-static u16 palette_blue[16];
-static struct fb_cmap palette_cmap = {
-    0, 16, palette_red, palette_green, palette_blue, NULL
-};
-
-
-/**
- *	console_getmode - get current mode
- *	@mode: virtual console mode structure
- *
- *	Populates @mode with the current mode held in the global
- *	display_info structure.
- *
- *	Note, this function is only for XPMAC compatibility.
- *
- *	Returns zero.
- */
-
-int console_getmode(struct vc_mode *mode)
-{
-    *mode = display_info;
-    return 0;
-}
-
-
-/**
- *	console_setmode - sets current console mode
- *	@mode: virtual console mode structure
- *	@doit: boolean, 0 test mode, 1 test and activate mode
- *
- *	Sets @mode for all virtual consoles if @doit is non-zero,
- *	otherwise, test a mode for validity.
- *
- *	Note, this function is only for XPMAC compatibility.
- *
- *	Returns negative errno on error, or zero for success.
- *
- */
-
-int console_setmode(struct vc_mode *mode, int doit)
-{
-    struct fb_var_screeninfo var;
-    int cmode, err;
-
-    if (!console_fb_info)
-        return -EOPNOTSUPP;
-
-    switch(mode->depth) {
-        case 0:
-        case 8:
-            cmode = CMODE_8;
-            break;
-        case 16:
-            cmode = CMODE_16;
-            break;
-        case 24:
-        case 32:
-            cmode = CMODE_32;
-            break;
-        default:
-            return -EINVAL;
-    }
-
-    if ((err = mac_vmode_to_var(mode->mode, cmode, &var)))
-        return err;
-
-    var.activate = FB_ACTIVATE_TEST;
-    err = console_fb_info->fbops->fb_set_var(&var, fg_console,
-                                             console_fb_info);
-    if (err || !doit)
-        return err;
-    else {
-        int unit;
-
-        var.activate = FB_ACTIVATE_NOW;
-        for (unit = 0; unit < MAX_NR_CONSOLES; unit++)
-            if (fb_display[unit].conp &&
-                (GET_FB_IDX(console_fb_info->node) == con2fb_map[unit]))
-                console_fb_info->fbops->fb_set_var(&var, unit,
-                                                   console_fb_info);
-    }
-
-    return 0;
-}
-
-
-/**
- *	console_setcmap - sets palette color map for console
- *	@n_entries: number of entries in the palette (max 16)
- *	@red: value for red component of palette
- *	@green: value for green component of palette
- *	@blue: value for blue component of palette
- *
- *	Sets global palette_cmap structure and activates the palette
- *	on the current console.
- *
- *	Note, this function is only for XPMAC compatibility.
- *
- *	Returns negative errno on error, or zero for success.
- *
- */
-
-int console_setcmap(int n_entries, unsigned char *red, unsigned char *green,
-                    unsigned char *blue)
-{
-    int i, j, n = 0, err;
-
-    if (!console_fb_info)
-        return -EOPNOTSUPP;
-
-    for (i = 0; i < n_entries; i += n) {
-        n = n_entries - i;
-        if (n > 16)
-            n = 16;
-        palette_cmap.start = i;
-        palette_cmap.len = n;
-
-        for (j = 0; j < n; j++) {
-            palette_cmap.red[j] = (red[i+j] << 8) | red[i+j];
-            palette_cmap.green[j] = (green[i+j] << 8) | green[i+j];
-            palette_cmap.blue[j] = (blue[i+j] << 8) | blue[i+j];
-        }
-        err = console_fb_info->fbops->fb_set_cmap(&palette_cmap, 1,
-                                                  fg_console,
-                                                  console_fb_info);
-        if (err)
-            return err;
-    }
-
-    return 0;
-}
-
-
-/**
- *	console_powermode - sets monitor power mode
- *	@mode: power state to set
- *
- *	Sets power state as dictated by @mode.
- *
- *	Note that this function is only for XPMAC compatibility and
- *	doesn't do much.
- *
- *	Returns 0 for %VC_POWERMODE_INQUIRY, -EINVAL for VESA power
- *	settings, or -ENIXIO on failure.
- *
- */
-
-int console_powermode(int mode)
-{
-    if (mode == VC_POWERMODE_INQUIRY)
-        return 0;
-    if (mode < VESA_NO_BLANKING || mode > VESA_POWERDOWN)
-        return -EINVAL;
-    /* Not Supported */
-    return -ENXIO;
-}
-#endif /* CONFIG_FB_COMPAT_XPMAC */
-
-
 /**
  *	mac_vmode_to_var - converts vmode/cmode pair to var structure
  *	@vmode: MacOS video mode
@@ -548,6 +378,7 @@
     unsigned int dbsize = 0;
 
     if (mode_option && !strncmp(mode_option, "mac", 3)) {
+	mode_option += 3;
 	db = mac_modedb;
 	dbsize = sizeof(mac_modedb)/sizeof(*mac_modedb);
     }
diff -Nru a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
--- a/drivers/video/matrox/matroxfb_base.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/matrox/matroxfb_base.c	Wed Jul 24 14:03:38 2002
@@ -68,7 +68,7 @@
  *               "Samuel Hocevar" <sam@via.ecp.fr>
  *                     Fixes
  *
- *               "Anton Altaparmakov"
+ *               "Anton Altaparmakov" <AntonA@bigfoot.com>
  *                     G400 MAX/non-MAX distinction
  *
  *               "Ken Aaker" <kdaaker@rchland.vnet.ibm.com>
@@ -883,25 +883,6 @@
 			}
 			matrox_cfbX_init(PMINFO display);
 			my_install_cmap(PMINFO2);
-#if defined(CONFIG_FB_COMPAT_XPMAC)
-			if (console_fb_info == &ACCESS_FBINFO(fbcon)) {
-				int vmode, cmode;
-
-				display_info.width = var->xres;
-				display_info.height = var->yres;
-				display_info.depth = var->bits_per_pixel;
-				display_info.pitch = (var->xres_virtual)*(var->bits_per_pixel)/8;
-				if (mac_var_to_vmode(var, &vmode, &cmode))
-					display_info.mode = 0;
-				else
-					display_info.mode = vmode;
-				strcpy(display_info.name, ACCESS_FBINFO(matrox_name));
-				display_info.fb_address = ACCESS_FBINFO(video.base);
-				display_info.cmap_adr_address = 0;
-				display_info.cmap_data_address = 0;
-				display_info.disp_reg_address = ACCESS_FBINFO(mmio.base);
-			}
-#endif /* CONFIG_FB_COMPAT_XPMAC */
 		}
 	}
 	return 0;
@@ -1848,12 +1829,6 @@
 
 	/* FIXME: Where to move this?! */
 #if defined(CONFIG_ALL_PPC)
-#if defined(CONFIG_FB_COMPAT_XPMAC)
-	strcpy(ACCESS_FBINFO(matrox_name), "MTRX,");	/* OpenFirmware naming convension */
-	strncat(ACCESS_FBINFO(matrox_name), b->name, 26);
-	if (!console_fb_info)
-		console_fb_info = &ACCESS_FBINFO(fbcon);
-#endif
 #ifndef MODULE
 	if (_machine == _MACH_Pmac) {
 		struct fb_var_screeninfo var;
diff -Nru a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
--- a/drivers/video/matrox/matroxfb_base.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/matrox/matroxfb_base.h	Wed Jul 24 14:03:38 2002
@@ -56,9 +56,6 @@
 #include <video/fbcon-cfb24.h>
 #include <video/fbcon-cfb32.h>
 
-#if defined(CONFIG_FB_COMPAT_XPMAC)
-#include <asm/vc_ioctl.h>
-#endif
 #if defined(CONFIG_PPC)
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
@@ -591,9 +588,6 @@
 				      } memory;
 			      } values;
 	struct { unsigned red, green, blue, transp; } palette[256];
-#if defined(CONFIG_FB_COMPAT_XPMAC)
-	char	matrox_name[32];
-#endif
 /* These ifdefs must be last! They differ for module & non-module compiles */
 #if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
 	union {
diff -Nru a/drivers/video/modedb.c b/drivers/video/modedb.c
--- a/drivers/video/modedb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/modedb.c	Wed Jul 24 14:03:38 2002
@@ -111,6 +111,10 @@
 	NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
 	0, FB_VMODE_INTERLACED
     }, {
+	/* 1400x1050 @ 60Hz, 63.9 kHz hsync */
+	NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
+	0, FB_VMODE_NONINTERLACED
+    }, {
 	/* 800x600 @ 100 Hz, 64.02 kHz hsync */
 	NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
 	0, FB_VMODE_NONINTERLACED
@@ -126,6 +130,10 @@
 	/* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
 	NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
 	0, FB_VMODE_NONINTERLACED
+    }, {
+	/* 1400x1050 @ 60Hz, 63.9 kHz hsync */
+	NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
+	0, FB_VMODE_NONINTERLACED   	
     }, {
 	/* 1024x768 @ 85 Hz, 70.24 kHz hsync */
 	NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
diff -Nru a/drivers/video/neofb.c b/drivers/video/neofb.c
--- a/drivers/video/neofb.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/video/neofb.c	Wed Jul 24 14:03:35 2002
@@ -1915,8 +1915,7 @@
 	/*
 	 * Our driver data
 	 */
-	dev->driver_data = info;
-
+	pci_set_drvdata(dev, info);
 	return 0;
 
       failed:
@@ -1929,7 +1928,7 @@
 
 static void __devexit neofb_remove(struct pci_dev *dev)
 {
-	struct fb_info *info = (struct fb_info *) dev->driver_data;
+	struct fb_info *info = pci_get_drvdata(dev);
 
 	DBG("neofb_remove");
 
@@ -1951,7 +1950,7 @@
 		 * Ensure that the driver data is no longer
 		 * valid.
 		 */
-		dev->driver_data = NULL;
+		pci_set_drvdata(dev, NULL);
 	}
 }
 
diff -Nru a/drivers/video/offb.c b/drivers/video/offb.c
--- a/drivers/video/offb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/offb.c	Wed Jul 24 14:03:38 2002
@@ -27,9 +27,6 @@
 #include <linux/selection.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-#endif
 #include <asm/io.h>
 #include <asm/prom.h>
 #ifdef CONFIG_BOOTX_TEXT
@@ -37,67 +34,42 @@
 #endif
 
 #include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb32.h>
 #include <video/macmodes.h>
 
 /* Supported palette hacks */
 enum {
 	cmap_unknown,
-	cmap_m64,	/* ATI Mach64 */
-	cmap_r128,	/* ATI Rage128 */
-	cmap_M3A,	/* ATI Rage Mobility M3 Head A */
-	cmap_M3B,	/* ATI Rage Mobility M3 Head B */
-	cmap_radeon,	/* ATI Radeon */
-	cmap_gxt2000,	/* IBM GXT2000 */
+	cmap_m64,		/* ATI Mach64 */
+	cmap_r128,		/* ATI Rage128 */
+	cmap_M3A,		/* ATI Rage Mobility M3 Head A */
+	cmap_M3B,		/* ATI Rage Mobility M3 Head B */
+	cmap_radeon,		/* ATI Radeon */
+	cmap_gxt2000,		/* IBM GXT2000 */
 };
 
-struct fb_info_offb {
-    struct fb_info info;
-    struct fb_fix_screeninfo fix;
-    struct fb_var_screeninfo var;
-    struct display disp;
-    struct { u_char red, green, blue, pad; } palette[256];
-    volatile unsigned char *cmap_adr;
-    volatile unsigned char *cmap_data;
-    int cmap_type;
-    int blanked;
-    union {
-#ifdef FBCON_HAS_CFB16
-	u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-	u32 cfb32[16];
-#endif
-    } fbcon_cmap;
+struct offb_par {
+	volatile unsigned char *cmap_adr;
+	volatile unsigned char *cmap_data;
+	int cmap_type;
+	int blanked;
 };
 
+struct offb_par default_par;
+
 #ifdef __powerpc__
 #define mach_eieio()	eieio()
 #else
 #define mach_eieio()	do {} while (0)
 #endif
 
-
     /*
      *  Interface used by the world
      */
 
 int offb_init(void);
 
-static int offb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			struct fb_info *info);
-static int offb_get_var(struct fb_var_screeninfo *var, int con,
-			struct fb_info *info);
-static int offb_set_var(struct fb_var_screeninfo *var, int con,
-			struct fb_info *info);
-static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			struct fb_info *info);
-static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			struct fb_info *info);
 static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			 u_int transp, struct fb_info *info);
+			  u_int transp, struct fb_info *info);
 static int offb_blank(int blank, struct fb_info *info);
 
 #ifdef CONFIG_BOOTX_TEXT
@@ -105,147 +77,101 @@
 #endif
 
 static void offb_init_nodriver(struct device_node *);
-static void offb_init_fb(const char *name, const char *full_name, int width,
-		      int height, int depth, int pitch, unsigned long address,
-		      struct device_node *dp);
-
-    /*
-     *  Interface to the low level console driver
-     */
-
-static int offbcon_switch(int con, struct fb_info *info);
-static int offbcon_updatevar(int con, struct fb_info *info);
-
-    /*
-     *  Internal routines
-     */
-
-static int offb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			 u_int *transp, struct fb_info *info);
+static void offb_init_fb(const char *name, const char *full_name,
+			 int width, int height, int depth, int pitch,
+			 unsigned long address, struct device_node *dp);
 
 static struct fb_ops offb_ops = {
 	owner:		THIS_MODULE,
-	fb_get_fix:	offb_get_fix,
-	fb_get_var:	offb_get_var,
-	fb_set_var:	offb_set_var,
-	fb_get_cmap:	offb_get_cmap,
-	fb_set_cmap:	offb_set_cmap,
+	fb_get_fix:	gen_get_fix,
+	fb_get_var:	gen_get_var,
+	fb_set_var:	gen_set_var,
+	fb_get_cmap:	gen_get_cmap,
+	fb_set_cmap:	gen_set_cmap,
 	fb_setcolreg:	offb_setcolreg,
 	fb_blank:	offb_blank,
+	fb_fillrect:	cfb_fillrect,
+	fb_copyarea:	cfb_copyarea,
+	fb_imageblit:	cfb_imageblit,
 };
 
     /*
-     *  Get the Fixed Part of the Display
-     */
-
-static int offb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			struct fb_info *info)
-{
-    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
-
-    memcpy(fix, &info2->fix, sizeof(struct fb_fix_screeninfo));
-    return 0;
-}
-
-
-    /*
-     *  Get the User Defined Part of the Display
-     */
-
-static int offb_get_var(struct fb_var_screeninfo *var, int con,
-			struct fb_info *info)
-{
-    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
-
-    memcpy(var, &info2->var, sizeof(struct fb_var_screeninfo));
-    return 0;
-}
-
-
-    /*
-     *  Set the User Defined Part of the Display
-     */
-
-static int offb_set_var(struct fb_var_screeninfo *var, int con,
-			struct fb_info *info)
-{
-    struct display *display;
-    unsigned int oldbpp = 0;
-    int err;
-    int activate = var->activate;
-    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
-
-    if (con >= 0)
-	display = &fb_display[con];
-    else
-	display = &info2->disp;	/* used during initialization */
-
-    if (var->xres > info2->var.xres || var->yres > info2->var.yres ||
-	var->xres_virtual > info2->var.xres_virtual ||
-	var->yres_virtual > info2->var.yres_virtual ||
-	var->bits_per_pixel > info2->var.bits_per_pixel ||
-	var->nonstd ||
-	(var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-	return -EINVAL;
-    memcpy(var, &info2->var, sizeof(struct fb_var_screeninfo));
-
-    if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-	oldbpp = display->var.bits_per_pixel;
-	display->var = *var;
-    }
-    if ((oldbpp != var->bits_per_pixel) || (display->cmap.len == 0)) {
-	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
-	    return err;
-	do_install_cmap(con, info);
-    }
-    return 0;
-}
-
-
-    /*
-     *  Get the Colormap
+     *  Set a single color register. The values supplied are already
+     *  rounded down to the hardware's capabilities (according to the
+     *  entries in the var structure). Return != 0 for invalid regno.
      */
 
-static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			 struct fb_info *info)
+static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			  u_int transp, struct fb_info *info)
 {
-    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
+	struct offb_par *par = (struct offb_par *) info->par;
 
-    if (con == info->currcon && !info2->blanked) /* current console? */		
-	return fb_get_cmap(cmap, kspc, offb_getcolreg, info);
-    if (fb_display[con].cmap.len) /* non default colormap? */
-	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-    else
-    {
-	int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
-	fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
-    }
-    return 0;
-}
-
-    /*
-     *  Set the Colormap
-     */
+	if (!par->cmap_adr || regno > 255)
+		return 1;
 
-static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			 struct fb_info *info)
-{
-    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
-    int err;
-
-    if (!info2->cmap_adr)
-	return -ENOSYS;
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+	switch (par->cmap_type) {
+	case cmap_m64:
+		*par->cmap_adr = regno;
+		mach_eieio();
+		*par->cmap_data = red;
+		mach_eieio();
+		*par->cmap_data = green;
+		mach_eieio();
+		*par->cmap_data = blue;
+		mach_eieio();
+		break;
+	case cmap_M3A:
+		/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
+		out_le32((unsigned *) (par->cmap_adr + 0x58),
+			 in_le32((unsigned *) (par->cmap_adr +
+					       0x58)) & ~0x20);
+	case cmap_r128:
+		/* Set palette index & data */
+		out_8(par->cmap_adr + 0xb0, regno);
+		out_le32((unsigned *) (par->cmap_adr + 0xb4),
+			 (red << 16 | green << 8 | blue));
+		break;
+	case cmap_M3B:
+		/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
+		out_le32((unsigned *) (par->cmap_adr + 0x58),
+			 in_le32((unsigned *) (par->cmap_adr +
+					       0x58)) | 0x20);
+		/* Set palette index & data */
+		out_8(par->cmap_adr + 0xb0, regno);
+		out_le32((unsigned *) (par->cmap_adr + 0xb4),
+			 (red << 16 | green << 8 | blue));
+		break;
+	case cmap_radeon:
+		/* Set palette index & data (could be smarter) */
+		out_8(par->cmap_adr + 0xb0, regno);
+		out_le32((unsigned *) (par->cmap_adr + 0xb4),
+			 (red << 16 | green << 8 | blue));
+		break;
+	case cmap_gxt2000:
+		out_le32((unsigned *) par->cmap_adr + regno,
+			 (red << 16 | green << 8 | blue));
+		break;
+	}
 
-    if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
-	int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
-	if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))
-	    return err;
-    }
-    if (con == info->currcon && !info2->blanked)	/* current console? */
-	return fb_set_cmap(cmap, kspc, info);
-    else
-	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
-    return 0;
+	if (regno < 16)
+		switch (info->var.bits_per_pixel) {
+		case 16:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 10) | (regno << 5) | regno;
+			break;
+		case 32:
+			{
+				int i = (regno << 8) | regno;
+				((u32 *) (info->pseudo_palette))[regno] =
+				    (i << 16) | i;
+				break;
+			}
+		}
+	return 0;
 }
 
     /*
@@ -254,62 +180,69 @@
 
 static int offb_blank(int blank, struct fb_info *info)
 {
-    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
-    int i, j;
+	struct offb_par *par = (struct offb_par *) info->par;
+	int i, j;
 
-    if (!info2->cmap_adr)
-	return 0;
+	if (!par->cmap_adr)
+		return 0;
 
-    if (!info2->blanked) {
-       if (!blank)
-	   return 0;
-       if (fb_display[info->currcon].cmap.len)
-   	   fb_get_cmap(&fb_display[info->currcon].cmap, 1, offb_getcolreg,info);
-    }
-
-    info2->blanked = blank;
-	
-
-    if (blank)
-	for (i = 0; i < 256; i++) {
-	    switch(info2->cmap_type) {
-	    case cmap_m64:
-	        *info2->cmap_adr = i;
-	  	mach_eieio();
-	  	for (j = 0; j < 3; j++) {
-		    *info2->cmap_data = 0;
-		    mach_eieio();
-	    	}
-	    	break;
-	    case cmap_M3A:
-	        /* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
-	    	out_le32((unsigned *)(info2->cmap_adr + 0x58),
-	    		in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
-	    case cmap_r128:
-	    	/* Set palette index & data */
-    	        out_8(info2->cmap_adr + 0xb0, i);
-	    	out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
-	    	break;
-	    case cmap_M3B:
-	        /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
-	    	out_le32((unsigned *)(info2->cmap_adr + 0x58),
-	    		in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
-	    	/* Set palette index & data */
-	    	out_8(info2->cmap_adr + 0xb0, i);
-	    	out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
-	    	break;
-	    case cmap_radeon:
-    	        out_8(info2->cmap_adr + 0xb0, i);
-	    	out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
-	    	break;
-	    case cmap_gxt2000:
-		out_le32((unsigned *)info2->cmap_adr + i, 0);
-		break;
-	    }
-	}
-    else
-	do_install_cmap(info->currcon, info);
-    return 0;	
+	if (!par->blanked)
+		if (!blank)
+			return 0;
+
+	par->blanked = blank;
+
+	if (blank)
+		for (i = 0; i < 256; i++) {
+			switch (par->cmap_type) {
+			case cmap_m64:
+				*par->cmap_adr = i;
+				mach_eieio();
+				for (j = 0; j < 3; j++) {
+					*par->cmap_data = 0;
+					mach_eieio();
+				}
+				break;
+			case cmap_M3A:
+				/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
+				out_le32((unsigned *) (par->cmap_adr +
+						       0x58),
+					 in_le32((unsigned *) (par->
+							       cmap_adr +
+							       0x58)) &
+					 ~0x20);
+			case cmap_r128:
+				/* Set palette index & data */
+				out_8(par->cmap_adr + 0xb0, i);
+				out_le32((unsigned *) (par->cmap_adr +
+						       0xb4), 0);
+				break;
+			case cmap_M3B:
+				/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
+				out_le32((unsigned *) (par->cmap_adr +
+						       0x58),
+					 in_le32((unsigned *) (par->
+							       cmap_adr +
+							       0x58)) |
+					 0x20);
+				/* Set palette index & data */
+				out_8(par->cmap_adr + 0xb0, i);
+				out_le32((unsigned *) (par->cmap_adr +
+						       0xb4), 0);
+				break;
+			case cmap_radeon:
+				out_8(par->cmap_adr + 0xb0, i);
+				out_le32((unsigned *) (par->cmap_adr +
+						       0xb4), 0);
+				break;
+			case cmap_gxt2000:
+				out_le32((unsigned *) par->cmap_adr + i,
+					 0);
+				break;
+			}
+	} else
+		fb_set_cmap(&info->cmap, 1, info);
+	return 0;
 }
 
     /*
@@ -318,500 +251,311 @@
 
 int __init offb_init(void)
 {
-    struct device_node *dp;
-    unsigned int dpy;
+	struct device_node *dp;
+	unsigned int dpy;
 #ifdef CONFIG_BOOTX_TEXT
-    struct device_node *displays = find_type_devices("display");
-    struct device_node *macos_display = NULL;
+	struct device_node *displays = find_type_devices("display");
+	struct device_node *macos_display = NULL;
 
-    /* If we're booted from BootX... */
-    if (prom_num_displays == 0 && boot_infos != 0) {
-	unsigned long addr = (unsigned long) boot_infos->dispDeviceBase;
-	/* find the device node corresponding to the macos display */
-	for (dp = displays; dp != NULL; dp = dp->next) {
-	    int i;
-	    /*
-	     * Grrr...  It looks like the MacOS ATI driver
-	     * munges the assigned-addresses property (but
-	     * the AAPL,address value is OK).
-	     */
-	    if (strncmp(dp->name, "ATY,", 4) == 0 && dp->n_addrs == 1) {
-		unsigned int *ap = (unsigned int *)
-		    get_property(dp, "AAPL,address", NULL);
-		if (ap != NULL) {
-		    dp->addrs[0].address = *ap;
-		    dp->addrs[0].size = 0x01000000;
+	/* If we're booted from BootX... */
+	if (prom_num_displays == 0 && boot_infos != 0) {
+		unsigned long addr =
+		    (unsigned long) boot_infos->dispDeviceBase;
+		/* find the device node corresponding to the macos display */
+		for (dp = displays; dp != NULL; dp = dp->next) {
+			int i;
+			/*
+			 * Grrr...  It looks like the MacOS ATI driver
+			 * munges the assigned-addresses property (but
+			 * the AAPL,address value is OK).
+			 */
+			if (strncmp(dp->name, "ATY,", 4) == 0
+			    && dp->n_addrs == 1) {
+				unsigned int *ap =
+				    (unsigned int *) get_property(dp,
+								  "AAPL,address",
+								  NULL);
+				if (ap != NULL) {
+					dp->addrs[0].address = *ap;
+					dp->addrs[0].size = 0x01000000;
+				}
+			}
+
+			/*
+			 * The LTPro on the Lombard powerbook has no addresses
+			 * on the display nodes, they are on their parent.
+			 */
+			if (dp->n_addrs == 0
+			    && device_is_compatible(dp, "ATY,264LTPro")) {
+				int na;
+				unsigned int *ap = (unsigned int *)
+				    get_property(dp, "AAPL,address", &na);
+				if (ap != 0)
+					for (na /= sizeof(unsigned int);
+					     na > 0; --na, ++ap)
+						if (*ap <= addr
+						    && addr <
+						    *ap + 0x1000000)
+							goto foundit;
+			}
+
+			/*
+			 * See if the display address is in one of the address
+			 * ranges for this display.
+			 */
+			for (i = 0; i < dp->n_addrs; ++i) {
+				if (dp->addrs[i].address <= addr
+				    && addr <
+				    dp->addrs[i].address +
+				    dp->addrs[i].size)
+					break;
+			}
+			if (i < dp->n_addrs) {
+			      foundit:
+				printk(KERN_INFO "MacOS display is %s\n",
+				       dp->full_name);
+				macos_display = dp;
+				break;
+			}
 		}
-	    }
 
-	    /*
-	     * The LTPro on the Lombard powerbook has no addresses
-	     * on the display nodes, they are on their parent.
-	     */
-	    if (dp->n_addrs == 0 && device_is_compatible(dp, "ATY,264LTPro")) {
-		int na;
-		unsigned int *ap = (unsigned int *)
-		    get_property(dp, "AAPL,address", &na);
-		if (ap != 0)
-		    for (na /= sizeof(unsigned int); na > 0; --na, ++ap)
-			if (*ap <= addr && addr < *ap + 0x1000000)
-			    goto foundit;
-	    }
-
-	    /*
-	     * See if the display address is in one of the address
-	     * ranges for this display.
-	     */
-	    for (i = 0; i < dp->n_addrs; ++i) {
-		if (dp->addrs[i].address <= addr
-		    && addr < dp->addrs[i].address + dp->addrs[i].size)
-		    break;
-	    }
-	    if (i < dp->n_addrs) {
-	    foundit:
-		printk(KERN_INFO "MacOS display is %s\n", dp->full_name);
-		macos_display = dp;
-		break;
-	    }
+		/* initialize it */
+		offb_init_fb(macos_display ? macos_display->
+			     name : "MacOS display",
+			     macos_display ? macos_display->
+			     full_name : "MacOS display",
+			     boot_infos->dispDeviceRect[2],
+			     boot_infos->dispDeviceRect[3],
+			     boot_infos->dispDeviceDepth,
+			     boot_infos->dispDeviceRowBytes, addr, NULL);
 	}
-
-	/* initialize it */
-	offb_init_fb(macos_display? macos_display->name: "MacOS display",
-		     macos_display? macos_display->full_name: "MacOS display",
-		     boot_infos->dispDeviceRect[2],
-		     boot_infos->dispDeviceRect[3],
-		     boot_infos->dispDeviceDepth,
-		     boot_infos->dispDeviceRowBytes, addr, NULL);
-    }
 #endif
 
-    for (dpy = 0; dpy < prom_num_displays; dpy++) {
-	if ((dp = find_path_device(prom_display_paths[dpy])))
-	    offb_init_nodriver(dp);
-    }
-    return 0;
+	for (dpy = 0; dpy < prom_num_displays; dpy++) {
+		if ((dp = find_path_device(prom_display_paths[dpy])))
+			offb_init_nodriver(dp);
+	}
+	return 0;
 }
 
 
 static void __init offb_init_nodriver(struct device_node *dp)
 {
-    int *pp, i;
-    unsigned int len;
-    int width = 640, height = 480, depth = 8, pitch;
-    unsigned *up, address;
-
-    if ((pp = (int *)get_property(dp, "depth", &len)) != NULL
-	&& len == sizeof(int))
-	depth = *pp;
-    if ((pp = (int *)get_property(dp, "width", &len)) != NULL
-	&& len == sizeof(int))
-	width = *pp;
-    if ((pp = (int *)get_property(dp, "height", &len)) != NULL
-	&& len == sizeof(int))
-	height = *pp;
-    if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL
-	&& len == sizeof(int)) {
-	pitch = *pp;
-	if (pitch == 1)
-	    pitch = 0x1000;
-    } else
-	pitch = width;
-    if ((up = (unsigned *)get_property(dp, "address", &len)) != NULL
-	&& len == sizeof(unsigned))
-	address = (u_long)*up;
-    else {
-	for (i = 0; i < dp->n_addrs; ++i)
-	    if (dp->addrs[i].size >= pitch*height*depth/8)
-		break;
-	if (i >= dp->n_addrs) {
-	    printk(KERN_ERR "no framebuffer address found for %s\n", dp->full_name);
-	    return;
-	}
-
-	address = (u_long)dp->addrs[i].address;
+	int *pp, i;
+	unsigned int len;
+	int width = 640, height = 480, depth = 8, pitch;
+	unsigned *up, address;
+
+	if ((pp = (int *) get_property(dp, "depth", &len)) != NULL
+	    && len == sizeof(int))
+		depth = *pp;
+	if ((pp = (int *) get_property(dp, "width", &len)) != NULL
+	    && len == sizeof(int))
+		width = *pp;
+	if ((pp = (int *) get_property(dp, "height", &len)) != NULL
+	    && len == sizeof(int))
+		height = *pp;
+	if ((pp = (int *) get_property(dp, "linebytes", &len)) != NULL
+	    && len == sizeof(int)) {
+		pitch = *pp;
+		if (pitch == 1)
+			pitch = 0x1000;
+	} else
+		pitch = width;
+	if ((up = (unsigned *) get_property(dp, "address", &len)) != NULL
+	    && len == sizeof(unsigned))
+		address = (u_long) * up;
+	else {
+		for (i = 0; i < dp->n_addrs; ++i)
+			if (dp->addrs[i].size >=
+			    pitch * height * depth / 8)
+				break;
+		if (i >= dp->n_addrs) {
+			printk(KERN_ERR
+			       "no framebuffer address found for %s\n",
+			       dp->full_name);
+			return;
+		}
 
-	/* kludge for valkyrie */
-	if (strcmp(dp->name, "valkyrie") == 0) 
-	    address += 0x1000;
-    }
-    offb_init_fb(dp->name, dp->full_name, width, height, depth,
-		 pitch, address, dp);
-    
-}
+		address = (u_long) dp->addrs[i].address;
 
-static void __init offb_init_fb(const char *name, const char *full_name,
-				    int width, int height, int depth,
-				    int pitch, unsigned long address,
-				    struct device_node *dp)
-{
-    int i;
-    struct fb_fix_screeninfo *fix;
-    struct fb_var_screeninfo *var;
-    struct display *disp;
-    struct fb_info_offb *info;
-    unsigned long res_start = address;
-    unsigned long res_size = pitch*height*depth/8;
-
-    if (!request_mem_region(res_start, res_size, "offb"))
-	return;
-
-    printk(KERN_INFO "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n",
-	   width, height, name, address, depth, pitch);
-    if (depth != 8 && depth != 16 && depth != 32) {
-	printk(KERN_ERR "%s: can't use depth = %d\n", full_name, depth);
-	release_mem_region(res_start, res_size);
-	return;
-    }
-
-    info = kmalloc(sizeof(struct fb_info_offb), GFP_ATOMIC);
-    if (info == 0) {
-	release_mem_region(res_start, res_size);
-	return;
-    }
-    memset(info, 0, sizeof(*info));
-
-    fix = &info->fix;
-    var = &info->var;
-    disp = &info->disp;
-
-    strcpy(fix->id, "OFfb ");
-    strncat(fix->id, name, sizeof(fix->id));
-    fix->id[sizeof(fix->id)-1] = '\0';
-
-    var->xres = var->xres_virtual = width;
-    var->yres = var->yres_virtual = height;
-    fix->line_length = pitch;
-
-    fix->smem_start = address;
-    fix->smem_len = pitch * height;
-    fix->type = FB_TYPE_PACKED_PIXELS;
-    fix->type_aux = 0;
-
-    info->cmap_type = cmap_unknown;
-    if (depth == 8)
-    {
-    	/* XXX kludge for ati */
-	if (dp && !strncmp(name, "ATY,Rage128", 11)) {
-		unsigned long regbase = dp->addrs[2].address;
-		info->cmap_adr = ioremap(regbase, 0x1FFF);
-		info->cmap_type = cmap_r128;
-	} else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
-		|| !strncmp(name, "ATY,RageM3p12A", 14))) {
-		unsigned long regbase = dp->parent->addrs[2].address;
-		info->cmap_adr = ioremap(regbase, 0x1FFF);
-		info->cmap_type = cmap_M3A;
-	} else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
-		unsigned long regbase = dp->parent->addrs[2].address;
-		info->cmap_adr = ioremap(regbase, 0x1FFF);
-		info->cmap_type = cmap_M3B;
-	} else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
-		unsigned long regbase = dp->addrs[1].address;
-		info->cmap_adr = ioremap(regbase, 0x1FFF);
-		info->cmap_type = cmap_radeon;
-	} else if (!strncmp(name, "ATY,", 4)) {
-		unsigned long base = address & 0xff000000UL;
-		info->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
-		info->cmap_data = info->cmap_adr + 1;
-		info->cmap_type = cmap_m64;
-	} else if (device_is_compatible(dp, "pci1014,b7")) {
-		unsigned long regbase = dp->addrs[0].address;
-		info->cmap_adr = ioremap(regbase + 0x6000, 0x1000);
-		info->cmap_type = cmap_gxt2000;
-	}
-        fix->visual = info->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
-				     : FB_VISUAL_STATIC_PSEUDOCOLOR;
-    }
-    else
-	fix->visual = /*info->cmap_adr ? FB_VISUAL_DIRECTCOLOR
-				     : */FB_VISUAL_TRUECOLOR;
-
-    var->xoffset = var->yoffset = 0;
-    var->bits_per_pixel = depth;
-    switch (depth) {
-	case 8:
-	    var->bits_per_pixel = 8;
-	    var->red.offset = 0;
-	    var->red.length = 8;
-	    var->green.offset = 0;
-	    var->green.length = 8;
-	    var->blue.offset = 0;
-	    var->blue.length = 8;
-	    var->transp.offset = 0;
-	    var->transp.length = 0;
-	    break;
-	case 16:	/* RGB 555 */
-	    var->bits_per_pixel = 16;
-	    var->red.offset = 10;
-	    var->red.length = 5;
-	    var->green.offset = 5;
-	    var->green.length = 5;
-	    var->blue.offset = 0;
-	    var->blue.length = 5;
-	    var->transp.offset = 0;
-	    var->transp.length = 0;
-	    break;
-	case 32:	/* RGB 888 */
-	    var->bits_per_pixel = 32;
-	    var->red.offset = 16;
-	    var->red.length = 8;
-	    var->green.offset = 8;
-	    var->green.length = 8;
-	    var->blue.offset = 0;
-	    var->blue.length = 8;
-	    var->transp.offset = 24;
-	    var->transp.length = 8;
-	    break;
-    }
-    var->red.msb_right = var->green.msb_right = var->blue.msb_right = var->transp.msb_right = 0;
-    var->grayscale = 0;
-    var->nonstd = 0;
-    var->activate = 0;
-    var->height = var->width = -1;
-    var->pixclock = 10000;
-    var->left_margin = var->right_margin = 16;
-    var->upper_margin = var->lower_margin = 16;
-    var->hsync_len = var->vsync_len = 8;
-    var->sync = 0;
-    var->vmode = FB_VMODE_NONINTERLACED;
-
-    disp->var = *var;
-    disp->cmap.start = 0;
-    disp->cmap.len = 0;
-    disp->cmap.red = NULL;
-    disp->cmap.green = NULL;
-    disp->cmap.blue = NULL;
-    disp->cmap.transp = NULL;
-    disp->visual = fix->visual;
-    disp->type = fix->type;
-    disp->type_aux = fix->type_aux;
-    disp->ypanstep = 0;
-    disp->ywrapstep = 0;
-    disp->line_length = fix->line_length;
-    disp->can_soft_blank = info->cmap_adr ? 1 : 0;
-    disp->inverse = 0;
-    switch (depth) {
-#ifdef FBCON_HAS_CFB8
-        case 8:
-            disp->dispsw = &fbcon_cfb8;
-            break;
-#endif
-#ifdef FBCON_HAS_CFB16
-        case 16:
-            disp->dispsw = &fbcon_cfb16;
-            disp->dispsw_data = info->fbcon_cmap.cfb16;
-            for (i = 0; i < 16; i++)
-            	if (fix->visual == FB_VISUAL_TRUECOLOR)
-		    info->fbcon_cmap.cfb16[i] =
-			    (((default_blu[i] >> 3) & 0x1f) << 10) |
-			    (((default_grn[i] >> 3) & 0x1f) << 5) |
-			    ((default_red[i] >> 3) & 0x1f);
-		else
-		    info->fbcon_cmap.cfb16[i] =
-			    (i << 10) | (i << 5) | i;
-            break;
-#endif
-#ifdef FBCON_HAS_CFB32
-        case 32:
-            disp->dispsw = &fbcon_cfb32;
-            disp->dispsw_data = info->fbcon_cmap.cfb32;
-            for (i = 0; i < 16; i++)
-            	if (fix->visual == FB_VISUAL_TRUECOLOR)
-		    info->fbcon_cmap.cfb32[i] =
-			(default_blu[i] << 16) |
-			(default_grn[i] << 8) |
-			default_red[i];
-		else
-		    info->fbcon_cmap.cfb32[i] =
-			    (i << 16) | (i << 8) | i;
-            break;
-#endif
-        default:
-            disp->dispsw = &fbcon_dummy;
-    }
-
-    disp->scrollmode = SCROLL_YREDRAW;
-
-    strcpy(info->info.modename, "OFfb ");
-    strncat(info->info.modename, full_name, sizeof(info->info.modename));
-    info->info.node = NODEV;
-    info->info.fbops = &offb_ops;
-    info->info.screen_base = ioremap(address, fix->smem_len);
-    info->info.disp = disp;
-    info->info.currcon = -1;	
-    info->info.fontname[0] = '\0';
-    info->info.changevar = NULL;
-    info->info.switch_con = &offbcon_switch;
-    info->info.updatevar = &offbcon_updatevar;
-    info->info.flags = FBINFO_FLAG_DEFAULT;
-
-    for (i = 0; i < 16; i++) {
-	int j = color_table[i];
-	info->palette[i].red = default_red[j];
-	info->palette[i].green = default_grn[j];
-	info->palette[i].blue = default_blu[j];
-    }
-    offb_set_var(var, -1, &info->info);
-
-    if (register_framebuffer(&info->info) < 0) {
-	kfree(info);
-	release_mem_region(res_start, res_size);
-	return;
-    }
-
-    printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
-	   GET_FB_IDX(info->info.node), full_name);
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-    if (!console_fb_info) {
-	display_info.height = var->yres;
-	display_info.width = var->xres;
-	display_info.depth = depth;
-	display_info.pitch = fix->line_length;
-	display_info.mode = 0;
-	strncpy(display_info.name, name, sizeof(display_info.name));
-	display_info.fb_address = address;
-	display_info.cmap_adr_address = 0;
-	display_info.cmap_data_address = 0;
-	display_info.disp_reg_address = 0;
-	/* XXX kludge for ati */
-	if (info->cmap_type == cmap_m64) {
-	    unsigned long base = address & 0xff000000UL;
-	    display_info.disp_reg_address = base + 0x7ffc00;
-	    display_info.cmap_adr_address = base + 0x7ffcc0;
-	    display_info.cmap_data_address = base + 0x7ffcc1;
+		/* kludge for valkyrie */
+		if (strcmp(dp->name, "valkyrie") == 0)
+			address += 0x1000;
 	}
-	console_fb_info = &info->info;
-    }
-#endif /* CONFIG_FB_COMPAT_XPMAC) */
-}
-
-static int offbcon_switch(int con, struct fb_info *info)
-{
-    struct fb_info_offb *info2 = (struct fb_info_offb *)info;	
+	offb_init_fb(dp->name, dp->full_name, width, height, depth,
+		     pitch, address, dp);
 
-    /* Do we have to save the colormap? */
-    if (fb_display[info->currcon].cmap.len && !info2->blanked)
-	fb_get_cmap(&fb_display[info->currcon].cmap, 1, offb_getcolreg, info);
-
-    info->currcon = con;
-    /* Install new colormap */
-    do_install_cmap(con, info);
-    return 0;
 }
 
-    /*
-     *  Update the `var' structure (called by fbcon.c)
-     */
-
-static int offbcon_updatevar(int con, struct fb_info *info)
-{
-    /* Nothing */
-    return 0;
-}
-
-    /*
-     *  Read a single color register and split it into
-     *  colors/transparent. Return != 0 for invalid regno.
-     */
-
-static int offb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			  u_int *transp, struct fb_info *info)
-{
-    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
-
-    if (!info2->cmap_adr || regno > 255)
-	return 1;
-    
-    *red = (info2->palette[regno].red<<8) | info2->palette[regno].red;
-    *green = (info2->palette[regno].green<<8) | info2->palette[regno].green;
-    *blue = (info2->palette[regno].blue<<8) | info2->palette[regno].blue;
-    *transp = 0;
-    return 0;
-}
+static void __init offb_init_fb(const char *name, const char *full_name,
+				int width, int height, int depth,
+				int pitch, unsigned long address,
+				struct device_node *dp)
+{
+	unsigned long res_size = pitch * height * depth / 8;
+	struct offb_par *par = &default_par;
+	unsigned long res_start = address;
+	struct fb_fix_screeninfo *fix;
+	struct fb_var_screeninfo *var;
+	struct fb_info *info;
+	int i;
+
+	if (!request_mem_region(res_start, res_size, "offb"))
+		return;
+
+	printk(KERN_INFO
+	       "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n",
+	       width, height, name, address, depth, pitch);
+	if (depth != 8 && depth != 16 && depth != 32) {
+		printk(KERN_ERR "%s: can't use depth = %d\n", full_name,
+		       depth);
+		release_mem_region(res_start, res_size);
+		return;
+	}
 
+	info =
+	    kmalloc(sizeof(struct fb_info) + sizeof(struct display) +
+		    sizeof(u32) * 17, GFP_ATOMIC);
+	if (info == 0) {
+		release_mem_region(res_start, res_size);
+		return;
+	}
+	memset(info, 0, sizeof(*info));
 
-    /*
-     *  Set a single color register. The values supplied are already
-     *  rounded down to the hardware's capabilities (according to the
-     *  entries in the var structure). Return != 0 for invalid regno.
-     */
+	fix = &info->fix;
+	var = &info->var;
 
-static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			 u_int transp, struct fb_info *info)
-{
-    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
-	
-    if (!info2->cmap_adr || regno > 255)
-	return 1;
-
-    red >>= 8;
-    green >>= 8;
-    blue >>= 8;
-
-    info2->palette[regno].red = red;
-    info2->palette[regno].green = green;
-    info2->palette[regno].blue = blue;
-
-    switch(info2->cmap_type) {
-    case cmap_m64:
-        *info2->cmap_adr = regno;
-	mach_eieio();
-	*info2->cmap_data = red;
-	mach_eieio();
-	*info2->cmap_data = green;
-	mach_eieio();
-	*info2->cmap_data = blue;
-	mach_eieio();
-	break;
-    case cmap_M3A:
-	/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
-	out_le32((unsigned *)(info2->cmap_adr + 0x58),
-		in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
-    case cmap_r128:
-	/* Set palette index & data */
-	out_8(info2->cmap_adr + 0xb0, regno);
-	out_le32((unsigned *)(info2->cmap_adr + 0xb4),
-		(red << 16 | green << 8 | blue));
-	break;
-    case cmap_M3B:
-        /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
-    	out_le32((unsigned *)(info2->cmap_adr + 0x58),
-    		in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
-    	/* Set palette index & data */
-    	out_8(info2->cmap_adr + 0xb0, regno);
-  	out_le32((unsigned *)(info2->cmap_adr + 0xb4),
-    		(red << 16 | green << 8 | blue));
-    	break;
-    case cmap_radeon:
-	/* Set palette index & data (could be smarter) */
-	out_8(info2->cmap_adr + 0xb0, regno);
-  	out_le32((unsigned *)(info2->cmap_adr + 0xb4),
-    		(red << 16 | green << 8 | blue));
-	break;
-    case cmap_gxt2000:
-	out_le32((unsigned *)info2->cmap_adr + regno,
-		(red << 16 | green << 8 | blue));
-	break;
-    }
-
-    if (regno < 16)
-	switch (info2->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB16
-	    case 16:
-		info2->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | regno;
+	strcpy(fix->id, "OFfb ");
+	strncat(fix->id, name, sizeof(fix->id));
+	fix->id[sizeof(fix->id) - 1] = '\0';
+
+	var->xres = var->xres_virtual = width;
+	var->yres = var->yres_virtual = height;
+	fix->line_length = pitch;
+
+	fix->smem_start = address;
+	fix->smem_len = pitch * height;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+
+	par->cmap_type = cmap_unknown;
+	if (depth == 8) {
+		/* XXX kludge for ati */
+		if (dp && !strncmp(name, "ATY,Rage128", 11)) {
+			unsigned long regbase = dp->addrs[2].address;
+			par->cmap_adr = ioremap(regbase, 0x1FFF);
+			par->cmap_type = cmap_r128;
+		} else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
+				  || !strncmp(name, "ATY,RageM3p12A", 14))) {
+			unsigned long regbase =
+			    dp->parent->addrs[2].address;
+			par->cmap_adr = ioremap(regbase, 0x1FFF);
+			par->cmap_type = cmap_M3A;
+		} else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
+			unsigned long regbase =
+			    dp->parent->addrs[2].address;
+			par->cmap_adr = ioremap(regbase, 0x1FFF);
+			par->cmap_type = cmap_M3B;
+		} else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
+			unsigned long regbase = dp->addrs[1].address;
+			par->cmap_adr = ioremap(regbase, 0x1FFF);
+			par->cmap_type = cmap_radeon;
+		} else if (!strncmp(name, "ATY,", 4)) {
+			unsigned long base = address & 0xff000000UL;
+			par->cmap_adr =
+			    ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
+			par->cmap_data = info->cmap_adr + 1;
+			par->cmap_type = cmap_m64;
+		} else if (device_is_compatible(dp, "pci1014,b7")) {
+			unsigned long regbase = dp->addrs[0].address;
+			par->cmap_adr = ioremap(regbase + 0x6000, 0x1000);
+			par->cmap_type = cmap_gxt2000;
+		}
+		fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
+		    : FB_VISUAL_STATIC_PSEUDOCOLOR;
+	} else
+		fix->visual =	/* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR
+				   : */ FB_VISUAL_TRUECOLOR;
+
+	var->xoffset = var->yoffset = 0;
+	var->bits_per_pixel = depth;
+	switch (depth) {
+	case 8:
+		var->bits_per_pixel = 8;
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	    case 32:
-	    {
-		int i = (regno << 8) | regno;
-		info2->fbcon_cmap.cfb32[regno] = (i << 16) | i;
+	case 16:		/* RGB 555 */
+		var->bits_per_pixel = 16;
+		var->red.offset = 10;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 5;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = 0;
+		var->transp.length = 0;
 		break;
-	    }
-#endif
-       }
+	case 32:		/* RGB 888 */
+		var->bits_per_pixel = 32;
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		break;
+	}
+	var->red.msb_right = var->green.msb_right = var->blue.msb_right =
+	    var->transp.msb_right = 0;
+	var->grayscale = 0;
+	var->nonstd = 0;
+	var->activate = 0;
+	var->height = var->width = -1;
+	var->pixclock = 10000;
+	var->left_margin = var->right_margin = 16;
+	var->upper_margin = var->lower_margin = 16;
+	var->hsync_len = var->vsync_len = 8;
+	var->sync = 0;
+	var->vmode = FB_VMODE_NONINTERLACED;
+
+	strcpy(fix->id, "OFfb ");
+	strncat(fix->id, full_name, sizeof(fix->id));
+	strcpy(info->modename, fix->id);
+	info->node = NODEV;
+	info->fbops = &offb_ops;
+	info->screen_base = ioremap(address, fix->smem_len);
+	info->par = par;
+	info->disp = (struct display *) (info + 1);
+	info->pseudo_palette = (void *) (info->disp + 1);
+	info->currcon = -1;
+	info->fontname[0] = '\0';
+	info->changevar = NULL;
+	info->switch_con = gen_switch;
+	info->updatevar = gen_update_var;
+	info->flags = FBINFO_FLAG_DEFAULT;
+
+	fb_alloc_cmap(&info->cmap, 256, 0);
+
+	gen_set_disp(-1, info);
+
+	if (register_framebuffer(info) < 0) {
+		kfree(info);
+		release_mem_region(res_start, res_size);
+		return;
+	}
 
-    return 0;
+	printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
+	       GET_FB_IDX(info->info.node), full_name);
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
--- a/drivers/video/platinumfb.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/platinumfb.c	Wed Jul 24 14:03:37 2002
@@ -33,9 +33,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/nvram.h>
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-#endif
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pgtable.h>
@@ -510,24 +507,6 @@
 	set_platinum_clock(info);
 
 	out_be32(&platinum_regs->reg[24].r, 0);	/* turn display on */
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-	if (console_fb_info == &info->fb_info) {
-		display_info.height = par->yres;
-		display_info.width = par->xres;
-		display_info.depth = ( (cmode == CMODE_32) ? 32 :
-				      ((cmode == CMODE_16) ? 16 : 8));
-		display_info.pitch = vmode_attrs[vmode-1].hres * (1<<cmode) + 0x20;
-		display_info.mode = vmode;
-		strncpy(display_info.name, "platinum",
-			sizeof(display_info.name));
-		display_info.fb_address = info->frame_buffer_phys + init->fb_offset + 0x20;
-		display_info.cmap_adr_address = info->cmap_regs_phys;
-		display_info.cmap_data_address = info->cmap_regs_phys + 0x30;
-		display_info.disp_reg_address = info->platinum_regs_phys;
-		
-	}
-#endif /* CONFIG_FB_COMPAT_XPMAC */
 }
 
 
@@ -705,11 +684,6 @@
 		kfree(info);
 		return;
 	}
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-	if (!console_fb_info)
-		console_fb_info = &info->fb_info;
-#endif
 }
 
 /*
diff -Nru a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
--- a/drivers/video/pm2fb.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/video/pm2fb.c	Wed Jul 24 14:03:39 2002
@@ -57,7 +57,7 @@
 #error	"The endianness of the target host has not been defined."
 #endif
 
-#if defined(__BIG_ENDIAN) && !defined(__sparc__)
+#if defined(__BIG_ENDIAN) && !defined(__sparc__) && (!defined(CONFIG_PPC) || defined(CONFIG_FB_PM2_CVPPC))
 #define PM2FB_BE_APERTURE
 #endif
 
diff -Nru a/drivers/video/q40fb.c b/drivers/video/q40fb.c
--- a/drivers/video/q40fb.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/q40fb.c	Wed Jul 24 14:03:37 2002
@@ -42,7 +42,7 @@
 	type:		FB_TYPE_PACKED_PIXELS,
 	visual:		FB_VISUAL_TRUECOLOR,
 	line_length:	1024*2,
-	accel_flags:	FB_ACCEL_NONE,
+	accel:		FB_ACCEL_NONE,
 };
 
 static struct fb_var_screeninfo q40fb_var __initdata = {
@@ -95,9 +95,9 @@
     blue>>=10;
 
     if (regno < 16) {
-	info->pseudo_palette[regno] = ((red & 31) <<6) |
-	                              ((green & 31) << 11) |
-	                         	(blue & 63);
+	((u16 *)info->pseudo_palette)[regno] = ((red & 31) <<6) |
+					       ((green & 31) << 11) |
+					       (blue & 63);
     }
     return 0;
 }
diff -Nru a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
--- a/drivers/video/retz3fb.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/video/retz3fb.c	Wed Jul 24 14:03:39 2002
@@ -1274,8 +1274,6 @@
 static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
 			    struct fb_info *info)
 {
-	struct retz3_fb_info *zinfo = retz3info(info);
-
 	if (con == info->currcon) /* current console? */
 		return(fb_get_cmap(cmap, kspc, retz3_getcolreg, info));
 	else if (fb_display[con].cmap.len) /* non default colormap? */
@@ -1446,8 +1444,6 @@
 
 static int z3fb_switch(int con, struct fb_info *info)
 {
-	struct retz3_fb_info *zinfo = retz3info(info);
-
 	/* Do we have to save the colormap? */
 	if (fb_display[info->currcon].cmap.len)
 		fb_get_cmap(&fb_display[info->currcon].cmap, 1,
diff -Nru a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
--- a/drivers/video/sgivwfb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/sgivwfb.c	Wed Jul 24 14:03:38 2002
@@ -27,18 +27,15 @@
 #include <asm/mtrr.h>
 
 #include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb32.h>
 
 #define INCLUDE_TIMING_TABLE_DATA
 #define DBE_REG_BASE regs
-#include "sgivwfb.h"
+#include <video/sgivw.h>
 
-struct sgivwfb_par {
-  struct fb_var_screeninfo var;
-  u_long timing_num;
-  int valid;
+struct sgivw_par {
+	asregs *regs;
+	u32 cmap_fifo;
+	u_long timing_num;
 };
 
 /*
@@ -49,113 +46,109 @@
  */
 
 /* set by arch/i386/kernel/setup.c */
-u_long                sgivwfb_mem_phys;
-u_long                sgivwfb_mem_size;
+u_long sgivwfb_mem_phys;
+u_long sgivwfb_mem_size;
 
-static asregs         *regs;
 static struct fb_info fb_info;
-static struct { u_char red, green, blue, pad; } palette[256];
-static char           sgivwfb_name[16] = "SGI Vis WS FB";
-static u32            cmap_fifo;
-static int            ypan       = 0;
-static int            ywrap      = 0;
+static struct sgivw_par default_par;
+static int ypan = 0;
+static int ywrap = 0;
+
+static struct fb_fix_screeninfo sgivwfb_fix __initdata = {
+	id:		"SGI Vis WS FB",
+	type:		FB_TYPE_PACKED_PIXELS,
+        visual:		FB_VISUAL_PSEUDOCOLOR,
+	mmio_start:	DBE_REG_PHYS,
+	mmio_len:	DBE_REG_SIZE,
+        accel_flags:	FB_ACCEL_NONE
+};
+
+static struct fb_var_screeninfo sgivwfb_var __initdata = {
+        /* 640x480, 8 bpp */
+        xres:		640,
+	yres:		480,
+	xres_virtual:	640,
+	yres_virtual:	480,
+	bits_per_pixel:	8,
+        red:		{0, 8, 0},
+	green:		{0, 8, 0},
+	blue:		{0, 8, 0},
+        height:		-1,
+	width:		-1,
+	pixclock:	20000,
+	left_margin:	64,
+	right_margin:	64,
+	upper_margin:	32,
+	lower_margin:	32,
+	hsync_len:	64,
+	vsync_len:	2,
+        vmode:		FB_VMODE_NONINTERLACED
+};
 
 /* console related variables */
 static struct display disp;
 
-static union {
-#ifdef FBCON_HAS_CFB16
-  u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-  u32 cfb32[16];
-#endif
-} fbcon_cmap;
-
-static struct sgivwfb_par par_current = {
-  {                             /* var (screeninfo) */
-    /* 640x480, 8 bpp */
-    640, 480, 640, 480, 0, 0, 8, 0,
-    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-    0, 0, -1, -1, 0, 20000, 64, 64, 32, 32, 64, 2,
-    0, FB_VMODE_NONINTERLACED
-  },
-  0,                            /* timing_num */
-  0				/* par not activated */
-};
-
 /*
  *  Interface used by the world
  */
-int sgivwfb_setup(char*);
+int sgivwfb_init(void);
+int sgivwfb_setup(char *);
 
-static int sgivwfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			   struct fb_info *info);
-static int sgivwfb_get_var(struct fb_var_screeninfo *var, int con,
-			   struct fb_info *info);
-static int sgivwfb_set_var(struct fb_var_screeninfo *var, int con,
-			   struct fb_info *info);
-static int sgivwfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			    struct fb_info *info);
-static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			     u_int transp, struct fb_info *info);
+static int sgivwfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
+static int sgivwfb_set_par(struct fb_info *info);
+static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
+			     u_int blue, u_int transp,
+			     struct fb_info *info);
 static int sgivwfb_mmap(struct fb_info *info, struct file *file,
-                        struct vm_area_struct *vma);
+			struct vm_area_struct *vma);
 
 static struct fb_ops sgivwfb_ops = {
 	owner:		THIS_MODULE,
-	fb_get_fix:	sgivwfb_get_fix,
-	fb_get_var:	sgivwfb_get_var,
-	fb_set_var:	sgivwfb_set_var,
-	fb_get_cmap:	sgivwfb_get_cmap,
+	fb_get_fix:	gen_get_fix,
+	fb_get_var:	gen_get_var,
+	fb_set_var:	gen_set_var,
+	fb_get_cmap:	gen_get_cmap,
 	fb_set_cmap:	gen_set_cmap,
+	fb_check_var:	sgivwfb_check_var,
+	fb_set_par:	sgivwfb_set_par,
 	fb_setcolreg:	sgivwfb_setcolreg,
+	fb_fillrect:	cfb_fillrect,
+	fb_copyarea:	cfb_copyarea,
+	fb_imageblit:	cfb_imageblit,
 	fb_mmap:	sgivwfb_mmap,
 };
 
 /*
- *  Interface to the low level console driver
- */
-int sgivwfb_init(void);
-static int sgivwfbcon_switch(int con, struct fb_info *info);
-static int sgivwfbcon_updatevar(int con, struct fb_info *info);
-
-/*
  *  Internal routines
  */
 static u_long get_line_length(int xres_virtual, int bpp);
 static unsigned long bytes_per_pixel(int bpp);
-static void activate_par(struct sgivwfb_par *par);
-static void sgivwfb_encode_fix(struct fb_fix_screeninfo *fix,
-			       struct fb_var_screeninfo *var);
-static int sgivwfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			     u_int *transp, struct fb_info *info);
 
 static unsigned long get_line_length(int xres_virtual, int bpp)
 {
-  return(xres_virtual * bytes_per_pixel(bpp));
+	return (xres_virtual * bytes_per_pixel(bpp));
 }
 
 static unsigned long bytes_per_pixel(int bpp)
 {
-  unsigned long length;
+	unsigned long length;
 
-  switch (bpp) {
-  case 8:
-    length = 1;
-    break;
-  case 16:
-    length = 2;
-    break;
-  case 32:
-    length = 4;
-    break;
-  default:
-    printk(KERN_INFO "sgivwfb: unsupported bpp=%d\n", bpp);
-    length = 0;
-    break;
-  }
-  return(length);
+	switch (bpp) {
+	case 8:
+		length = 1;
+		break;
+	case 16:
+		length = 2;
+		break;
+	case 32:
+		length = 4;
+		break;
+	default:
+		printk(KERN_INFO "sgivwfb: unsupported bpp=%d\n", bpp);
+		length = 0;
+		break;
+	}
+	return (length);
 }
 
 /*
@@ -168,360 +161,476 @@
 
 static void dbe_TurnOffDma(void)
 {
-  int i;
-  unsigned int readVal;
+	int i;
+	unsigned int readVal;
 
-  // Check to see if things are already turned off:
-  // 1) Check to see if dbe is not using the internal dotclock.
-  // 2) Check to see if the xy counter in dbe is already off.
-
-  DBE_GETREG(ctrlstat, readVal);
-  if (GET_DBE_FIELD(CTRLSTAT, PCLKSEL, readVal) < 2)
-    return;
-
-  DBE_GETREG(vt_xy, readVal);
-  if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1)
-    return;
-
-  // Otherwise, turn off dbe
-
-  DBE_GETREG(ovr_control, readVal);
-  SET_DBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, readVal, 0);
-  DBE_SETREG(ovr_control, readVal);
-  udelay(1000);
-  DBE_GETREG(frm_control, readVal);
-  SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, readVal, 0);
-  DBE_SETREG(frm_control, readVal);
-  udelay(1000);
-  DBE_GETREG(did_control, readVal);
-  SET_DBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, readVal, 0);
-  DBE_SETREG(did_control, readVal);
-  udelay(1000);
-
-  // XXX HACK:
-  //
-  //    This was necessary for GBE--we had to wait through two
-  //    vertical retrace periods before the pixel DMA was
-  //    turned off for sure.  I've left this in for now, in
-  //    case dbe needs it.
-
-  for (i = 0; i < 10000; i++)
-    {
-      DBE_GETREG(frm_inhwctrl, readVal);
-      if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) == 0)
-        udelay(10);
-      else
-        {
-          DBE_GETREG(ovr_inhwctrl, readVal);
-          if (GET_DBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0)
-            udelay(10);
-          else
-            {
-              DBE_GETREG(did_inhwctrl, readVal);
-              if (GET_DBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, readVal) == 0)
-                udelay(10);
-              else
-                break;
-            }
-        }
-    }
+	// Check to see if things are already turned off:
+	// 1) Check to see if dbe is not using the internal dotclock.
+	// 2) Check to see if the xy counter in dbe is already off.
+
+	DBE_GETREG(ctrlstat, readVal);
+	if (GET_DBE_FIELD(CTRLSTAT, PCLKSEL, readVal) < 2)
+		return;
+
+	DBE_GETREG(vt_xy, readVal);
+	if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1)
+		return;
+
+	// Otherwise, turn off dbe
+
+	DBE_GETREG(ovr_control, readVal);
+	SET_DBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, readVal, 0);
+	DBE_SETREG(ovr_control, readVal);
+	udelay(1000);
+	DBE_GETREG(frm_control, readVal);
+	SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, readVal, 0);
+	DBE_SETREG(frm_control, readVal);
+	udelay(1000);
+	DBE_GETREG(did_control, readVal);
+	SET_DBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, readVal, 0);
+	DBE_SETREG(did_control, readVal);
+	udelay(1000);
+
+	// XXX HACK:
+	//
+	//    This was necessary for GBE--we had to wait through two
+	//    vertical retrace periods before the pixel DMA was
+	//    turned off for sure.  I've left this in for now, in
+	//    case dbe needs it.
+
+	for (i = 0; i < 10000; i++) {
+		DBE_GETREG(frm_inhwctrl, readVal);
+		if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) ==
+		    0)
+			udelay(10);
+		else {
+			DBE_GETREG(ovr_inhwctrl, readVal);
+			if (GET_DBE_FIELD
+			    (OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0)
+				udelay(10);
+			else {
+				DBE_GETREG(did_inhwctrl, readVal);
+				if (GET_DBE_FIELD
+				    (DID_INHWCTRL, DID_DMA_ENABLE,
+				     readVal) == 0)
+					udelay(10);
+				else
+					break;
+			}
+		}
+	}
 }
 
 /*
- *  Set the hardware according to 'par'.
+ *  Set the User Defined Part of the Display. Again if par use it to get
+ *  real video mode.
  */
-static void activate_par(struct sgivwfb_par *par)
+static int sgivwfb_check_var(struct fb_var_screeninfo *var, 
+			     struct fb_info *info)
 {
-  int i,j, htmp, temp;
-  u32 readVal, outputVal;
-  int wholeTilesX, maxPixelsPerTileX;
-  int frmWrite1, frmWrite2, frmWrite3b;
-  dbe_timing_info_t *currentTiming;    /* Current Video Timing */
-  int xpmax, ypmax;                       // Monitor resolution
-  int bytesPerPixel;                      // Bytes per pixel
-
-  currentTiming = &dbeVTimings[par->timing_num];
-  bytesPerPixel = bytes_per_pixel(par->var.bits_per_pixel);
-  xpmax = currentTiming->width;
-  ypmax = currentTiming->height;
-
-  /* dbe_InitGraphicsBase(); */
-  /* Turn on dotclock PLL */
-  DBE_SETREG(ctrlstat, 0x20000000);
-
-  dbe_TurnOffDma();
-
-  /* dbe_CalculateScreenParams(); */
-  maxPixelsPerTileX = 512/bytesPerPixel;
-  wholeTilesX = xpmax/maxPixelsPerTileX;
-  if (wholeTilesX*maxPixelsPerTileX < xpmax)
-    wholeTilesX++;
-
-  printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n",
-	 maxPixelsPerTileX, wholeTilesX);
-
-  /* dbe_InitGammaMap(); */
-  udelay(10);
-
-  for (i = 0; i < 256; i++)
-    {
-      DBE_ISETREG(gmap, i, (i << 24) | (i << 16) | (i << 8));
-    }
-
-  /* dbe_TurnOn(); */
-  DBE_GETREG(vt_xy, readVal);
-  if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1)
-    {
-      DBE_SETREG(vt_xy, 0x00000000);
-      udelay(1);
-    }
-  else
-    dbe_TurnOffDma();
-
-  /* dbe_Initdbe(); */
-  for (i = 0; i < 256; i++)
-    {
-      for (j = 0; j < 100; j++)
-        {
-          DBE_GETREG(cm_fifo, readVal);
-          if (readVal != 0x00000000)
-            break;
-          else
-            udelay(10);
-        }
-
-      // DBE_ISETREG(cmap, i, 0x00000000);
-      DBE_ISETREG(cmap, i, (i<<8)|(i<<16)|(i<<24));
-    }
-
-  /* dbe_InitFramebuffer(); */
-  frmWrite1 = 0;
-  SET_DBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, frmWrite1, wholeTilesX);
-  SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0);
-
-  switch(bytesPerPixel)
-    {
-      case 1:
-        SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, DBE_FRM_DEPTH_8);
-        break;
-      case 2:
-        SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, DBE_FRM_DEPTH_16);
-        break;
-      case 4:
-        SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, DBE_FRM_DEPTH_32);
-        break;
-    }
-
-  frmWrite2 = 0;
-  SET_DBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, frmWrite2, ypmax);
-
-  // Tell dbe about the framebuffer location and type
-  // XXX What format is the FRM_TILE_PTR??  64K aligned address?
-  frmWrite3b = 0;
-  SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b, sgivwfb_mem_phys>>9);
-  SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1);
-  SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1);
-
-  /* Initialize DIDs */
-
-  outputVal = 0;
-  switch(bytesPerPixel)
-    {
-      case 1:
-        SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8);
-        break;
-      case 2:
-        SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5);
-        break;
-      case 4:
-        SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8);
-        break;
-    }
-  SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH);
-
-  for (i = 0; i < 32; i++)
-    {
-      DBE_ISETREG(mode_regs, i, outputVal);
-    }
-
-  /* dbe_InitTiming(); */
-  DBE_SETREG(vt_intr01, 0xffffffff);
-  DBE_SETREG(vt_intr23, 0xffffffff);
-
-  DBE_GETREG(dotclock, readVal);
-  DBE_SETREG(dotclock, readVal & 0xffff);
-
-  DBE_SETREG(vt_xymax, 0x00000000);
-  outputVal = 0;
-  SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_ON, outputVal, currentTiming->vsync_start);
-  SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_OFF, outputVal, currentTiming->vsync_end);
-  DBE_SETREG(vt_vsync, outputVal);
-  outputVal = 0;
-  SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_ON, outputVal, currentTiming->hsync_start);
-  SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_OFF, outputVal, currentTiming->hsync_end);
-  DBE_SETREG(vt_hsync, outputVal);
-  outputVal = 0;
-  SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_ON, outputVal, currentTiming->vblank_start);
-  SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_OFF, outputVal, currentTiming->vblank_end);
-  DBE_SETREG(vt_vblank, outputVal);
-  outputVal = 0;
-  SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_ON, outputVal, currentTiming->hblank_start);
-  SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_OFF, outputVal, currentTiming->hblank_end-3);
-  DBE_SETREG(vt_hblank, outputVal);
-  outputVal = 0;
-  SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_ON, outputVal, currentTiming->vblank_start);
-  SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_OFF, outputVal, currentTiming->vblank_end);
-  DBE_SETREG(vt_vcmap, outputVal);
-  outputVal = 0;
-  SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_ON, outputVal, currentTiming->hblank_start);
-  SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_OFF, outputVal, currentTiming->hblank_end-3);
-  DBE_SETREG(vt_hcmap, outputVal);
-
-  outputVal = 0;
-  temp = currentTiming->vblank_start - currentTiming->vblank_end - 1;
-  if (temp > 0)
-    temp = -temp;
-
-  SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32)temp);
-  if (currentTiming->hblank_end >= 20)
-    SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
-                      currentTiming->hblank_end - 20);
-  else
-    SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
-                      currentTiming->htotal - (20 - currentTiming->hblank_end));
-  DBE_SETREG(did_start_xy, outputVal);
-
-  outputVal = 0;
-  SET_DBE_FIELD(CRS_START_XY, CRS_STARTY, outputVal, (u32)(temp+1));
-  if (currentTiming->hblank_end >= DBE_CRS_MAGIC)
-    SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
-                      currentTiming->hblank_end - DBE_CRS_MAGIC);
-  else
-    SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
-                      currentTiming->htotal - (DBE_CRS_MAGIC - currentTiming->hblank_end));
-  DBE_SETREG(crs_start_xy, outputVal);
-
-  outputVal = 0;
-  SET_DBE_FIELD(VC_START_XY, VC_STARTY, outputVal, (u32)temp);
-  SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal,
-                    currentTiming->hblank_end - 4);
-  DBE_SETREG(vc_start_xy, outputVal);
-
-  DBE_SETREG(frm_size_tile, frmWrite1);
-  DBE_SETREG(frm_size_pixel, frmWrite2);
-
-  outputVal = 0;
-  SET_DBE_FIELD(DOTCLK, M, outputVal, currentTiming->pll_m-1);
-  SET_DBE_FIELD(DOTCLK, N, outputVal, currentTiming->pll_n-1);
-  SET_DBE_FIELD(DOTCLK, P, outputVal, currentTiming->pll_p);
-  SET_DBE_FIELD(DOTCLK, RUN, outputVal, 1);
-  DBE_SETREG(dotclock, outputVal);
-
-  udelay(11*1000);
-
-  DBE_SETREG(vt_vpixen, 0xffffff);
-  DBE_SETREG(vt_hpixen, 0xffffff);
-
-  outputVal = 0;
-  SET_DBE_FIELD(VT_XYMAX, VT_MAXX, outputVal, currentTiming->htotal);
-  SET_DBE_FIELD(VT_XYMAX, VT_MAXY, outputVal, currentTiming->vtotal);
-  DBE_SETREG(vt_xymax, outputVal);
-
-  outputVal = frmWrite1;
-  SET_DBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, outputVal, 1);
-  DBE_SETREG(frm_size_tile, outputVal);
-  DBE_SETREG(frm_size_tile, frmWrite1);
-
-  outputVal = 0;
-  SET_DBE_FIELD(OVR_WIDTH_TILE, OVR_FIFO_RESET, outputVal, 1);
-  DBE_SETREG(ovr_width_tile, outputVal);
-  DBE_SETREG(ovr_width_tile, 0);
-
-  DBE_SETREG(frm_control, frmWrite3b);
-  DBE_SETREG(did_control, 0);
-
-  // Wait for dbe to take frame settings
-  for (i=0; i<100000; i++)
-    {
-      DBE_GETREG(frm_inhwctrl, readVal);
-      if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) != 0)
-        break;
-      else
-        udelay(1);
-    }
-
-  if (i==100000)
-    printk(KERN_INFO "sgivwfb: timeout waiting for frame DMA enable.\n");
-
-  outputVal = 0;
-  htmp = currentTiming->hblank_end - 19;
-  if (htmp < 0)
-    htmp += currentTiming->htotal;    /* allow blank to wrap around */
-  SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_ON, outputVal, htmp);
-  SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_OFF, outputVal,
-                    ((htmp + currentTiming->width - 2) % currentTiming->htotal));
-  DBE_SETREG(vt_hpixen, outputVal);
-
-  outputVal = 0;
-  SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_OFF, outputVal,
-                    currentTiming->vblank_start);
-  SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_ON, outputVal,
-                    currentTiming->vblank_end);
-  DBE_SETREG(vt_vpixen, outputVal);
-
-  // Turn off mouse cursor
-  regs->crs_ctl = 0;
-
-  // XXX What's this section for??
-  DBE_GETREG(ctrlstat, readVal);
-  readVal &= 0x02000000;
-
-  if (readVal != 0)
-    {
-      DBE_SETREG(ctrlstat, 0x30000000);
-    }
-}
-
-static void sgivwfb_encode_fix(struct fb_fix_screeninfo *fix,
-			       struct fb_var_screeninfo *var)
-{
-  memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-  strcpy(fix->id, sgivwfb_name);
-  fix->smem_start = sgivwfb_mem_phys;
-  fix->smem_len = sgivwfb_mem_size;
-  fix->type = FB_TYPE_PACKED_PIXELS;
-  fix->type_aux = 0;
-  switch (var->bits_per_pixel) {
-  case 8:
-    fix->visual = FB_VISUAL_PSEUDOCOLOR;
-    break;
-  default:
-    fix->visual = FB_VISUAL_TRUECOLOR;
-    break;
-  }
-  fix->ywrapstep = ywrap;
-  fix->xpanstep = 0;
-  fix->ypanstep = ypan;
-  fix->line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
-  fix->mmio_start = DBE_REG_PHYS;
-  fix->mmio_len = DBE_REG_SIZE;
+	int err, activate = var->activate;
+	struct dbe_timing_info *timing;
+	u_long line_length;
+	u_long min_mode;
+	int req_dot;
+	int test_mode;
+
+	/*
+	 *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
+	 *  as FB_VMODE_SMOOTH_XPAN is only used internally
+	 */
+
+	if (var->vmode & FB_VMODE_CONUPDATE) {
+		var->vmode |= FB_VMODE_YWRAP;
+		var->xoffset = display->var.xoffset;
+		var->yoffset = display->var.yoffset;
+	}
+
+	/* XXX FIXME - forcing var's */
+	var->xoffset = 0;
+	var->yoffset = 0;
+
+	/* Limit bpp to 8, 16, and 32 */
+	if (var->bits_per_pixel <= 8)
+		var->bits_per_pixel = 8;
+	else if (var->bits_per_pixel <= 16)
+		var->bits_per_pixel = 16;
+	else if (var->bits_per_pixel <= 32)
+		var->bits_per_pixel = 32;
+	else
+		return -EINVAL;
+
+	var->grayscale = 0;	/* No grayscale for now */
+
+	/* determine valid resolution and timing */
+	for (min_mode = 0; min_mode < DBE_VT_SIZE; min_mode++) {
+		if (dbeVTimings[min_mode].width >= var->xres &&
+		    dbeVTimings[min_mode].height >= var->yres)
+			break;
+	}
+
+	if (min_mode == DBE_VT_SIZE)
+		return -EINVAL;	/* Resolution to high */
+
+	/* XXX FIXME - should try to pick best refresh rate */
+	/* for now, pick closest dot-clock within 3MHz */
+	req_dot = PICOS2KHZ(var->pixclock);
+	printk(KERN_INFO "sgivwfb: requested pixclock=%d ps (%d KHz)\n",
+	       var->pixclock, req_dot);
+	test_mode = min_mode;
+	while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) {
+		if (dbeVTimings[test_mode].cfreq + 3000 > req_dot)
+			break;
+		test_mode++;
+	}
+	if (dbeVTimings[min_mode].width != dbeVTimings[test_mode].width)
+		test_mode--;
+	min_mode = test_mode;
+	timing = &dbeVTimings[min_mode];
+	printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n",
+	       timing->cfreq);
+
+	/* Adjust virtual resolution, if necessary */
+	if (var->xres > var->xres_virtual || (!ywrap && !ypan))
+		var->xres_virtual = var->xres;
+	if (var->yres > var->yres_virtual || (!ywrap && !ypan))
+		var->yres_virtual = var->yres;
+
+	/*
+	 *  Memory limit
+	 */
+	line_length =
+	    get_line_length(var->xres_virtual, var->bits_per_pixel);
+	if (line_length * var->yres_virtual > sgivwfb_mem_size)
+		return -ENOMEM;	/* Virtual resolution to high */
+
+	switch (var->bits_per_pixel) {
+	case 8:
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
+	case 16:		/* RGBA 5551 */
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 6;
+		var->green.length = 5;
+		var->blue.offset = 1;
+		var->blue.length = 5;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
+	case 32:		/* RGB 8888 */
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 16;
+		var->blue.length = 8;
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		break;
+	}
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+	var->transp.msb_right = 0;
+
+	/* set video timing information */
+	var->pixclock = KHZ2PICOS(timing->cfreq);
+	var->left_margin = timing->htotal - timing->hsync_end;
+	var->right_margin = timing->hsync_start - timing->width;
+	var->upper_margin = timing->vtotal - timing->vsync_end;
+	var->lower_margin = timing->vsync_start - timing->height;
+	var->hsync_len = timing->hsync_end - timing->hsync_start;
+	var->vsync_len = timing->vsync_end - timing->vsync_start;
+
+	/* Ouch. This breaks the rules but timing_num is only important if you
+	* change a video mode */
+	par->timing_num = min_mode;
+
+	printk(KERN_INFO "sgivwfb: new video mode xres=%d yres=%d bpp=%d\n",
+		var->xres, var->yres, var->bits_per_pixel);
+	printk(KERN_INFO "         vxres=%d vyres=%d\n", var->xres_virtual,
+		var->yres_virtual);
+	return 0;
 }
 
 /*
- *  Read a single color register and split it into
- *  colors/transparent. Return != 0 for invalid regno.
+ *  Set the hardware according to 'par'.
  */
-static int sgivwfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                             u_int *transp, struct fb_info *info)
+static int sgivwfb_set_par(struct fb_info *info)
 {
-  if (regno > 255)
-    return 1;
-
-  *red =   palette[regno].red << 8;
-  *green = palette[regno].green << 8;
-  *blue =  palette[regno].blue << 8;
-  *transp = 0;
-  return 0;
+	struct sgivw_par *par = info->par;
+	int i, j, htmp, temp;
+	u32 readVal, outputVal;
+	int wholeTilesX, maxPixelsPerTileX;
+	int frmWrite1, frmWrite2, frmWrite3b;
+	dbe_timing_info_t *currentTiming;	/* Current Video Timing */
+	int xpmax, ypmax;	// Monitor resolution
+	int bytesPerPixel;	// Bytes per pixel
+
+	currentTiming = &dbeVTimings[par->timing_num];
+	bytesPerPixel = bytes_per_pixel(info->var.bits_per_pixel);
+	xpmax = currentTiming->width;
+	ypmax = currentTiming->height;
+
+	/* dbe_InitGraphicsBase(); */
+	/* Turn on dotclock PLL */
+	DBE_SETREG(ctrlstat, 0x20000000);
+
+	dbe_TurnOffDma();
+
+	/* dbe_CalculateScreenParams(); */
+	maxPixelsPerTileX = 512 / bytesPerPixel;
+	wholeTilesX = xpmax / maxPixelsPerTileX;
+	if (wholeTilesX * maxPixelsPerTileX < xpmax)
+		wholeTilesX++;
+
+	printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n",
+	       maxPixelsPerTileX, wholeTilesX);
+
+	/* dbe_InitGammaMap(); */
+	udelay(10);
+
+	for (i = 0; i < 256; i++) {
+		DBE_ISETREG(gmap, i, (i << 24) | (i << 16) | (i << 8));
+	}
+
+	/* dbe_TurnOn(); */
+	DBE_GETREG(vt_xy, readVal);
+	if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) {
+		DBE_SETREG(vt_xy, 0x00000000);
+		udelay(1);
+	} else
+		dbe_TurnOffDma();
+
+	/* dbe_Initdbe(); */
+	for (i = 0; i < 256; i++) {
+		for (j = 0; j < 100; j++) {
+			DBE_GETREG(cm_fifo, readVal);
+			if (readVal != 0x00000000)
+				break;
+			else
+				udelay(10);
+		}
+
+		// DBE_ISETREG(cmap, i, 0x00000000);
+		DBE_ISETREG(cmap, i, (i << 8) | (i << 16) | (i << 24));
+	}
+
+	/* dbe_InitFramebuffer(); */
+	frmWrite1 = 0;
+	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, frmWrite1,
+		      wholeTilesX);
+	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0);
+
+	switch (bytesPerPixel) {
+	case 1:
+		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
+			      DBE_FRM_DEPTH_8);
+		break;
+	case 2:
+		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
+			      DBE_FRM_DEPTH_16);
+		break;
+	case 4:
+		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
+			      DBE_FRM_DEPTH_32);
+		break;
+	}
+
+	frmWrite2 = 0;
+	SET_DBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, frmWrite2, ypmax);
+
+	// Tell dbe about the framebuffer location and type
+	// XXX What format is the FRM_TILE_PTR??  64K aligned address?
+	frmWrite3b = 0;
+	SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b,
+		      sgivwfb_mem_phys >> 9);
+	SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1);
+	SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1);
+
+	/* Initialize DIDs */
+
+	outputVal = 0;
+	switch (bytesPerPixel) {
+	case 1:
+		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8);
+		break;
+	case 2:
+		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5);
+		break;
+	case 4:
+		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8);
+		break;
+	}
+	SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH);
+
+	for (i = 0; i < 32; i++) {
+		DBE_ISETREG(mode_regs, i, outputVal);
+	}
+
+	/* dbe_InitTiming(); */
+	DBE_SETREG(vt_intr01, 0xffffffff);
+	DBE_SETREG(vt_intr23, 0xffffffff);
+
+	DBE_GETREG(dotclock, readVal);
+	DBE_SETREG(dotclock, readVal & 0xffff);
+
+	DBE_SETREG(vt_xymax, 0x00000000);
+	outputVal = 0;
+	SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_ON, outputVal,
+		      currentTiming->vsync_start);
+	SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_OFF, outputVal,
+		      currentTiming->vsync_end);
+	DBE_SETREG(vt_vsync, outputVal);
+	outputVal = 0;
+	SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_ON, outputVal,
+		      currentTiming->hsync_start);
+	SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_OFF, outputVal,
+		      currentTiming->hsync_end);
+	DBE_SETREG(vt_hsync, outputVal);
+	outputVal = 0;
+	SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_ON, outputVal,
+		      currentTiming->vblank_start);
+	SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_OFF, outputVal,
+		      currentTiming->vblank_end);
+	DBE_SETREG(vt_vblank, outputVal);
+	outputVal = 0;
+	SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_ON, outputVal,
+		      currentTiming->hblank_start);
+	SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_OFF, outputVal,
+		      currentTiming->hblank_end - 3);
+	DBE_SETREG(vt_hblank, outputVal);
+	outputVal = 0;
+	SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_ON, outputVal,
+		      currentTiming->vblank_start);
+	SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_OFF, outputVal,
+		      currentTiming->vblank_end);
+	DBE_SETREG(vt_vcmap, outputVal);
+	outputVal = 0;
+	SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_ON, outputVal,
+		      currentTiming->hblank_start);
+	SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_OFF, outputVal,
+		      currentTiming->hblank_end - 3);
+	DBE_SETREG(vt_hcmap, outputVal);
+
+	outputVal = 0;
+	temp = currentTiming->vblank_start - currentTiming->vblank_end - 1;
+	if (temp > 0)
+		temp = -temp;
+
+	SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32) temp);
+	if (currentTiming->hblank_end >= 20)
+		SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
+			      currentTiming->hblank_end - 20);
+	else
+		SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
+			      currentTiming->htotal - (20 -
+						       currentTiming->
+						       hblank_end));
+	DBE_SETREG(did_start_xy, outputVal);
+
+	outputVal = 0;
+	SET_DBE_FIELD(CRS_START_XY, CRS_STARTY, outputVal,
+		      (u32) (temp + 1));
+	if (currentTiming->hblank_end >= DBE_CRS_MAGIC)
+		SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
+			      currentTiming->hblank_end - DBE_CRS_MAGIC);
+	else
+		SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
+			      currentTiming->htotal - (DBE_CRS_MAGIC -
+						       currentTiming->
+						       hblank_end));
+	DBE_SETREG(crs_start_xy, outputVal);
+
+	outputVal = 0;
+	SET_DBE_FIELD(VC_START_XY, VC_STARTY, outputVal, (u32) temp);
+	SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal,
+		      currentTiming->hblank_end - 4);
+	DBE_SETREG(vc_start_xy, outputVal);
+
+	DBE_SETREG(frm_size_tile, frmWrite1);
+	DBE_SETREG(frm_size_pixel, frmWrite2);
+
+	outputVal = 0;
+	SET_DBE_FIELD(DOTCLK, M, outputVal, currentTiming->pll_m - 1);
+	SET_DBE_FIELD(DOTCLK, N, outputVal, currentTiming->pll_n - 1);
+	SET_DBE_FIELD(DOTCLK, P, outputVal, currentTiming->pll_p);
+	SET_DBE_FIELD(DOTCLK, RUN, outputVal, 1);
+	DBE_SETREG(dotclock, outputVal);
+
+	udelay(11 * 1000);
+
+	DBE_SETREG(vt_vpixen, 0xffffff);
+	DBE_SETREG(vt_hpixen, 0xffffff);
+
+	outputVal = 0;
+	SET_DBE_FIELD(VT_XYMAX, VT_MAXX, outputVal, currentTiming->htotal);
+	SET_DBE_FIELD(VT_XYMAX, VT_MAXY, outputVal, currentTiming->vtotal);
+	DBE_SETREG(vt_xymax, outputVal);
+
+	outputVal = frmWrite1;
+	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, outputVal, 1);
+	DBE_SETREG(frm_size_tile, outputVal);
+	DBE_SETREG(frm_size_tile, frmWrite1);
+
+	outputVal = 0;
+	SET_DBE_FIELD(OVR_WIDTH_TILE, OVR_FIFO_RESET, outputVal, 1);
+	DBE_SETREG(ovr_width_tile, outputVal);
+	DBE_SETREG(ovr_width_tile, 0);
+
+	DBE_SETREG(frm_control, frmWrite3b);
+	DBE_SETREG(did_control, 0);
+
+	// Wait for dbe to take frame settings
+	for (i = 0; i < 100000; i++) {
+		DBE_GETREG(frm_inhwctrl, readVal);
+		if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) !=
+		    0)
+			break;
+		else
+			udelay(1);
+	}
+
+	if (i == 100000)
+		printk(KERN_INFO
+		       "sgivwfb: timeout waiting for frame DMA enable.\n");
+
+	outputVal = 0;
+	htmp = currentTiming->hblank_end - 19;
+	if (htmp < 0)
+		htmp += currentTiming->htotal;	/* allow blank to wrap around */
+	SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_ON, outputVal, htmp);
+	SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_OFF, outputVal,
+		      ((htmp + currentTiming->width -
+			2) % currentTiming->htotal));
+	DBE_SETREG(vt_hpixen, outputVal);
+
+	outputVal = 0;
+	SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_OFF, outputVal,
+		      currentTiming->vblank_start);
+	SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_ON, outputVal,
+		      currentTiming->vblank_end);
+	DBE_SETREG(vt_vpixen, outputVal);
+
+	// Turn off mouse cursor
+	par->regs->crs_ctl = 0;
+
+	// XXX What's this section for??
+	DBE_GETREG(ctrlstat, readVal);
+	readVal &= 0x02000000;
+
+	if (readVal != 0) {
+		DBE_SETREG(ctrlstat, 0x30000000);
+	}
+	return 0;
 }
 
 /*
@@ -530,307 +639,64 @@
  *  entries in the var structure). Return != 0 for invalid regno.
  */
 
-static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                             u_int transp, struct fb_info *info)
-{
-  if (regno > 255)
-    return 1;
-  red >>= 8;
-  green >>= 8;
-  blue >>= 8;
-  palette[regno].red = red;
-  palette[regno].green = green;
-  palette[regno].blue = blue;
-
-  /* wait for the color map FIFO to have a free entry */
-  while (cmap_fifo == 0)
-    cmap_fifo = regs->cm_fifo;
-
-  regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
-  cmap_fifo--;			/* assume FIFO is filling up */
-  return 0;
-}
-
-/* ---------------------------------------------------- */
-
-/*
- *  Get the Fixed Part of the Display
- */
-static int sgivwfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			   struct fb_info *info)
-{
-  struct fb_var_screeninfo *var;
-
-  if (con == -1)
-    var = &par_current.var;
-  else
-    var = &fb_display[con].var;
-  sgivwfb_encode_fix(fix, var);
-  return 0;
-}
-
-/*
- *  Get the User Defined Part of the Display. If a real par get it form there
- */
-static int sgivwfb_get_var(struct fb_var_screeninfo *var, int con,
-			   struct fb_info *info)
-{
-  if (con == -1)
-    *var = par_current.var;
-  else
-    *var = fb_display[con].var;
-  return 0;
-}
-
-/*
- *  Set the User Defined Part of the Display. Again if par use it to get
- *  real video mode.
- */
-static int sgivwfb_set_var(struct fb_var_screeninfo *var, int con,
-			   struct fb_info *info)
-{
-  int err, activate = var->activate;
-  int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
-  u_long line_length;
-  u_long min_mode;
-  int req_dot;
-  int test_mode;
-
-  struct dbe_timing_info *timing;
-
-  struct display *display;
-
-  if (con >= 0)
-    display = &fb_display[con];
-  else
-    display = &disp;	/* used during initialization */
-
-  /*
-   *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
-   *  as FB_VMODE_SMOOTH_XPAN is only used internally
-   */
-
-  if (var->vmode & FB_VMODE_CONUPDATE) {
-    var->vmode |= FB_VMODE_YWRAP;
-    var->xoffset = display->var.xoffset;
-    var->yoffset = display->var.yoffset;
-  }
-
-  /* XXX FIXME - forcing var's */
-  var->xoffset = 0;
-  var->yoffset = 0;
-
-  /* Limit bpp to 8, 16, and 32 */
-  if (var->bits_per_pixel <= 8)
-    var->bits_per_pixel = 8;
-  else if (var->bits_per_pixel <= 16)
-    var->bits_per_pixel = 16;
-  else if (var->bits_per_pixel <= 32)
-    var->bits_per_pixel = 32;
-  else
-    return -EINVAL;
-
-  var->grayscale = 0;           /* No grayscale for now */
-
-  /* determine valid resolution and timing */
-  for (min_mode=0; min_mode<DBE_VT_SIZE; min_mode++) {
-    if (dbeVTimings[min_mode].width >= var->xres &&
-        dbeVTimings[min_mode].height >= var->yres)
-      break;
-  }
-
-  if (min_mode == DBE_VT_SIZE)
-    return -EINVAL;             /* Resolution to high */
-
-  /* XXX FIXME - should try to pick best refresh rate */
-  /* for now, pick closest dot-clock within 3MHz*/
-#error "Floating point not allowed in kernel"  
-  req_dot = (int)((1.0e3/1.0e6) / (1.0e-12 * (float)var->pixclock));
-  printk(KERN_INFO "sgivwfb: requested pixclock=%d ps (%d KHz)\n", var->pixclock,
-	 req_dot);
-  test_mode=min_mode;
-  while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) {
-    if (dbeVTimings[test_mode].cfreq+3000 > req_dot)
-      break;
-    test_mode++;
-  }
-  if (dbeVTimings[min_mode].width != dbeVTimings[test_mode].width)
-    test_mode--;
-  min_mode = test_mode;
-  timing = &dbeVTimings[min_mode];
-  printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq);
-
-  /* Adjust virtual resolution, if necessary */
-  if (var->xres > var->xres_virtual || (!ywrap && !ypan))
-    var->xres_virtual = var->xres;
-  if (var->yres > var->yres_virtual || (!ywrap && !ypan))
-    var->yres_virtual = var->yres;
-
-  /*
-   *  Memory limit
-   */
-  line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
-  if (line_length*var->yres_virtual > sgivwfb_mem_size)
-    return -ENOMEM;             /* Virtual resolution to high */
-
-  switch (var->bits_per_pixel)
-    {
-    case 8:
-      var->red.offset = 0;
-      var->red.length = 8;
-      var->green.offset = 0;
-      var->green.length = 8;
-      var->blue.offset = 0;
-      var->blue.length = 8;
-      var->transp.offset = 0;
-      var->transp.length = 0;
-      break;
-    case 16:	/* RGBA 5551 */
-      var->red.offset = 11;
-      var->red.length = 5;
-      var->green.offset = 6;
-      var->green.length = 5;
-      var->blue.offset = 1;
-      var->blue.length = 5;
-      var->transp.offset = 0;
-      var->transp.length = 0;
-      break;
-    case 32:	/* RGB 8888 */
-      var->red.offset = 0;
-      var->red.length = 8;
-      var->green.offset = 8;
-      var->green.length = 8;
-      var->blue.offset = 16;
-      var->blue.length = 8;
-      var->transp.offset = 24;
-      var->transp.length = 8;
-      break;
-    }
-  var->red.msb_right = 0;
-  var->green.msb_right = 0;
-  var->blue.msb_right = 0;
-  var->transp.msb_right = 0;
-
-  /* set video timing information */
-  var->pixclock = (__u32)(1.0e+9/(float)timing->cfreq);
-  var->left_margin = timing->htotal - timing->hsync_end;
-  var->right_margin = timing->hsync_start - timing->width;
-  var->upper_margin = timing->vtotal - timing->vsync_end;
-  var->lower_margin = timing->vsync_start - timing->height;
-  var->hsync_len = timing->hsync_end - timing->hsync_start;
-  var->vsync_len = timing->vsync_end -  timing->vsync_start;
-
-  if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-    oldxres = display->var.xres;
-    oldyres = display->var.yres;
-    oldvxres = display->var.xres_virtual;
-    oldvyres = display->var.yres_virtual;
-    oldbpp = display->var.bits_per_pixel;
-    display->var = *var;
-    par_current.var = *var;
-    par_current.timing_num = min_mode;
-    if (oldxres != var->xres || oldyres != var->yres ||
-	oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
-	oldbpp != var->bits_per_pixel || !par_current.valid) {
-      struct fb_fix_screeninfo fix;
-      printk(KERN_INFO "sgivwfb: new video mode xres=%d yres=%d bpp=%d\n",
-	     var->xres, var->yres, var->bits_per_pixel);
-      printk(KERN_INFO "         vxres=%d vyres=%d\n",
-	     var->xres_virtual, var->yres_virtual);
-      activate_par(&par_current);
-      sgivwfb_encode_fix(&fix, var);
-      display->visual = fix.visual;
-      display->type = fix.type;
-      display->type_aux = fix.type_aux;
-      display->ypanstep = fix.ypanstep;
-      display->ywrapstep = fix.ywrapstep;
-      display->line_length = fix.line_length;
-      display->can_soft_blank = 1;
-      display->inverse = 0;
-      if (oldbpp != var->bits_per_pixel || !par_current.valid) {
-	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
-	  return err;
-	do_install_cmap(con, info);
-      }
-      switch (var->bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
-      case 8:
-	display->dispsw = &fbcon_cfb8;
-	break;
-#endif
-#ifdef FBCON_HAS_CFB16
-      case 16:
-	display->dispsw = &fbcon_cfb16;
-	display->dispsw_data = fbcon_cmap.cfb16;
-	break;
-#endif
-#ifdef FBCON_HAS_CFB32
-      case 32:
-	display->dispsw = &fbcon_cfb32;
-	display->dispsw_data = fbcon_cmap.cfb32;
-	break;
-#endif
-      default:
-	display->dispsw = &fbcon_dummy;
-	break;
-      }
-      par_current.valid = 1;
-      if (fb_info.changevar)
-	(*fb_info.changevar)(con);
-    }
-  }
-  return 0;
-}
-
-/*
- *  Get the Colormap
- */
-static int sgivwfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			    struct fb_info *info)
-{
-  if (con == info->currcon) /* current console? */
-    return fb_get_cmap(cmap, kspc, sgivwfb_getcolreg, info);
-  else if (fb_display[con].cmap.len) /* non default colormap? */
-    fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-  else
-    fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
-		 cmap, kspc ? 0 : 2);
-  return 0;
+static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
+			     u_int blue, u_int transp,
+			     struct fb_info *info)
+{
+	struct sgivw_par *par = (struct sgivw_par *) info->par;
+
+	if (regno > 255)
+		return 1;
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+	/* wait for the color map FIFO to have a free entry */
+	while (par->cmap_fifo == 0)
+		par->cmap_fifo = par->regs->cm_fifo;
+
+	par->regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
+	par->cmap_fifo--;	/* assume FIFO is filling up */
+	return 0;
 }
 
 static int sgivwfb_mmap(struct fb_info *info, struct file *file,
-                        struct vm_area_struct *vma)
+			struct vm_area_struct *vma)
 {
-  unsigned long size = vma->vm_end - vma->vm_start;
-  unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-  if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-	return -EINVAL;
-  if (offset+size > sgivwfb_mem_size)
-    return -EINVAL;
-  offset += sgivwfb_mem_phys;
-  pgprot_val(vma->vm_page_prot) = pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
-  vma->vm_flags |= VM_IO;
-  if (remap_page_range(vma, vma->vm_start, offset, size, vma->vm_page_prot))
-    return -EAGAIN;
-  vma->vm_file = file;
-  printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", offset, vma->vm_start);
-  return 0;
+	unsigned long size = vma->vm_end - vma->vm_start;
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+	if (offset + size > sgivwfb_mem_size)
+		return -EINVAL;
+	offset += sgivwfb_mem_phys;
+	pgprot_val(vma->vm_page_prot) =
+	    pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
+	vma->vm_flags |= VM_IO;
+	if (remap_page_range
+	    (vma, vma->vm_start, offset, size, vma->vm_page_prot))
+		return -EAGAIN;
+	vma->vm_file = file;
+	printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n",
+	       offset, vma->vm_start);
+	return 0;
 }
 
 int __init sgivwfb_setup(char *options)
 {
-  char *this_opt;
+	char *this_opt;
 
-  fb_info.fontname[0] = '\0';
+	fb_info.fontname[0] = '\0';
 
-  if (!options || !*options)
-    return 0;
+	if (!options || !*options)
+		return 0;
 
-  while ((this_opt = strsep(&options, ",")) != NULL) {
-    if (!strncmp(this_opt, "font:", 5))
-      strcpy(fb_info.fontname, this_opt+5);
-  }
-  return 0;
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+		if (!strncmp(this_opt, "font:", 5))
+			strcpy(fb_info.fontname, this_opt + 5);
+	}
+	return 0;
 }
 
 /*
@@ -838,75 +704,67 @@
  */
 int __init sgivwfb_init(void)
 {
-  printk(KERN_INFO "sgivwfb: framebuffer at 0x%lx, size %ldk\n",
-	 sgivwfb_mem_phys, sgivwfb_mem_size/1024);
-
-  regs = (asregs*)ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
-  if (!regs) {
-    printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
-    goto fail_ioremap_regs;
-  }
+	printk(KERN_INFO "sgivwfb: framebuffer at 0x%lx, size %ldk\n",
+	       sgivwfb_mem_phys, sgivwfb_mem_size / 1024);
 
+	default_par.regs = (asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
+	if (!default_par.regs) {
+		printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
+		goto fail_ioremap_regs;
+	}
 #ifdef CONFIG_MTRR
-  mtrr_add((unsigned long)sgivwfb_mem_phys, sgivwfb_mem_size, MTRR_TYPE_WRCOMB, 1);
+	mtrr_add((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size,
+		 MTRR_TYPE_WRCOMB, 1);
 #endif
 
-  strcpy(fb_info.modename, sgivwfb_name);
-  fb_info.changevar = NULL;
-  fb_info.node = NODEV;
-  fb_info.fbops = &sgivwfb_ops;
-  fb_info.disp = &disp;
-  fb_info.currcon = -1;	
-  fb_info.switch_con = &sgivwfbcon_switch;
-  fb_info.updatevar = &sgivwfbcon_updatevar;
-  fb_info.flags = FBINFO_FLAG_DEFAULT;
-
-  fb_info.screen_base = ioremap_nocache((unsigned long)sgivwfb_mem_phys, sgivwfb_mem_size);
-  if (!fb_info.screen_base) {
-    printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
-    goto fail_ioremap_fbmem;
-  }
-
-  /* turn on default video mode */
-  sgivwfb_set_var(&par_current.var, -1, &fb_info);
-
-  if (register_framebuffer(&fb_info) < 0) {
-    printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n");
-    goto fail_register_framebuffer;
-  }
-
-  printk(KERN_INFO "fb%d: Virtual frame buffer device, using %ldK of video memory\n",
-	 GET_FB_IDX(fb_info.node), sgivwfb_mem_size>>10);
-
-  return 0;
-
- fail_register_framebuffer:
-  iounmap((char*)fb_info.screen_base);
- fail_ioremap_fbmem:
-  iounmap(regs);
- fail_ioremap_regs:
-  return -ENXIO;
-}
-
-static int sgivwfbcon_switch(int con, struct fb_info *info)
-{
-  /* Do we have to save the colormap? */
-  if (fb_display[info->currcon].cmap.len)
-    fb_get_cmap(&fb_display[info->currcon].cmap, 1, sgivwfb_getcolreg, info);
-
-  info->currcon = con;
-  /* Install new colormap */
-  do_install_cmap(con, info);
-  return 0;
-}
-
-/*
- *  Update the `var' structure (called by fbcon.c)
- */
-static int sgivwfbcon_updatevar(int con, struct fb_info *info)
-{
-    /* Nothing */
-    return 0;
+	sgivwfb_fix.smem_start = sgivwfb_mem_phys;
+	sgivwfb_fix.smem_len = sgivwfb_mem_size;
+	sgivwfb_fix.ywrapstep = ywrap;
+	sgivwfb_fix.ypanstep = ypan;
+
+	strcpy(fb_info.modename, sgivwfb_fix.id);
+	fb_info.changevar = NULL;
+	fb_info.node = NODEV;
+	fb_info.fix = sgivwfb_fix;
+	fb_info.var = sgivwfb_var;
+	fb_info.fbops = &sgivwfb_ops;
+	fb_info.pseudo_palette = pseudo_palette;
+	fb_info.par = &default_par;
+	fb_info.disp = &disp;
+	fb_info.currcon = -1;
+	fb_info.switch_con = gen_switch;
+	fb_info.updatevar = gen_update_var;
+	fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+	fb_info.screen_base =
+	    ioremap_nocache((unsigned long) sgivwfb_mem_phys,
+			    sgivwfb_mem_size);
+	if (!fb_info.screen_base) {
+		printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
+		goto fail_ioremap_fbmem;
+	}
+
+	/* turn on default video mode */
+	gen_set_var(&fb_info->var, -1, &fb_info);
+
+	if (register_framebuffer(&fb_info) < 0) {
+		printk(KERN_ERR
+		       "sgivwfb: couldn't register framebuffer\n");
+		goto fail_register_framebuffer;
+	}
+
+	printk(KERN_INFO
+	       "fb%d: Virtual frame buffer device, using %ldK of video memory\n",
+	       GET_FB_IDX(fb_info.node), sgivwfb_mem_size >> 10);
+
+	return 0;
+
+      fail_register_framebuffer:
+	iounmap((char *) fb_info.screen_base);
+      fail_ioremap_fbmem:
+	iounmap(default_par.regs);
+      fail_ioremap_regs:
+	return -ENXIO;
 }
 
 #ifdef MODULE
@@ -914,15 +772,15 @@
 
 int init_module(void)
 {
-  return sgivwfb_init();
+	return sgivwfb_init();
 }
 
 void cleanup_module(void)
 {
-  unregister_framebuffer(&fb_info);
-  dbe_TurnOffDma();
-  iounmap(regs);
-  iounmap(&fb_info.screen_base);
+	unregister_framebuffer(&fb_info);
+	dbe_TurnOffDma();
+	iounmap(regs);
+	iounmap(&fb_info.screen_base);
 }
 
-#endif /* MODULE */
+#endif				/* MODULE */
diff -Nru a/drivers/video/sgivwfb.h b/drivers/video/sgivwfb.h
--- a/drivers/video/sgivwfb.h	Wed Jul 24 14:03:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,660 +0,0 @@
-/*
- *  linux/drivers/video/sgivwfb.h -- SGI DBE frame buffer device header
- *
- *      Copyright (C) 1999 Silicon Graphics, Inc.
- *      Jeffrey Newquist, newquist@engr.sgi.som
- *
- *  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.
- */
-
-#ifndef __SGIVWFB_H__
-#define __SGIVWFB_H__
-
-#define DBE_GETREG(reg, dest)       ((dest) = DBE_REG_BASE->##reg)
-#define DBE_SETREG(reg, src)        DBE_REG_BASE->##reg = (src)
-#define DBE_IGETREG(reg, idx, dest) ((dest) = DBE_REG_BASE->##reg##[idx])
-#define DBE_ISETREG(reg, idx, src)  (DBE_REG_BASE->##reg##[idx] = (src))
-
-#define MASK(msb, lsb)          ( (((u32)1<<((msb)-(lsb)+1))-1) << (lsb) )
-#define GET(v, msb, lsb)        ( ((u32)(v) & MASK(msb,lsb)) >> (lsb) )
-#define SET(v, f, msb, lsb)     ( (v) = ((v)&~MASK(msb,lsb)) | (( (u32)(f)<<(lsb) ) & MASK(msb,lsb)) )
-
-#define GET_DBE_FIELD(reg, field, v)        GET((v), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB)
-#define SET_DBE_FIELD(reg, field, v, f)     SET((v), (f), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB)
-
-/* NOTE: All loads/stores must be 32 bits and uncached */
-
-#define DBE_REG_PHYS	0xd0000000
-#define DBE_REG_SIZE        0x01000000
-
-typedef struct {
-  volatile u32 ctrlstat;     /* 0x000000 general control */
-  volatile u32 dotclock;     /* 0x000004 dot clock PLL control */
-  volatile u32 i2c;          /* 0x000008 crt I2C control */
-  volatile u32 sysclk;       /* 0x00000c system clock PLL control */
-  volatile u32 i2cfp;        /* 0x000010 flat panel I2C control */
-  volatile u32 id;           /* 0x000014 device id/chip revision */
-  volatile u32 config;       /* 0x000018 power on configuration */
-  volatile u32 bist;         /* 0x00001c internal bist status */
-
-  char _pad0[ 0x010000 - 0x000020 ];
-
-  volatile u32 vt_xy;        /* 0x010000 current dot coords */
-  volatile u32 vt_xymax;     /* 0x010004 maximum dot coords */
-  volatile u32 vt_vsync;     /* 0x010008 vsync on/off */
-  volatile u32 vt_hsync;     /* 0x01000c hsync on/off */
-  volatile u32 vt_vblank;    /* 0x010010 vblank on/off */
-  volatile u32 vt_hblank;    /* 0x010014 hblank on/off */
-  volatile u32 vt_flags;     /* 0x010018 polarity of vt signals */
-  volatile u32 vt_f2rf_lock; /* 0x01001c f2rf & framelck y coord */
-  volatile u32 vt_intr01;    /* 0x010020 intr 0,1 y coords */
-  volatile u32 vt_intr23;    /* 0x010024 intr 2,3 y coords */
-  volatile u32 fp_hdrv;      /* 0x010028 flat panel hdrv on/off */
-  volatile u32 fp_vdrv;      /* 0x01002c flat panel vdrv on/off */
-  volatile u32 fp_de;        /* 0x010030 flat panel de on/off */
-  volatile u32 vt_hpixen;    /* 0x010034 intrnl horiz pixel on/off*/
-  volatile u32 vt_vpixen;    /* 0x010038 intrnl vert pixel on/off */
-  volatile u32 vt_hcmap;     /* 0x01003c cmap write (horiz) */
-  volatile u32 vt_vcmap;     /* 0x010040 cmap write (vert) */
-  volatile u32 did_start_xy; /* 0x010044 eol/f did/xy reset val */
-  volatile u32 crs_start_xy; /* 0x010048 eol/f crs/xy reset val */
-  volatile u32 vc_start_xy;  /* 0x01004c eol/f vc/xy reset val */
-
-  char _pad1[ 0x020000 - 0x010050 ];
-
-  volatile u32 ovr_width_tile; /* 0x020000 overlay plane ctrl 0 */
-  volatile u32 ovr_inhwctrl;   /* 0x020004 overlay plane ctrl 1 */
-  volatile u32 ovr_control;    /* 0x020008 overlay plane ctrl 1 */
-
-  char _pad2[ 0x030000 - 0x02000C ];
-
-  volatile u32 frm_size_tile;  /* 0x030000 normal plane ctrl 0 */
-  volatile u32 frm_size_pixel; /* 0x030004 normal plane ctrl 1 */
-  volatile u32 frm_inhwctrl;   /* 0x030008 normal plane ctrl 2 */
-  volatile u32 frm_control;	   /* 0x03000C normal plane ctrl 3 */
-
-  char _pad3[ 0x040000 - 0x030010 ];
-
-  volatile u32 did_inhwctrl;   /* 0x040000 DID control */
-  volatile u32 did_control;    /* 0x040004 DID shadow */
-
-  char _pad4[ 0x048000 - 0x040008 ];
-
-  volatile u32 mode_regs[32];  /* 0x048000 - 0x04807c WID table */
-
-  char _pad5[ 0x050000 - 0x048080 ];
-
-  volatile u32 cmap[6144];     /* 0x050000 - 0x055ffc color map */
-
-  char _pad6[ 0x058000 - 0x056000 ];
-
-  volatile u32 cm_fifo;        /* 0x058000 color map fifo status */
-
-  char _pad7[ 0x060000 - 0x058004 ];
-
-  volatile u32 gmap[256];      /* 0x060000 - 0x0603fc gamma map */
-
-  char _pad8[ 0x068000 - 0x060400 ];
-
-  volatile u32 gmap10[1024];   /* 0x068000 - 0x068ffc gamma map */
-
-  char _pad9[ 0x070000 - 0x069000 ];
-
-  volatile u32 crs_pos;        /* 0x070000 cusror control 0 */
-  volatile u32 crs_ctl;        /* 0x070004 cusror control 1 */
-  volatile u32 crs_cmap[3];    /* 0x070008 - 0x070010 crs cmap */
-
-  char _pad10[ 0x078000 - 0x070014 ];
-
-  volatile u32 crs_glyph[64];  /* 0x078000 - 0x0780fc crs glyph */
-
-  char _pad11[ 0x080000 - 0x078100 ];
-
-  volatile u32 vc_0;           /* 0x080000 video capture crtl 0 */
-  volatile u32 vc_1;           /* 0x080004 video capture crtl 1 */
-  volatile u32 vc_2;           /* 0x080008 video capture crtl 2 */
-  volatile u32 vc_3;           /* 0x08000c video capture crtl 3 */
-  volatile u32 vc_4;           /* 0x080010 video capture crtl 3 */
-  volatile u32 vc_5;           /* 0x080014 video capture crtl 3 */
-  volatile u32 vc_6;           /* 0x080018 video capture crtl 3 */
-  volatile u32 vc_7;           /* 0x08001c video capture crtl 3 */
-  volatile u32 vc_8;           /* 0x08000c video capture crtl 3 */
-} asregs;
-
-/* Bit mask information */
-
-#define DBE_CTRLSTAT_CHIPID_MSB     3
-#define DBE_CTRLSTAT_CHIPID_LSB     0
-#define DBE_CTRLSTAT_SENSE_N_MSB    4
-#define DBE_CTRLSTAT_SENSE_N_LSB    4
-#define DBE_CTRLSTAT_PCLKSEL_MSB    29
-#define DBE_CTRLSTAT_PCLKSEL_LSB    28
-
-#define DBE_DOTCLK_M_MSB            7
-#define DBE_DOTCLK_M_LSB            0
-#define DBE_DOTCLK_N_MSB            13
-#define DBE_DOTCLK_N_LSB            8
-#define DBE_DOTCLK_P_MSB            15
-#define DBE_DOTCLK_P_LSB            14
-#define DBE_DOTCLK_RUN_MSB          20
-#define DBE_DOTCLK_RUN_LSB          20
-
-#define DBE_VT_XY_VT_FREEZE_MSB     31
-#define DBE_VT_XY_VT_FREEZE_LSB     31
-
-#define DBE_VT_VSYNC_VT_VSYNC_ON_MSB        23
-#define DBE_VT_VSYNC_VT_VSYNC_ON_LSB        12
-#define DBE_VT_VSYNC_VT_VSYNC_OFF_MSB       11
-#define DBE_VT_VSYNC_VT_VSYNC_OFF_LSB       0
-
-#define DBE_VT_HSYNC_VT_HSYNC_ON_MSB        23
-#define DBE_VT_HSYNC_VT_HSYNC_ON_LSB        12
-#define DBE_VT_HSYNC_VT_HSYNC_OFF_MSB       11
-#define DBE_VT_HSYNC_VT_HSYNC_OFF_LSB       0
-
-#define DBE_VT_VBLANK_VT_VBLANK_ON_MSB        23
-#define DBE_VT_VBLANK_VT_VBLANK_ON_LSB        12
-#define DBE_VT_VBLANK_VT_VBLANK_OFF_MSB       11
-#define DBE_VT_VBLANK_VT_VBLANK_OFF_LSB       0
-
-#define DBE_VT_HBLANK_VT_HBLANK_ON_MSB        23
-#define DBE_VT_HBLANK_VT_HBLANK_ON_LSB        12
-#define DBE_VT_HBLANK_VT_HBLANK_OFF_MSB       11
-#define DBE_VT_HBLANK_VT_HBLANK_OFF_LSB       0
-
-#define DBE_VT_VCMAP_VT_VCMAP_ON_MSB        23
-#define DBE_VT_VCMAP_VT_VCMAP_ON_LSB        12
-#define DBE_VT_VCMAP_VT_VCMAP_OFF_MSB       11
-#define DBE_VT_VCMAP_VT_VCMAP_OFF_LSB       0
-
-#define DBE_VT_HCMAP_VT_HCMAP_ON_MSB        23
-#define DBE_VT_HCMAP_VT_HCMAP_ON_LSB        12
-#define DBE_VT_HCMAP_VT_HCMAP_OFF_MSB       11
-#define DBE_VT_HCMAP_VT_HCMAP_OFF_LSB       0
-
-#define DBE_VT_XYMAX_VT_MAXX_MSB    11
-#define DBE_VT_XYMAX_VT_MAXX_LSB    0
-#define DBE_VT_XYMAX_VT_MAXY_MSB    23
-#define DBE_VT_XYMAX_VT_MAXY_LSB    12
-
-#define DBE_VT_HPIXEN_VT_HPIXEN_ON_MSB      23
-#define DBE_VT_HPIXEN_VT_HPIXEN_ON_LSB      12
-#define DBE_VT_HPIXEN_VT_HPIXEN_OFF_MSB     11
-#define DBE_VT_HPIXEN_VT_HPIXEN_OFF_LSB     0
-
-#define DBE_VT_VPIXEN_VT_VPIXEN_ON_MSB      23
-#define DBE_VT_VPIXEN_VT_VPIXEN_ON_LSB      12
-#define DBE_VT_VPIXEN_VT_VPIXEN_OFF_MSB     11
-#define DBE_VT_VPIXEN_VT_VPIXEN_OFF_LSB     0
-
-#define DBE_OVR_CONTROL_OVR_DMA_ENABLE_MSB  0
-#define DBE_OVR_CONTROL_OVR_DMA_ENABLE_LSB  0
-
-#define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_MSB 0
-#define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_LSB 0
-
-#define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_MSB       13
-#define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_LSB       13
-
-#define DBE_FRM_CONTROL_FRM_DMA_ENABLE_MSB  0
-#define DBE_FRM_CONTROL_FRM_DMA_ENABLE_LSB  0
-#define DBE_FRM_CONTROL_FRM_TILE_PTR_MSB    31
-#define DBE_FRM_CONTROL_FRM_TILE_PTR_LSB    9
-#define DBE_FRM_CONTROL_FRM_LINEAR_MSB      1
-#define DBE_FRM_CONTROL_FRM_LINEAR_LSB      1
-
-#define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_MSB 0
-#define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_LSB 0
-
-#define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_MSB        12
-#define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_LSB        5
-#define DBE_FRM_SIZE_TILE_FRM_RHS_MSB       4
-#define DBE_FRM_SIZE_TILE_FRM_RHS_LSB       0
-#define DBE_FRM_SIZE_TILE_FRM_DEPTH_MSB     14
-#define DBE_FRM_SIZE_TILE_FRM_DEPTH_LSB     13
-#define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_MSB        15
-#define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_LSB        15
-
-#define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_MSB        31
-#define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_LSB        16
-
-#define DBE_DID_CONTROL_DID_DMA_ENABLE_MSB  0
-#define DBE_DID_CONTROL_DID_DMA_ENABLE_LSB  0
-#define DBE_DID_INHWCTRL_DID_DMA_ENABLE_MSB 0
-#define DBE_DID_INHWCTRL_DID_DMA_ENABLE_LSB 0
-
-#define DBE_DID_START_XY_DID_STARTY_MSB     23
-#define DBE_DID_START_XY_DID_STARTY_LSB     12
-#define DBE_DID_START_XY_DID_STARTX_MSB     11
-#define DBE_DID_START_XY_DID_STARTX_LSB     0
-
-#define DBE_CRS_START_XY_CRS_STARTY_MSB     23
-#define DBE_CRS_START_XY_CRS_STARTY_LSB     12
-#define DBE_CRS_START_XY_CRS_STARTX_MSB     11
-#define DBE_CRS_START_XY_CRS_STARTX_LSB     0
-
-#define DBE_WID_TYP_MSB     4
-#define DBE_WID_TYP_LSB     2
-#define DBE_WID_BUF_MSB     1
-#define DBE_WID_BUF_LSB     0
-
-#define DBE_VC_START_XY_VC_STARTY_MSB       23
-#define DBE_VC_START_XY_VC_STARTY_LSB       12
-#define DBE_VC_START_XY_VC_STARTX_MSB       11
-#define DBE_VC_START_XY_VC_STARTX_LSB       0
-
-/* Constants */
-
-#define DBE_FRM_DEPTH_8     0
-#define DBE_FRM_DEPTH_16    1
-#define DBE_FRM_DEPTH_32    2
-
-#define DBE_CMODE_I8        0
-#define DBE_CMODE_I12       1
-#define DBE_CMODE_RG3B2     2
-#define DBE_CMODE_RGB4      3
-#define DBE_CMODE_ARGB5     4
-#define DBE_CMODE_RGB8      5
-#define DBE_CMODE_RGBA5     6
-#define DBE_CMODE_RGB10     7
-
-#define DBE_BMODE_BOTH      3
-
-#define DBE_CRS_MAGIC       54
-
-/* Config Register (DBE Only) Definitions */
-
-#define DBE_CONFIG_VDAC_ENABLE       0x00000001
-#define DBE_CONFIG_VDAC_GSYNC        0x00000002
-#define DBE_CONFIG_VDAC_PBLANK       0x00000004
-#define DBE_CONFIG_FPENABLE          0x00000008
-#define DBE_CONFIG_LENDIAN           0x00000020
-#define DBE_CONFIG_TILEHIST          0x00000040
-#define DBE_CONFIG_EXT_ADDR          0x00000080
-
-#define DBE_CONFIG_FBDEV        ( DBE_CONFIG_VDAC_ENABLE | \
-                                      DBE_CONFIG_VDAC_GSYNC  | \
-                                      DBE_CONFIG_VDAC_PBLANK | \
-                                      DBE_CONFIG_LENDIAN     | \
-                                      DBE_CONFIG_EXT_ADDR )
-
-/*
- * Available Video Timings and Corresponding Indices
- */
-
-typedef enum {
-  DBE_VT_640_480_60,
-
-  DBE_VT_800_600_60,
-  DBE_VT_800_600_75,
-  DBE_VT_800_600_120,
-
-  DBE_VT_1024_768_50,
-  DBE_VT_1024_768_60,
-  DBE_VT_1024_768_75,
-  DBE_VT_1024_768_85,
-  DBE_VT_1024_768_120,
-
-  DBE_VT_1280_1024_50,
-  DBE_VT_1280_1024_60,
-  DBE_VT_1280_1024_75,
-  DBE_VT_1280_1024_85,
-
-  DBE_VT_1600_1024_53,
-  DBE_VT_1600_1024_60,
-
-  DBE_VT_1600_1200_50,
-  DBE_VT_1600_1200_60,
-  DBE_VT_1600_1200_75,
-
-  DBE_VT_1920_1080_50,
-  DBE_VT_1920_1080_60,
-  DBE_VT_1920_1080_72,
-
-  DBE_VT_1920_1200_50,
-  DBE_VT_1920_1200_60,
-  DBE_VT_1920_1200_66,
-
-  DBE_VT_UNKNOWN
-} dbe_timing_t;
-
-
-
-/*
- * Crime Video Timing Data Structure
- */
-
-typedef struct dbe_timing_info
-{
-  dbe_timing_t type;
-  int flags;				
-  short width;		    /* Monitor resolution		*/
-  short height;
-  int fields_sec;	    /* fields/sec  (Hz -3 dec. places */
-  int cfreq;		    /* pixel clock frequency (MHz -3 dec. places) */
-  short htotal;		    /* Horizontal total pixels	*/
-  short hblank_start;	    /* Horizontal blank start	*/
-  short hblank_end;	    /* Horizontal blank end		*/
-  short hsync_start;	    /* Horizontal sync start	*/
-  short hsync_end;	    /* Horizontal sync end		*/
-  short vtotal;		    /* Vertical total lines		*/
-  short vblank_start;	    /* Vertical blank start		*/
-  short vblank_end;	    /* Vertical blank end		*/
-  short vsync_start;	    /* Vertical sync start		*/
-  short vsync_end;	    /* Vertical sync end		*/
-  short pll_m;		    /* PLL M parameter		*/
-  short pll_n;		    /* PLL P parameter		*/
-  short pll_p;		    /* PLL N parameter		*/
-} dbe_timing_info_t;
-
-/* Defines for dbe_vof_info_t flags */
-
-#define DBE_VOF_UNKNOWNMON    1
-#define DBE_VOF_STEREO        2
-#define DBE_VOF_DO_GENSYNC    4          /* enable incoming sync */
-#define DBE_VOF_SYNC_ON_GREEN 8          /* sync on green */
-#define DBE_VOF_FLATPANEL     0x1000     /* FLATPANEL Timing */
-#define DBE_VOF_MAGICKEY      0x2000     /* Backdoor key */
-
-/*
- * DBE Timing Tables
- */
-
-#ifdef INCLUDE_TIMING_TABLE_DATA
-struct dbe_timing_info dbeVTimings[] = {
-  {
-    DBE_VT_640_480_60,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,  	640,			480,		59940,			25175,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    800,	640,		    800,		656,	    	752,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    525,	480,		    525,		490,		    492,
-    /*	pll_m,	pll_n,			pll_p */
-    15,	    2,				3
-  },
-
-  {
-    DBE_VT_800_600_60,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    800,			600,		60317,			40000,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1056,	800,		    1056,		840,		    968,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    628,	600,		    628,		601,		    605,
-    /*	pll_m,	pll_n,			pll_p */
-    3,	    1,				1
-  },
-
-  {
-    DBE_VT_800_600_75,
-    /*	flags,	width,		    height,		fields_sec,	    cfreq */
-    0,	    800,		    600,		75000,		    49500,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1056,	800,		    1056,		816,		    896,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    625,	600,		    625,		601,		    604,
-    /*	pll_m,	pll_n,		    pll_p */
-    11,	    3,		        1
-  },
-
-  {
-    DBE_VT_800_600_120,
-    /*	flags,					width,		height,			fields_sec,	    cfreq */
-    DBE_VOF_STEREO,	    800,		600,			119800,		    82978,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1040,	800,		    1040,		856,		    976,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    666,	600,		    666,		637,		    643,
-    /*	pll_m,	pll_n,		    pll_p */
-    31,	    5,		        1
-  },
-
-  {
-    DBE_VT_1024_768_50,
-    /*	flags,	width,		    height,		fields_sec,	    cfreq */
-    0,	    1024,		    768,		50000,		    54163,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1344,	1024,		    1344,		1048,		    1184,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    806,	768,		    806,		771,		    777,
-    /*	pll_m,	pll_n,		    pll_p */
-    4,	    1,		        1
-  },
-
-  {
-    DBE_VT_1024_768_60,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1024,			768,		60004,			65000,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1344,	1024,		    1344,		1048,		    1184,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    806,	768,		    806,		771,		    777,
-    /*	pll_m,	pll_n,			pll_p */
-    12,	    5,				0
-  },
-
-  {
-    DBE_VT_1024_768_75,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1024,			768,		75029,			78750,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1312,	1024,		    1312,		1040,		    1136,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    800,	768,		    800,		769,		    772,
-    /*	pll_m,	pll_n,			pll_p */
-    29,	    5,				1
-  },
-
-  {
-    DBE_VT_1024_768_85,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1024,			768,		84997,			94500,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1376,	1024,		    1376,		1072,		    1168,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    808,	768,		    808,		769,		    772,
-    /*	pll_m,	pll_n,			pll_p */
-    7,	    2,				0
-  },
-
-  {
-    DBE_VT_1024_768_120,
-    /*	flags,					width,		height,			fields_sec,		cfreq */
-    DBE_VOF_STEREO,	    1024,		768,			119800,			133195,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1376,	1024,		    1376,		1072,		    1168,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    808,	768,		    808,		769,		    772,
-    /*	pll_m,	pll_n,			pll_p */
-    5,	    1,				0
-  },
-
-  {
-    DBE_VT_1280_1024_50,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1280,			1024,		50000,			89460,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1680,	1280,		    1680,		1360,		    1480,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    1065,	1024,		    1065,		1027,		    1030,
-    /*	pll_m,	pll_n,			pll_p */
-    10,	    3,				0
-  },
-
-  {
-    DBE_VT_1280_1024_60,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1280,			1024,		60020,			108000,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1688,	1280,		    1688,		1328,		    1440,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    1066,	1024,		    1066,		1025,		    1028,
-    /*	pll_m,	pll_n,			pll_p */
-    4,	    1,			    0
-  },
-
-  {
-    DBE_VT_1280_1024_75,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1280,			1024,		75025,			135000,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1688,	1280,		    1688,		1296,		    1440,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    1066,	1024,		    1066,		1025,		    1028,
-    /*	pll_m,	pll_n,			pll_p */
-    5,	    1,				0
-  },
-
-  {
-    DBE_VT_1280_1024_85,
-    /*	flags,	width,		    height,		fields_sec,	    cfreq */
-    0,	    1280,		    1024,		85024,		    157500,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1728,	1280,		    1728,		1344,		    1504,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    1072,	1024,		    1072,		1025,		    1028,
-    /*	pll_m,	pll_n,		    pll_p */
-    29,	    5,		        0
-  },
-
-  {
-    DBE_VT_1600_1024_53,
-    /* flags,	width,			height,		fields_sec,     cfreq */
-    DBE_VOF_FLATPANEL | DBE_VOF_MAGICKEY,
-    1600,			1024,		53000,			107447,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    1900,   1600,           1900,           1630,           1730,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1067,   1024,           1067,           1027,           1030,
-    /* pll_m,  pll_n,          pll_p */
-    4,      1,              0
-  },
-
-  {
-    DBE_VT_1600_1024_60,
-    /* flags,					width,          height,			fields_sec,     cfreq */
-    DBE_VOF_FLATPANEL,   1600,           1024,			60000,          106913,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    1670,   1600,           1670,           1630,           1650,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1067,   1024,           1067,           1027,           1030,
-    /* pll_m,  pll_n,          pll_p */
-    4,      1,              0
-  },
-
-  {
-    DBE_VT_1600_1200_50,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1600,           1200,           50000,          130500,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2088,   1600,           2088,           1644,           1764,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1205,           1211,
-    /* pll_m,  pll_n,          pll_p */
-    24,     5,              0
-  },
-
-  {
-    DBE_VT_1600_1200_60,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1600,           1200,           59940,          162000,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2160,   1600,           2160,           1644,           1856,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1201,           1204,
-    /* pll_m,  pll_n,          pll_p */
-    6,		1,              0
-  },
-
-  {
-    DBE_VT_1600_1200_75,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1600,           1200,           75000,          202500,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2160,   1600,           2160,           1644,           1856,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1201,           1204,
-    /* pll_m,  pll_n,          pll_p */
-    15,		2,              0
-  },
-
-  {
-    DBE_VT_1920_1080_50,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1080,           50000,          133200,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2368,   1920,           2368,           1952,           2096,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1125,   1080,           1125,           1083,           1086,
-    /* pll_m,  pll_n,          pll_p */
-    5,      1,              0
-  },
-
-  {
-    DBE_VT_1920_1080_60,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1080,           59940,          159840,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2368,   1920,           2368,           1952,           2096,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1125,   1080,           1125,           1083,           1086,
-    /* pll_m,  pll_n,          pll_p */
-    6,      1,              0
-  },
-
-  {
-    DBE_VT_1920_1080_72,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1080,           72000,          216023,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2560,   1920,           2560,           1968,           2184,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1172,   1080,           1172,           1083,           1086,
-    /* pll_m,  pll_n,          pll_p */
-    8,      1,              0
-  },
-
-  {
-    DBE_VT_1920_1200_50,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1200,           50000,          161500,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2584,   1920,           2584,           1984,           2240,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1203,           1206,
-    /* pll_m,  pll_n,          pll_p */
-    6,      1,              0
-  },
-	
-  {
-    DBE_VT_1920_1200_60,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1200,           59940,          193800,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2584,   1920,           2584,           1984,           2240,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1203,           1206,
-    /* pll_m,  pll_n,          pll_p */
-    29,     4,              0
-  },
-
-  {
-    DBE_VT_1920_1200_66,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1200,           66000,          213180,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2584,   1920,           2584,           1984,           2240,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1203,           1206,
-    /* pll_m,  pll_n,          pll_p */
-    8,      1,              0
-  }
-};
-
-#define DBE_VT_SIZE  (sizeof(dbeVTimings)/sizeof(dbeVTimings[0]))
-#endif // INCLUDE_TIMING_TABLE_DATA
-
-#endif // ! __SGIVWFB_H__
diff -Nru a/drivers/video/sis/300vtbl.h b/drivers/video/sis/300vtbl.h
--- a/drivers/video/sis/300vtbl.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/sis/300vtbl.h	Wed Jul 24 14:03:36 2002
@@ -1,4 +1,10 @@
-typedef struct _SiS300_StStruct {
+
+
+/* Register settings for SiS 300 series */
+
+
+typedef struct _SiS300_StStruct
+{
 	UCHAR St_ModeID;
 	USHORT St_ModeFlag;
 	UCHAR St_StTableIndex;
@@ -9,31 +15,33 @@
 	UCHAR VB_StTVYFilterIndex;
 } SiS300_StStruct;
 
-SiS300_StStruct SiS300_SModeIDTable[] =
+SiS300_StStruct  SiS300_SModeIDTable[]=
 {
-	{0x01, 0x9208, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x01, 0x1210, 0x14, 0x01, 0x01, 0x00, 0x00, 0x00},
-	{0x01, 0x1010, 0x17, 0x02, 0x02, 0x00, 0x00, 0x00},
-	{0x03, 0x8208, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x03, 0x0210, 0x16, 0x01, 0x01, 0x00, 0x00, 0x00},
-	{0x03, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x00, 0x00},
-	{0x05, 0x9209, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x06, 0x8209, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x07, 0x0000, 0x07, 0x03, 0x03, 0x00, 0x00, 0x00},
-	{0x07, 0x0000, 0x19, 0x02, 0x02, 0x00, 0x00, 0x00},
-	{0x0d, 0x920a, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x0e, 0x820a, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x0f, 0x0202, 0x11, 0x01, 0x01, 0x00, 0x00, 0x00},
-	{0x10, 0x0212, 0x12, 0x01, 0x01, 0x00, 0x00, 0x00},
-	{0x11, 0x0212, 0x1a, 0x04, 0x04, 0x00, 0x00, 0x00},
-	{0x12, 0x0212, 0x1b, 0x04, 0x04, 0x00, 0x00, 0x00},
-	{0x13, 0x021b, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x12, 0x0210, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x12, 0x0210, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00},
-	{0xff, 0, 0, 0, 0, 0, 0, 0}
+	{0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00},
+	{0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00},
+	{0x01,0x1010,0x17,0x02,0x02,0x00,0x00,0x00},
+	{0x03,0x8208,0x03,0x00,0x00,0x00,0x00,0x00},
+	{0x03,0x0210,0x16,0x01,0x01,0x00,0x00,0x00},
+	{0x03,0x0010,0x18,0x02,0x02,0x00,0x00,0x00},
+	{0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x00},
+	{0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x00},
+	{0x07,0x0000,0x07,0x03,0x03,0x00,0x00,0x00},
+	{0x07,0x0000,0x19,0x02,0x02,0x00,0x00,0x00},
+	{0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x00},
+	{0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x00},
+	{0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x00},
+	{0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x00},
+	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00},
+	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00},
+	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00},
+	/* {0x12,0x0210,0x18,0x00,0x00,0x00,0x00,0x00}, */  /* <--- Different in BIOS */
+	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00},
+	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00},
+	{0xff,0,0,0,0,0,0,0}
 };
 
-typedef struct _SiS300_StandTableStruct {
+typedef struct _SiS300_StandTableStruct
+{
 	UCHAR CRT_COLS;
 	UCHAR ROWS;
 	UCHAR CHAR_HEIGHT;
@@ -45,362 +53,364 @@
 	UCHAR GRC[9];
 } SiS300_StandTableStruct;
 
-SiS300_StandTableStruct SiS300_StandTable[] = {
-	{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}},
-	{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}},
-	{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}},
-	{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}},
-	{0x28, 0x18, 0x08, 0x4000,
-	 {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,
-	 {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,
-	 {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,
-	 {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}},
+SiS300_StandTableStruct  SiS300_StandTable[]=
+{ /* TW: @ 0x38d4 in BIOS */
+ {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} },
+ {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} },
+ {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} },
+ {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} },
+ {0x28,0x18,0x08,0x4000,
+  {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,
+  {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,
+  {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,
+  {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,
-	 {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}},
+ {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} },
 /* 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}},
+ {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} },
 /* 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}},
+ {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} },
 /* 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}},
-	{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}},
-	{0x28, 0x18, 0x08, 0x2000,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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,
-	 {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}}
+ {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} },
+ {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} },
+ {0x28,0x18,0x08,0x2000,
+  {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,
+  {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,	/* TW: Standtable for VGA modes */
+  {0x01,0x0f,0x00,0x0e},	/*    (identical to BIOS) */
+  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,
+  {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,
+  {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,
+  {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,
+  {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,
+  {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,
+  {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,
+  {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,
+  {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,
+  {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,
+  {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,
+  {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,
+  {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,
+  {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 {
+typedef struct _SiS300_ExtStruct
+{
 	UCHAR Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
@@ -413,502 +423,594 @@
 	UCHAR VB_ExtTVYFilterIndex;
 	UCHAR REFindex;
 } SiS300_ExtStruct;
-SiS300_ExtStruct SiS300_EModeIDTable[] = {
-	{0x6a, 0x2212, 0x47, 0x3563, 0x0102, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00},
-	{0x2e, 0x0a1b, 0x36, 0x3539, 0x0101, 0x08, 0x06, 0x00, 0x00, 0x00, 0x08},
-	{0x2f, 0x021b, 0x35, 0x3532, 0x0100, 0x08, 0x05, 0x00, 0x00, 0x00, 0x10},
-	{0x30, 0x2a1b, 0x47, 0x3563, 0x0103, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00},
-	{0x31, 0x0a1b, 0xad, 0x3630, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x11},
-	{0x32, 0x2a1b, 0xae, 0x3637, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x00, 0x12},
-	{0x33, 0x0a1d, 0xad, 0x3630, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x11},
-	{0x34, 0x2a1d, 0xae, 0x3637, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x00, 0x12},
-	{0x35, 0x0a1f, 0xad, 0x3630, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x11},
-	{0x36, 0x2a1f, 0xae, 0x3637, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x00, 0x12},
-	{0x37, 0x0212, 0x58, 0x358d, 0x0104, 0x08, 0x08, 0x00, 0x00, 0x00, 0x13},
-	{0x38, 0x0a1b, 0x58, 0x358d, 0x0105, 0x08, 0x08, 0x00, 0x00, 0x00, 0x13},
-	{0x3a, 0x0e3b, 0x69, 0x35be, 0x0107, 0x08, 0x09, 0x00, 0x00, 0x00, 0x1a},
-	{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},
-	{0x47, 0x2a1d, 0x47, 0x3563, 0x0114, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00},
-	{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, 0x921b, 0x13, 0x3524, 0x0133, 0x08, 0x03, 0x00, 0x00, 0x00, 0x25},
-	{0x52, 0x921b, 0x24, 0x352b, 0x0134, 0x08, 0x04, 0x00, 0x00, 0x00, 0x26},
-	{0x56, 0x921d, 0x01, 0x351d, 0x0135, 0x08, 0x01, 0x00, 0x00, 0x00, 0x24},
-	{0x57, 0x921d, 0x13, 0x3524, 0x0136, 0x08, 0x03, 0x00, 0x00, 0x00, 0x25},
-	{0x58, 0x921d, 0x24, 0x352b, 0x0137, 0x08, 0x04, 0x00, 0x00, 0x00, 0x26},
-	{0x59, 0x921b, 0x00, 0x3516, 0x0138, 0x08, 0x00, 0x00, 0x00, 0x00, 0x23},
-	{0x5d, 0x021d, 0x35, 0x3532, 0x0139, 0x08, 0x05, 0x00, 0x00, 0x00, 0x10},
-	{0x62, 0x0a3f, 0x36, 0x3539, 0x013a, 0x08, 0x06, 0x00, 0x00, 0x00, 0x08},
-	{0x63, 0x2a3f, 0x47, 0x3563, 0x013b, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00},
-	{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, 0x0c, 0x00, 0x00, 0x00, 0x28},
-	{0x6d, 0x06fd, 0x9c, 0x35f6, 0x0000, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x28},
-	{0x6e, 0x0e3b, 0x6f, 0x35b2, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x00, 0x29},
-	{0x6f, 0x0e7d, 0x6f, 0x35b2, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x00, 0x29},
-	{0x7b, 0x0eff, 0x6f, 0x35b2, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x00, 0x29},
-	{0x7c, 0x221b, 0xb3, 0x363e, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x2b},
-	{0x7d, 0x221d, 0xb3, 0x363e, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x2b},
-	{0x7e, 0x223f, 0xb3, 0x363e, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x2b},
-	{0xff, 0x0000, 0x00, 0x0000, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+SiS300_ExtStruct  SiS300_EModeIDTable[]=
+{
+	{0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */  /* 800x600x? */
+	{0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
+	{0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10},  /* 37bc */
+	{0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
+	{0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 38ba */ /* 720x480x8 */
+	{0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 38c1 */ /* 720x576x8 */
+	{0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 38ba */ /* 720x480x16 */
+	{0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 38c1 */ /* 720x576x16 */
+	{0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 38ba */ /* 720x480x32 */
+	{0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 38c1 */ /* 720x576x32 */
+	{0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */ /* 1024x768x? */
+	{0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */ /* 1024x768x8 */
+	{0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */ /* 1280x1024x8 */
+	{0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},  /* 385e */
+	{0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},  /* 385e */
+	{0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23},  /* 37a0 */
+	{0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23},  /* 37a0 */
+	{0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
+	{0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
+	{0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
+	{0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
+	{0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */
+	{0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */
+	{0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */
+	{0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */
+	{0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24},  /* 37a7 */
+	{0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25},  /* 37ae */
+	{0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26},  /* 37b5 */
+	{0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24},  /* 37a7 */
+	{0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25},  /* 37ae */
+	{0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26},  /* 37b5 */
+	{0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23},  /* 37a0 */
+	{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},  /* 37bc */
+	{0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
+	{0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
+	{0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */
+	{0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */
+	{0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},  /* 385e */
+	{0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27},  /* 3879 */
+	{0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27},  /* 3879 */
+	{0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27},  /* 3879 */
+	{0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x0c,0x00,0x00,0x00,0x28},  /* 3880 */
+	{0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x0c,0x00,0x00,0x00,0x28},  /* 3880 */
+	{0x6e,0x0e3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 383c */  /* 1280x960x8 */
+	{0x6f,0x0e7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 383c */  /* 1280x960x16 */
+	{0x7b,0x0eff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 383c */  /* 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},
+	{0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS300_Ext2Struct {
+typedef struct _SiS300_Ext2Struct
+{
 	USHORT Ext_InfoFlag;
-	UCHAR Ext_CRT1CRTC;
+	UCHAR Ext_CRT1CRTC;  /* TW: Index in SiS300_CRT1Table */
 	UCHAR Ext_CRTVCLK;
-	UCHAR Ext_CRT2CRTC;
-	UCHAR ModeID;
+	UCHAR Ext_CRT2CRTC;  /* TW: Index in LCD Paneltype arrays (&3f) */
+	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
 	USHORT ROM_OFFSET;
 } SiS300_Ext2Struct;
-SiS300_Ext2Struct SiS300_RefIndex[] = {
-	{0x085f, 0x0d, 0x03, 0x05, 0x6a, 800, 600, 0x3563},
-	{0x0467, 0x0e, 0x44, 0x05, 0x6a, 800, 600, 0x3568},
-	{0x0067, 0x4f, 0x07, 0x48, 0x6a, 800, 600, 0x356d},
-	{0x0067, 0x10, 0x06, 0x8b, 0x6a, 800, 600, 0x3572},
-	{0x0147, 0x11, 0x08, 0x00, 0x6a, 800, 600, 0x3577},
-	{0x0147, 0x12, 0x0c, 0x00, 0x6a, 800, 600, 0x357c},
-	{0x0047, 0x51, 0x4e, 0x00, 0x6a, 800, 600, 0x3581},
-	{0x0047, 0x11, 0x13, 0x00, 0x6a, 800, 600, 0x3586},
-	{0xc85f, 0x05, 0x00, 0x04, 0x2e, 640, 480, 0x3539},
-	{0xc067, 0x06, 0x02, 0x04, 0x2e, 640, 480, 0x353e},
-	{0xc067, 0x07, 0x02, 0x47, 0x2e, 640, 480, 0x3543},
-	{0xc067, 0x08, 0x03, 0x8a, 0x2e, 640, 480, 0x3548},
-	{0xc047, 0x09, 0x05, 0x00, 0x2e, 640, 480, 0x354d},
-	{0xc047, 0x0a, 0x08, 0x00, 0x2e, 640, 480, 0x3552},
-	{0xc047, 0x0b, 0x0a, 0x00, 0x2e, 640, 480, 0x3557},
-	{0xc047, 0x0c, 0x10, 0x00, 0x2e, 640, 480, 0x355c},
-	{0x487f, 0x04, 0x00, 0x00, 0x2f, 640, 400, 0x3532},
-	{0xc00f, 0x31, 0x01, 0x06, 0x31, 2048, 1536, 0x3630},
-	{0x000f, 0x32, 0x03, 0x06, 0x32, 720, 480, 0x3637},
-	{0x0187, 0x15, 0x05, 0x00, 0x37, 1024, 768, 0x358d},
-	{0xc877, 0x16, 0x09, 0x06, 0x37, 1024, 768, 0x3592},
-	{0xc067, 0x97, 0x0b, 0x49, 0x37, 1024, 768, 0x3597},
-	{0x0267, 0x18, 0x0d, 0x00, 0x37, 1024, 768, 0x359c},
-	{0x0047, 0x59, 0x11, 0x8c, 0x37, 1024, 768, 0x35a1},
-	{0x0047, 0x1a, 0x52, 0x00, 0x37, 1024, 768, 0x35a6},
-	{0x0047, 0x5b, 0x16, 0x00, 0x37, 1024, 768, 0x35ab},
-	{0x0387, 0x5c, 0x4d, 0x00, 0x3a, 1280, 1024, 0x35be},
-	{0x0077, 0x1d, 0x14, 0x07, 0x3a, 1280, 1024, 0x35c3},
-	{0x0047, 0x1e, 0x17, 0x00, 0x3a, 1280, 1024, 0x35c8},
-	{0x0007, 0x1f, 0x98, 0x00, 0x3a, 1280, 1024, 0x35cd},
-	{0x0007, 0x60, 0x59, 0x00, 0x3c, 1600, 1200, 0x35d4},
-	{0x0007, 0x21, 0x5a, 0x00, 0x3c, 1600, 1200, 0x35d9},
-	{0x0007, 0x22, 0x1b, 0x00, 0x3c, 1600, 1200, 0x35de},
-	{0x0007, 0x63, 0x1d, 0x00, 0x3c, 1600, 1200, 0x35e3},
-	{0x0007, 0x24, 0x1e, 0x00, 0x3c, 1600, 1200, 0x35e8},
-	{0x407f, 0x00, 0x00, 0x00, 0x40, 320, 200, 0x3516},
-	{0xc07f, 0x01, 0x00, 0x04, 0x50, 320, 240, 0x351d},
-	{0x0077, 0x02, 0x04, 0x05, 0x51, 400, 300, 0x3524},
-	{0xc077, 0x03, 0x09, 0x06, 0x52, 512, 384, 0x352b},
-	{0x8207, 0x25, 0x1f, 0x00, 0x68, 1920, 1440, 0x35ef},
-	{0x0007, 0x26, 0x20, 0x00, 0x6c, 2048, 1536, 0x35f6},
-	{0x0027, 0x27, 0x14, 0x08, 0x6e, 720, 576, 0x35b2},
-	{0x0027, 0x27, 0x14, 0x08, 0x6e, 720, 576, 0x35b7},
-	{0x00df, 0x33, 0x28, 0x00, 0x7c, 1280, 960, 0x363e},
-	{0xc05f, 0x34, 0x28, 0x00, 0x7c, 1280, 960, 0x3643},
-	{0xffff, 0, 0, 0, 0, 0, 0, 0}
+
+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,0x4f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 */
+	{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,0x51,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 */
+	{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,0x97,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 */
+	{0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c}, /* 16 */
+	{0x0047,0x59,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 */
+	{0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6}, /* 18 */
+	{0x0047,0x5b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 */
+	{0x0387,0x5c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a */
+	{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,0x60,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e */
+	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9}, /* 1f */
+	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de}, /* 20 */
+	{0x0007,0x63,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 */
+	{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 */
+	{0xc077,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */   
+	{0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef}, /* 27 */
+	{0x0007,0x26,0x20,0x00,0x6c, 720, 480,0x35f6}, /* 28 */
+	{0x0027,0x27,0x14,0x08,0x6e,1280, 960,0x35b2}, /* 29 */
+	{0x0027,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 2a */
+	{0xc077,0x33,0x09,0x06,0x20,1024, 600,0x0000}, /* 2b */
+	{0xc077,0x34,0x09,0x06,0x23,1152, 768,0x0000}, /* 2c */
+	{0xffff,0,0,0,0,0,0,0}
 };
 
 /*add for 300 oem util*/
-typedef struct _SiS_VBModeIDTableStruct {
-	UCHAR ModeID;
-	UCHAR VB_TVDelayIndex;
-	UCHAR VB_TVFlickerIndex;
-	UCHAR VB_TVPhaseIndex;
-	UCHAR VB_TVYFilterIndex;
-	UCHAR VB_LCDDelayIndex;
-	UCHAR _VB_LCDHIndex;
-	UCHAR _VB_LCDVIndex;
-} SiS_VBModeIDTableStruct;
-SiS_VBModeIDTableStruct SiS300_VBModeIDTable[] = {
-	{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
-	{0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02},
-	{0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00},
-	{0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01},
-	{0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x02},
-	{0x05, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00},
-	{0x06, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x00},
-	{0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x01},
-	{0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x02},
-	{0x0d, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00},
-	{0x0e, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x00},
-	{0x0f, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x01},
-	{0x10, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x01},
-	{0x11, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x03},
-	{0x12, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x03},
-	{0x13, 0x00, 0x00, 0x01, 0x04, 0x00, 0x04, 0x00},
-	{0x6a, 0x00, 0x00, 0x01, 0x07, 0x00, 0x08, 0x0a},
-	{0x2e, 0x00, 0x00, 0x01, 0x05, 0x00, 0x06, 0x08},
-	{0x2f, 0x00, 0x00, 0x01, 0x05, 0x00, 0x06, 0x06},
-	{0x30, 0x00, 0x00, 0x01, 0x07, 0x00, 0x08, 0x0a},
-	{0x31, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00},
-	{0x32, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00},
-	{0x37, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0c},
-	{0x38, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0c},
-	{0x3a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x40, 0x00, 0x00, 0x01, 0x04, 0x00, 0x05, 0x05},
-	{0x41, 0x00, 0x00, 0x01, 0x04, 0x00, 0x05, 0x05},
-	{0x43, 0x00, 0x00, 0x01, 0x05, 0x00, 0x06, 0x08},
-	{0x44, 0x00, 0x00, 0x01, 0x05, 0x00, 0x06, 0x08},
-	{0x46, 0x00, 0x00, 0x01, 0x07, 0x00, 0x08, 0x0a},
-	{0x47, 0x00, 0x00, 0x01, 0x07, 0x00, 0x08, 0x0a},
-	{0x49, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0c},
-	{0x4a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0c},
-	{0x4c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x4d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x50, 0x00, 0x00, 0x01, 0x04, 0x00, 0x05, 0x07},
-	{0x51, 0x00, 0x00, 0x01, 0x07, 0x00, 0x07, 0x09},
-	{0x52, 0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0x0b},
-	{0x56, 0x00, 0x00, 0x01, 0x04, 0x00, 0x05, 0x07},
-	{0x57, 0x00, 0x00, 0x01, 0x07, 0x00, 0x07, 0x09},
-	{0x58, 0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0x0b},
-	{0x59, 0x00, 0x00, 0x01, 0x04, 0x00, 0x05, 0x05},
-	{0x5d, 0x00, 0x00, 0x01, 0x07, 0x00, 0x06, 0x06},
-	{0x62, 0x00, 0x00, 0x01, 0x05, 0x00, 0x06, 0x08},
-	{0x63, 0x00, 0x00, 0x01, 0x07, 0x00, 0x08, 0x0a},
-	{0x64, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0c},
-	{0x65, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x6e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x6f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x7b, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d}
+typedef struct _SiS_VBModeIDTableStruct
+{
+	UCHAR  ModeID;
+	UCHAR  VB_TVDelayIndex;
+	UCHAR  VB_TVFlickerIndex;
+	UCHAR  VB_TVPhaseIndex;
+	UCHAR  VB_TVYFilterIndex;
+	UCHAR  VB_LCDDelayIndex;
+	UCHAR  _VB_LCDHIndex;
+	UCHAR  _VB_LCDVIndex;
+}SiS_VBModeIDTableStruct;
+
+SiS_VBModeIDTableStruct  SiS300_VBModeIDTable[]=
+{
+	{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* TW: Identical to 630/301B BIOS */
+	{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+	{0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x02},
+	{0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x00},
+	{0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x01},
+	{0x03,0x00,0x00,0x00,0x03,0x00,0x03,0x02},
+	{0x05,0x00,0x00,0x01,0x04,0x00,0x00,0x00},
+	{0x06,0x00,0x00,0x01,0x05,0x00,0x02,0x00},
+	{0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x01},
+	{0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x02},
+	{0x0d,0x00,0x00,0x01,0x04,0x00,0x00,0x00},
+	{0x0e,0x00,0x00,0x01,0x05,0x00,0x02,0x00},
+	{0x0f,0x00,0x00,0x01,0x05,0x00,0x02,0x01},
+	{0x10,0x00,0x00,0x01,0x05,0x00,0x02,0x01},
+	{0x11,0x00,0x00,0x01,0x05,0x00,0x02,0x03},
+	{0x12,0x00,0x00,0x01,0x05,0x00,0x02,0x03},
+	{0x13,0x00,0x00,0x01,0x04,0x00,0x04,0x00},
+	{0x6a,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+	{0x2e,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+	{0x2f,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
+	{0x30,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+	{0x31,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+	{0x32,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+	{0x37,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+	{0x38,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+	{0x3a,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x40,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
+	{0x41,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
+	{0x43,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+	{0x44,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+	{0x46,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+	{0x47,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+	{0x49,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+	{0x4a,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+	{0x4c,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x4d,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x50,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
+	{0x51,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
+	{0x52,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
+	{0x56,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
+	{0x57,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
+	{0x58,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
+	{0x59,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
+	{0x5d,0x00,0x00,0x01,0x07,0x00,0x06,0x06},
+	{0x62,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+	{0x63,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+	{0x64,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+	{0x65,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{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! */
 };
 /*end*/
 
-typedef struct _SiS300_CRT1TableStruct {
+typedef struct _SiS300_CRT1TableStruct
+{
 	UCHAR CR[17];
 } SiS300_CRT1TableStruct;
-SiS300_CRT1TableStruct SiS300_CRT1Table[] = {
-	{{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	  0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x04,
-	  0x00}},
-	{{0x3d, 0x31, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x05,
-	  0x01}},
-	{{0x4f, 0x3f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x01,
-	  0x01}},
-	{{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x63, 0x4f, 0x50, 0x86, 0x56, 0x9b, 0x06, 0x3e,
-	  0xe8, 0x8b, 0xdf, 0xe7, 0xff, 0x10, 0x00, 0x01,
-	  0x00}},
-	{{0x64, 0x4f, 0x4f, 0x88, 0x55, 0x9d, 0xf2, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xf3, 0x10, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x4f, 0x87, 0x5a, 0x81, 0xfb, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x66, 0x4f, 0x4f, 0x86, 0x56, 0x9e, 0x03, 0x3e,
-	  0xe4, 0x87, 0xdf, 0xdf, 0x04, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x6c, 0x4f, 0x4f, 0x83, 0x59, 0x9e, 0x00, 0x3e,
-	  0xe5, 0x8d, 0xdf, 0xdf, 0x01, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x4f, 0x87, 0x56, 0x9d, 0xfb, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x01,
-	  0x00}},
-	{{0x65, 0x4f, 0x4f, 0x89, 0x57, 0x9f, 0xfb, 0x1f,
-	  0xe6, 0x8a, 0xe5, 0xe5, 0xfc, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x7b, 0x63, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	  0x58, 0x8a, 0x57, 0x57, 0x70, 0x20, 0x00, 0x05,
-	  0x01}},
-	{{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x06,
-	  0x01}},
-	{{0x7d, 0x63, 0x63, 0x81, 0x6e, 0x1d, 0x98, 0xf0,
-	  0x7c, 0x82, 0x57, 0x57, 0x99, 0x00, 0x00, 0x06,
-	  0x01}},
-	{{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x70, 0x20, 0x00, 0x06,
-	  0x01}},
-	{{0x7e, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06,
-	  0x01}},
-	{{0x8c, 0x63, 0x63, 0x87, 0x72, 0x16, 0x7e, 0xf0,
-	  0x59, 0x8d, 0x57, 0x57, 0x7f, 0x00, 0x00, 0x06,
-	  0x01}},
-	{{0x7e, 0x63, 0x63, 0x82, 0x6c, 0x14, 0x75, 0xe0,
-	  0x58, 0x0b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06,
-	  0x01}},
-	{{0x7e, 0x63, 0x63, 0x82, 0x6c, 0x14, 0x75, 0xe0,
-	  0x58, 0x0b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06,
-	  0x01}},
-	{{0x99, 0x7f, 0x7f, 0x9d, 0x84, 0x1a, 0x96, 0x1f,
-	  0x7f, 0x83, 0x7f, 0x7f, 0x97, 0x10, 0x00, 0x02,
-	  0x00}},
-	{{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0xa1, 0x7f, 0x7f, 0x85, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x1f, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0xa7, 0x7f, 0x7f, 0x8b, 0x89, 0x95, 0x26, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x27, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0x9f, 0x7f, 0x7f, 0x83, 0x83, 0x93, 0x1e, 0xf5,
-	  0x00, 0x84, 0xff, 0xff, 0x1f, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0xa2, 0x7f, 0x7f, 0x86, 0x84, 0x94, 0x37, 0xf5,
-	  0x0b, 0x82, 0xff, 0xff, 0x38, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0xcf, 0x9f, 0x9f, 0x93, 0xb2, 0x01, 0x14, 0xba,
-	  0x00, 0x83, 0xff, 0xff, 0x15, 0x00, 0x00, 0x03,
-	  0x00}},
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	  0x01}},
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	  0x01}},
-	{{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x2f, 0x09, 0x00, 0x07,
-	  0x01}},
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},
-	{{0x3f, 0xef, 0xef, 0x83, 0xfd, 0x1a, 0xda, 0x1f,
-	  0xa0, 0x84, 0x9f, 0x9f, 0xdb, 0x1f, 0x01, 0x01,
-	  0x00}},
-	{{0x55, 0xff, 0xff, 0x99, 0x0d, 0x0c, 0x3e, 0xba,
-	  0x00, 0x84, 0xff, 0xff, 0x3f, 0x0f, 0x41, 0x05,
-	  0x00}},
-	{{0xdc, 0x9f, 0x9f, 0x00, 0xab, 0x19, 0xe6, 0xef,
-	  0xc0, 0xc3, 0xbf, 0xbf, 0xe7, 0x10, 0x00, 0x07,
-	  0x01}},
-	{{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xba,
-	  0x27, 0x8b, 0xdf, 0xdf, 0x73, 0x00, 0x00, 0x06,
-	  0x01}},
-	{{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xba,
-	  0x26, 0x89, 0xdf, 0xdf, 0x6f, 0x00, 0x00, 0x06,
-	  0x01}},
-	{{0x7f, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xba,
-	  0x29, 0x8c, 0xdf, 0xdf, 0x75, 0x00, 0x00, 0x06,
-	  0x01}},
-	{{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf1,
-	  0xaf, 0x85, 0x3f, 0x3f, 0x25, 0x30, 0x00, 0x02,
-	  0x01}},
-	{{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf1,
-	  0xad, 0x81, 0x3f, 0x3f, 0x1f, 0x30, 0x00, 0x02,
-	  0x01}},
-	{{0xa7, 0x7f, 0x7f, 0x88, 0x89, 0x15, 0x26, 0xf1,
-	  0xb1, 0x85, 0x3f, 0x3f, 0x27, 0x30, 0x00, 0x02,
-	  0x01}},
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0xc4,
-	  0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	  0x01}},
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0xd4,
-	  0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	  0x01}},
-	{{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0xd4,
-	  0x7d, 0x81, 0xcf, 0xcf, 0x2f, 0x21, 0x00, 0x07,
-	  0x01}},
-	{{0x6b, 0x59, 0x59, 0x8f, 0x5e, 0x8c, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x7b, 0x59, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	  0x58, 0x8a, 0x3f, 0x57, 0x70, 0x20, 0x00, 0x05,
-	  0x01}},
-	{{0x86, 0x6a, 0x6a, 0x8a, 0x74, 0x06, 0x8c, 0x15,
-	  0x4f, 0x83, 0xef, 0xef, 0x8d, 0x30, 0x00, 0x02,
-	  0x00}},
-	{{0x81, 0x6a, 0x6a, 0x85, 0x70, 0x00, 0x0f, 0x3e,
-	  0xeb, 0x8e, 0xdf, 0xdf, 0x10, 0x00, 0x00, 0x02,
-	  0x00}}
+
+SiS300_CRT1TableStruct  SiS300_CRT1Table[]=
+{
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,    /* 0x00 */
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+  0x00}},
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+  0x00}},
+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+  0x01}},
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+  0x01}},
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
+  0x00}},
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+  0x00}},
+ {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
+  0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
+  0x00}},
+ {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
+  0x00}},
+ {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
+  0x00}},
+ {{0x66,0x4f,0x4f,0x86,0x56,0x9e,0x03,0x3e,
+  0xe4,0x87,0xdf,0xdf,0x04,0x00,0x00,0x01,
+  0x00}},
+ {{0x6c,0x4f,0x4f,0x83,0x59,0x9e,0x00,0x3e,    /* 0x0a */
+  0xe5,0x8d,0xdf,0xdf,0x01,0x00,0x00,0x01,
+  0x00}},
+ {{0x63,0x4f,0x4f,0x87,0x56,0x9d,0xfb,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x01,
+  0x00}},
+ {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
+  0xe6,0x8a,0xe5,0xe5,0xfc,0x00,0x00,0x01,
+  0x00}},
+ {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+  0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
+  0x01}},
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
+  0x01}},
+ {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
+  0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
+  0x01}},
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
+  0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
+  0x01}},
+ {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
+  0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
+  0x01}},
+ {{0x8c,0x63,0x63,0x87,0x72,0x16,0x7e,0xf0,
+  0x59,0x8d,0x57,0x57,0x7f,0x00,0x00,0x06,
+  0x01}},
+ {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0,
+  0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06,
+  0x01}},
+ {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0,   /* 0x14 */
+  0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06,
+  0x01}},
+ {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
+  0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
+  0x00}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}},
+ {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
+  0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
+  0x01}},
+ {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
+  0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
+  0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x83,0x93,0x1e,0xf5,
+  0x00,0x84,0xff,0xff,0x1f,0x10,0x00,0x02,
+  0x01}},
+ {{0xa2,0x7f,0x7f,0x86,0x84,0x94,0x37,0xf5,
+  0x0b,0x82,0xff,0xff,0x38,0x10,0x00,0x02,
+  0x01}},
+ {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
+  0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
+  0x00}},
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
+  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+  0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,  /* 0x1e */
+  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+  0x01}},
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
+  0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
+  0x01}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,  /* 36: 1600x1200x85Hz */
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}},
+ {{0x3f,0xef,0xef,0x83,0xfd,0x1a,0xda,0x1f,  /* 37: 1920x1440x60Hz */
+  0xa0,0x84,0x9f,0x9f,0xdb,0x1f,0x01,0x01,
+  0x00}},
+ {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
+  0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
+  0x00}},
+ {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,
+  0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+  0x01}},
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x28 */
+  0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+  0x01}},
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+  0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+  0x01}},
+ {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+  0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+  0x01}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+  0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+  0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+  0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+  0x01}},
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
+  0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+  0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+  0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+  0x01}},
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+  0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+  0x01}},
+ {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+  0x00}},
+ {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,  /* 0x32 */
+  0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
+  0x01}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,  /* 0x33 - 1024x600 */
+  0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
+  0x01}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,  /* 0x34 - 1152x768 */
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}}
 };
 
-typedef struct _SiS300_MCLKDataStruct {
-	UCHAR SR28, SR29, SR2A;
+typedef struct _SiS300_MCLKDataStruct
+{
+	UCHAR SR28,SR29,SR2A;
 	USHORT CLOCK;
 } SiS300_MCLKDataStruct;
-SiS300_MCLKDataStruct SiS300_MCLKData[] = {
-	{0x5a, 0x64, 0x80, 66},
-	{0xb3, 0x45, 0x80, 83},
-	{0x37, 0x61, 0x80, 100},
-	{0x37, 0x22, 0x80, 133},
-	{0x37, 0x61, 0x80, 100},
-	{0x37, 0x61, 0x80, 100},
-	{0x37, 0x61, 0x80, 100},
-	{0x37, 0x61, 0x80, 100}
+
+SiS300_MCLKDataStruct  SiS300_MCLKData[]=
+{ /* TW: at 0x54 in BIOS */
+	{ 0x5a,0x64,0x80, 66},
+	{ 0xb3,0x45,0x80, 83},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x22,0x80,133},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x61,0x80,100}
 };
 
-typedef struct _SiS300_ECLKDataStruct {
-	UCHAR SR2E, SR2F, SR30;
+typedef struct _SiS300_ECLKDataStruct
+{
+	UCHAR SR2E,SR2F,SR30;
 	USHORT CLOCK;
 } SiS300_ECLKDataStruct;
-SiS300_ECLKDataStruct SiS300_ECLKData[] = {
-	{0x54, 0x43, 0x80, 100},
-	{0x53, 0x43, 0x80, 100},
-	{0x55, 0x43, 0x80, 100},
-	{0x52, 0x43, 0x80, 100},
-	{0x3f, 0x42, 0x80, 100},
-	{0x54, 0x43, 0x80, 100},
-	{0x54, 0x43, 0x80, 100},
-	{0x54, 0x43, 0x80, 100}
+
+SiS300_ECLKDataStruct  SiS300_ECLKData[]=
+{
+	{ 0x54,0x43,0x80,100},
+	{ 0x53,0x43,0x80,100},
+	{ 0x55,0x43,0x80,100},
+	{ 0x52,0x43,0x80,100},
+	{ 0x3f,0x42,0x80,100},
+	{ 0x54,0x43,0x80,100},
+	{ 0x54,0x43,0x80,100},
+	{ 0x54,0x43,0x80,100}
 };
 
-typedef struct _SiS300_VCLKDataStruct {
-	UCHAR SR2B, SR2C;
+typedef struct _SiS300_VCLKDataStruct
+{
+	UCHAR SR2B,SR2C;
 	USHORT CLOCK;
 } SiS300_VCLKDataStruct;
-SiS300_VCLKDataStruct SiS300_VCLKData[] = {
-	{0x1b, 0xe1, 25},
-	{0x4e, 0xe4, 28},
-	{0x57, 0xe4, 32},
-	{0xc3, 0xc8, 36},
-	{0x42, 0xc3, 40},
-	{0x5d, 0xc4, 45},
-	{0x52, 0x65, 50},
-	{0x53, 0x65, 50},
-	{0x6d, 0x66, 56},
-	{0x5a, 0x64, 65},
-	{0x46, 0x44, 68},
-	{0x3e, 0x43, 75},
-	{0x6d, 0x46, 76},
-	{0x41, 0x43, 79},
-	{0x31, 0x42, 79},
-	{0x46, 0x25, 85},
-	{0x78, 0x29, 87},
-	{0x62, 0x44, 95},
-	{0x2b, 0x22, 105},
-	{0x49, 0x24, 106},
-	{0xc3, 0x28, 108},
-	{0x3c, 0x23, 109},
-	{0xf7, 0x2c, 132},
-	{0xd4, 0x28, 136},
-	{0x41, 0x05, 158},
-	{0x43, 0x05, 162},
-	{0xe1, 0x0f, 175},
-	{0xfc, 0x12, 189},
-	{0xde, 0x26, 194},
-	{0x54, 0x05, 203},
-	{0x3f, 0x03, 230},
-	{0x30, 0x02, 234},
-	{0x24, 0x01, 266},
-	{0x52, 0x2a, 54},
-	{0x52, 0x6a, 27},
-	{0x62, 0x24, 70},
-	{0x62, 0x64, 70},
-	{0xa8, 0x4c, 30},
-	{0x20, 0x26, 33},
-	{0x31, 0xc2, 39},
-	{0xbf, 0xc8, 35},
-	{0x60, 0x36, 30},
-	{0x40, 0x4a, 28},
-	{0x9f, 0x46, 44},
-	{0x97, 0x2c, 26},
-	{0x44, 0xe4, 25},
-	{0x7e, 0x32, 47},
-	{0x8a, 0x24, 31},
-	{0x97, 0x2c, 26},
-	{0xce, 0x3c, 39},
-	{0x52, 0x4a, 36},
-	{0x34, 0x61, 95},
-	{0x78, 0x27, 108},
-	{0xff, 0x1b, 6625}
+
+SiS300_VCLKDataStruct  SiS300_VCLKData[]=
+{
+	{ 0x1b,0xe1, 25},
+	{ 0x4e,0xe4, 28},
+	{ 0x57,0xe4, 32},
+	{ 0xc3,0xc8, 36},
+	{ 0x42,0xc3, 40},
+	{ 0x5d,0xc4, 45},
+	{ 0x52,0x65, 50},
+	{ 0x53,0x65, 50},
+	{ 0x6d,0x66, 56},
+	{ 0x5a,0x64, 65},
+	{ 0x46,0x44, 68},
+	{ 0x3e,0x43, 75},
+	{ 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH);  - LVDS2(CH), A901(301B): 0xb1,0x46, 76 */
+	{ 0x41,0x43, 79},
+	{ 0x31,0x42, 79},
+	{ 0x46,0x25, 85},
+	{ 0x78,0x29, 87}, /* 0x10 */
+	{ 0x62,0x44, 95},
+	{ 0x2b,0x22,105},
+	{ 0x49,0x24,106},
+	{ 0xc3,0x28,108},
+	{ 0x3c,0x23,109},
+	{ 0xf7,0x2c,132},
+	{ 0xd4,0x28,136},
+	{ 0x41,0x05,158},
+	{ 0x43,0x05,162},
+	{ 0xe1,0x0f,175},
+	{ 0xfc,0x12,189},
+	{ 0xde,0x26,194},
+	{ 0x54,0x05,203},
+	{ 0x3f,0x03,230},
+	{ 0x30,0x02,234},
+	{ 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 */
+	{ 0x60,0x36, 30},  /* 0x29  CH/UNTSC TEXT | LVDS_2(CH) - LVDS2(CH), 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) -  LVDS2(CH), A901(301B): 0x57, 0xe4, 31 */
+	{ 0x97,0x2c, 26},
+	{ 0xce,0x3c, 39},
+	{ 0x52,0x4a, 36},
+	{ 0x34,0x61, 95},
+	{ 0x78,0x27,108},
+	{ 0xce,0x25,189},
+	{ 0x45,0x6b, 21},  /* 0x36 */  /* TW: Added from Mitac */
+	{ 0xff,0x00,  0}
+};
+
+#if 0 /* TW: This table is in all BIOSes, but not used */
+SiS300_VCLKDataStruct  SiS300_VBVCLKData[]=
+{
+	{ 0x1b,0xe1, 25},
+	{ 0x4e,0xe4, 28},
+	{ 0x57,0xe4, 31},
+	{ 0xc3,0xc8, 36},
+	{ 0x42,0x47, 40},
+	{ 0x5d,0xc4, 44},
+	{ 0x52,0x47, 49},
+	{ 0x53,0x47, 50},
+	{ 0x6d,0x66, 56},
+	{ 0x5a,0x64, 65},
+	{ 0x46,0x44, 67},
+	{ 0x29,0x61, 75},
+	{ 0x6d,0x46, 75},
+	{ 0x41,0x43, 78},
+	{ 0x31,0x42, 79},
+	{ 0x46,0x25, 84},
+	{ 0x78,0x29, 86}, /* 0x10 */
+	{ 0x62,0x44, 94},
+	{ 0x2b,0x22,104},
+	{ 0x49,0x24,105},
+	{ 0x43,0x42,108},
+	{ 0x3c,0x23,109},
+	{ 0xe0,0x46,132},
+	{ 0x70,0x25,135},
+	{ 0x41,0x22,157},
+	{ 0x43,0x22,162},
+	{ 0x30,0x21,175},
+	{ 0xc1,0x24,189},
+	{ 0xde,0x26,194},
+	{ 0x70,0x07,202},
+	{ 0x3f,0x03,229},
+	{ 0x30,0x02,234},  /* 0x1f */
+	{ 0x24,0x01,265},  /* 0x20 */
+	{ 0x52,0x2a, 54},
+	{ 0x52,0x6a, 27},
+	{ 0x62,0x24, 70},
+	{ 0x62,0x64, 70},
+	{ 0xa8,0x4c, 30},
+	{ 0x20,0x26, 33},
+	{ 0x31,0xc2, 39},
+	{ 0x2e,0x48, 25},  /* 0x28 */
+	{ 0x24,0x46, 25},  /* 0x29 */
+	{ 0x26,0x64, 28},
+	{ 0x37,0x64, 40},
+	{ 0xa1,0x42,108},
+	{ 0x37,0x61,100},
+	{ 0x78,0x27,108},
+	{ 0xff,0x00,  0}
 };
+#endif
 
 UCHAR SiS300_ScreenOffset[] =
-    { 0x14, 0x19, 0x20, 0x28, 0x32, 0x40, 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35,
-	    0xff };
+{
+	0x14,0x19,0x20,0x28,0x32,0x40,0x50,
+        0x64,0x78,0x80,0x2d,0x35,0x48,0xff
+};
 
-typedef struct _SiS300_StResInfoStruct {
+typedef struct _SiS300_StResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
 } SiS300_StResInfoStruct;
-SiS300_StResInfoStruct SiS300_StResInfo[] = {
-	{640, 400},
-	{640, 350},
-	{720, 400},
-	{720, 350},
-	{640, 480}
+
+SiS300_StResInfoStruct  SiS300_StResInfo[] =
+{
+	{ 640,400},
+	{ 640,350},
+	{ 720,400},
+	{ 720,350},
+	{ 640,480}
 };
 
-typedef struct _SiS300_ModeResInfoStruct {
+typedef struct _SiS300_ModeResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
-	UCHAR XChar;
-	UCHAR YChar;
+	UCHAR  XChar;
+	UCHAR  YChar;
 } SiS300_ModeResInfoStruct;
-SiS300_ModeResInfoStruct SiS300_ModeResInfo[] = {
-	{320, 200, 8, 8},
-	{320, 240, 8, 8},
-	{320, 400, 8, 8},
-	{400, 300, 8, 8},
-	{512, 384, 8, 8},
-	{640, 400, 8, 16},
-	{640, 480, 8, 16},
-	{800, 600, 8, 16},
-	{1024, 768, 8, 16},
-	{1280, 1024, 8, 16},
-	{1600, 1200, 8, 16},
-	{1920, 1440, 8, 16},
-	{720, 480, 8, 16},
-	{720, 576, 8, 16},
-	{1280, 960, 8, 16}
+
+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 */
 };
 
-UCHAR SiS300_OutputSelect = 0x40;
+UCHAR SiS300_OutputSelect =0x40;
 UCHAR SiS300_SoftSetting = 30;
-UCHAR SiS300_SR07 = 0x10;
-UCHAR SiS300_SR15[8][4] = {
-	{0x1, 0x9, 0xa3, 0x0},
-	{0x43, 0x43, 0x43, 0x0},
-	{0x1e, 0x1e, 0x1e, 0x0},
-	{0x2a, 0x2a, 0x2a, 0x0},
-	{0x6, 0x6, 0x6, 0x0},
-	{0x0, 0x0, 0x0, 0x0},
-	{0x0, 0x0, 0x0, 0x0},
-	{0x0, 0x0, 0x0, 0x0}
-};
-UCHAR SiS300_SR1F = 0x0;
-UCHAR SiS300_SR21 = 0x16;
-UCHAR SiS300_SR22 = 0xb2;
-UCHAR SiS300_SR23 = 0xf6;
-UCHAR SiS300_SR24 = 0xd;
-UCHAR SiS300_SR25[] = { 0x0, 0x0 };
-UCHAR SiS300_SR31 = 0x0;
-UCHAR SiS300_SR32 = 0x11;
-UCHAR SiS300_SR33 = 0x0;
+UCHAR SiS300_SR07=0x10;
+UCHAR SiS300_SR15[8][4] =
+{
+	{0x1,0x9,0xa3,0x0},
+	{0x43,0x43,0x43,0x0},
+	{0x1e,0x1e,0x1e,0x0},
+	{0x2a,0x2a,0x2a,0x0},
+	{0x6,0x6,0x6,0x0},
+	{0x0,0x0,0x0,0x0},
+	{0x0,0x0,0x0,0x0},
+	{0x0,0x0,0x0,0x0}
+};
+UCHAR SiS300_SR1F=0x0;
+UCHAR SiS300_SR21=0x16;
+UCHAR SiS300_SR22=0xb2;
+UCHAR SiS300_SR23=0xf6;
+UCHAR SiS300_SR24=0xd;
+UCHAR SiS300_SR25[]={0x0,0x0};
+UCHAR SiS300_SR31=0x0;
+UCHAR SiS300_SR32=0x11;
+UCHAR SiS300_SR33=0x0;
 UCHAR SiS300_CRT2Data_1_2 = 0x40;
 UCHAR SiS300_CRT2Data_4_D = 0x0;
 UCHAR SiS300_CRT2Data_4_E = 0x0;
@@ -916,42 +1018,68 @@
 USHORT SiS300_RGBSenseData = 0xd1;
 USHORT SiS300_VideoSenseData = 0xb3;
 USHORT SiS300_YCSenseData = 0xb9;
-USHORT SiS300_RGBSenseData2 = 0x0190;	/*301b */
+USHORT SiS300_RGBSenseData2 = 0x0190;     /*301b*/
 USHORT SiS300_VideoSenseData2 = 0x0174;
 USHORT SiS300_YCSenseData2 = 0x016b;
 
 UCHAR SiS300_CR40[5][4];
 UCHAR SiS300_CR49[2];
-UCHAR SiS300_NTSCPhase[] = { 0x21, 0xed, 0x8a, 0x8 };
-UCHAR SiS300_PALPhase[] = { 0x2a, 0x5, 0xd3, 0x0 };
-UCHAR SiS300_NTSCPhase2[] = { 0x21, 0xF0, 0x7B, 0xD6 };	/*301b */
-UCHAR SiS300_PALPhase2[] = { 0x2a, 0x09, 0x86, 0xe9 };
-UCHAR SiS300_PALMPhase[] = { 0x21, 0xE4, 0x2E, 0x9B };	/*palmn */
-UCHAR SiS300_PALNPhase[] = { 0x21, 0xF4, 0x3E, 0xBA };
+UCHAR SiS300_NTSCPhase[]  = {0x21,0xed,0x8a,0x08};
+UCHAR SiS300_PALPhase[]   = {0x2a,0x05,0xd3,0x00};
+UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};  /* 301b */
+UCHAR SiS300_PALPhase2[]  = {0x2a,0x09,0x86,0xe9};  /* 301b */
+UCHAR SiS300_PALMPhase[]  = {0x21,0xE4,0x2E,0x9B};  /* palmn */
+UCHAR SiS300_PALNPhase[]  = {0x21,0xF4,0x3E,0xBA};
+UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
+UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
 
-typedef struct _SiS300_PanelDelayTblStruct {
+typedef struct _SiS300_PanelDelayTblStruct
+{
 	UCHAR timer[2];
 } SiS300_PanelDelayTblStruct;
-SiS300_PanelDelayTblStruct SiS300_PanelDelayTbl[] = {
-	{{0x05, 0xaa}},
-	{{0x05, 0x14}},
-	{{0x05, 0x36}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x90}},
-	{{0x05, 0x90}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x64}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}}
+
+SiS300_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
+{
+	{{0x05,0xaa}},
+	{{0x05,0x14}},
+	{{0x05,0x36}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x90}},
+	{{0x05,0x90}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x64}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}} 
+};
+
+SiS300_PanelDelayTblStruct SiS300_PanelDelayTblLVDS[] =
+{
+	{{0x05,0xaa}},
+	{{0x05,0x14}},
+	{{0x05,0x36}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x90}},
+	{{0x05,0x90}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x28}},  /* 2.04.5c: 20, 80 - Clevo (2.04.2c): 05, 28 */
+	{{0x05,0x14}},
+	{{0x05,0x14}},  /* Some BIOSes: 05, 40 */
+	{{0x05,0x60}}
 };
 
-typedef struct _SiS300_LCDDataStruct {
+typedef struct _SiS300_LCDDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -959,99 +1087,121 @@
 	USHORT LCDHT;
 	USHORT LCDVT;
 } SiS300_LCDDataStruct;
-SiS300_LCDDataStruct SiS300_StLCD1024x768Data[] = {
-	{66, 31, 992, 510, 1320, 816},
-	{66, 31, 992, 510, 1320, 816},
-	{176, 75, 900, 510, 1320, 816},
-	{176, 75, 900, 510, 1320, 816},
-	{66, 31, 992, 510, 1320, 816},
-	{27, 16, 1024, 650, 1350, 832},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS300_LCDDataStruct SiS300_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}
-};
-
-SiS300_LCDDataStruct SiS300_St2LCD1024x768Data[] = {
-	{62, 25, 800, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{104, 45, 945, 496, 1344, 806},
-	{62, 25, 800, 546, 1344, 806},
-	{31, 18, 1008, 624, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS300_LCDDataStruct SiS300_StLCD1280x1024Data[] = {
-	{4, 1, 880, 510, 1650, 1088},
-	{4, 1, 880, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{4, 1, 880, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS300_LCDDataStruct SiS300_ExtLCD1280x1024Data[] = {
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 500, 1688, 1066},
-	{211, 75, 1024, 625, 1688, 1066},
-	{211, 120, 1280, 798, 1688, 1066},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS300_LCDDataStruct SiS300_St2LCD1280x1024Data[] = {
-	{22, 5, 800, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS300_LCDDataStruct SiS300_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}
-};
-
-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}
+
+SiS300_LCDDataStruct  SiS300_StLCD1024x768Data[]=
+{
+	{   66,  31, 992, 510,1320, 816},
+	{   66,  31, 992, 510,1320, 816},
+	{  176,  75, 900, 510,1320, 816},
+	{  176,  75, 900, 510,1320, 816},
+	{   66,  31, 992, 510,1320, 816},
+	{   27,  16,1024, 650,1350, 832},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+SiS300_LCDDataStruct  SiS300_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}
+};
+
+SiS300_LCDDataStruct  SiS300_St2LCD1024x768Data[]=
+{
+	{   62,  25, 800, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{  104,  45, 945, 496,1344, 806},
+	{   62,  25, 800, 546,1344, 806},
+	{   31,  18,1008, 624,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+SiS300_LCDDataStruct  SiS300_StLCD1280x1024Data[]=
+{
+	{    4,   1, 880, 510,1650,1088},
+	{    4,   1, 880, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{    4,   1, 880, 510,1650,1088},
+	{   13,   5,1024, 675,1560,1152},
+	{   16,   9,1266, 804,1688,1072},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS300_LCDDataStruct  SiS300_ExtLCD1280x1024Data[]=
+{
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 500,1688,1066},
+	{  211,  75,1024, 625,1688,1066},
+	{  211, 120,1280, 798,1688,1066},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS300_LCDDataStruct  SiS300_St2LCD1280x1024Data[]=
+{
+	{   22,   5, 800, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{   13,   5,1024, 675,1560,1152},
+	{   16,   9,1266, 804,1688,1072},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS300_LCDDataStruct  SiS300_NoScaleData1024x768[]=
+{
+	{    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}
+};
+
+SiS300_LCDDataStruct  SiS300_NoScaleData1280x1024[]=  /* TW: Fake */
+{
+	{    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}
+};
+
+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}
 };
 
-typedef struct _SiS300_TVDataStruct {
+typedef struct _SiS300_TVDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -1066,457 +1216,1480 @@
 	UCHAR RY3COE;
 	UCHAR RY4COE;
 } SiS300_TVDataStruct;
-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}
-};
-
-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}	/*301b */
 
+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}
+};
+
+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}     /*301b*/
+
+};
+
+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}
+};
+
+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} /*301b*/
 };
 
-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}
-};
-
-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}	/*301b */
-};
-
-SiS_TVDataStruct SiS300_St1HiTVData[] = {
-	
-	    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	 0x00, 0x00}
-};
-
-SiS_TVDataStruct SiS300_St2HiTVData[] = {
-	
-	    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	 0x00, 0x00}
-};
-
-SiS_TVDataStruct SiS300_ExtHiTVData[] = {
-	
-	    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	 0x00, 0x00}
+SiS_TVDataStruct  SiS300_St1HiTVData[]=
+{
+ 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+SiS_TVDataStruct  SiS300_St2HiTVData[]=
+{
+ 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+SiS_TVDataStruct  SiS300_ExtHiTVData[]=
+{
+ 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
 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,
-	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
+	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
 };
 
 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,
-	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
+	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
 };
 
-UCHAR SiS300_HiTVExtTiming[] = { 0x00 };
+UCHAR SiS300_HiTVExtTiming[] = {0x00};
 
-UCHAR SiS300_HiTVSt1Timing[] = { 0x00 };
+UCHAR SiS300_HiTVSt1Timing[] = {0x00};
 
-UCHAR SiS300_HiTVSt2Timing[] = { 0x00 };
+UCHAR SiS300_HiTVSt2Timing[] = {0x00};
 
-UCHAR SiS300_HiTVTextTiming[] = { 0x00 };
+UCHAR SiS300_HiTVTextTiming[] = {0x00};
 
-UCHAR SiS300_HiTVGroup3Data[] = { 0x00 };
+UCHAR SiS300_HiTVGroup3Data[] = {0x00};
 
-UCHAR SiS300_HiTVGroup3Simu[] = { 0x00 };
+UCHAR SiS300_HiTVGroup3Simu[] = {0x00};
 
-UCHAR SiS300_HiTVGroup3Text[] = { 0x00 };
+UCHAR SiS300_HiTVGroup3Text[] = {0x00};
 
-typedef struct _SiS300_LVDSDataStruct {
+typedef struct _SiS300_LVDSDataStruct
+{
 	USHORT VGAHT;
 	USHORT VGAVT;
 	USHORT LCDHT;
 	USHORT LCDVT;
 } SiS300_LVDSDataStruct;
-SiS300_LVDSDataStruct SiS300_LVDS800x600Data_1[] = {
-	{0x00, 0x00, 0x00, 0x00}
+
+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}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS800x600Data_2[] = {
-	{0x00, 0x00, 0x00, 0x00}
+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}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_1[] = {
-	{0x00, 0x00, 0x00, 0x00}
+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}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_2[] = {
-	{0x00, 0x00, 0x00, 0x00}
+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}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_1[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_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}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_2[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_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}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS640x480Data_1[] = {
-	{0x00, 0x00, 0x00, 0x00}
+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}
 };
 
-SiS300_LVDSDataStruct SiS300_CHTVUNTSCData[] = {
-	{0x00, 0x00, 0x00, 0x00}
+/* TW: New: */
+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, 801},
+	{800, 525,1280, 813}
 };
 
-SiS300_LVDSDataStruct SiS300_CHTVONTSCData[] = {
-	{0x00, 0x00, 0x00, 0x00}
+/* TW: New: */
+SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_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}
 };
 
-SiS300_LVDSDataStruct SiS300_CHTVUPALData[] = {
-	{0x00, 0x00, 0x00, 0x00}
+/* TW: New: */
+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}
 };
 
-SiS300_LVDSDataStruct SiS300_CHTVOPALData[] = {
-	{0x00, 0x00, 0x00, 0x00}
+/* TW: New: */
+SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_2[]=
+{
+	{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}
 };
 
-typedef struct _SiS300_LVDSDesStruct {
+/* TW: New: */
+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}
+};
+
+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}
+};
+
+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}
+};
+
+SiS300_LVDSDataStruct  SiS300_CHTVOPALData[]=
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{840, 625, 840, 625},
+	{960, 750, 960, 750}
+};
+/* TW: new end */
+
+typedef struct _SiS300_LVDSDesStruct
+{
 	USHORT LCDHDES;
 	USHORT LCDVDES;
 } SiS300_LVDSDesStruct;
-SiS300_LVDSDesStruct SiS300_PanelType00_1[] = {
-	{0x00, 0x00}
+
+SiS300_LVDSDesStruct  SiS300_PanelType00_1[]=
+{
+	{0, 626},
+	{0, 624},
+	{0, 626},
+	{0, 624},
+	{0, 624},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType01_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType01_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType02_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType02_1[]=
+{
+	{0, 626},
+	{0, 624},
+	{0, 626},
+	{0, 624},
+	{0, 624},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType03_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType03_1[]=
+{
+	{ 8, 436},
+	{ 8, 440},
+	{ 8, 436},
+	{ 8, 440},
+	{ 8, 512},
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType04_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType04_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType05_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType05_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType06_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType06_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType07_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType07_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType08_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType08_1[]=
+{
+	{1059, 626},
+	{1059, 624},
+	{1059, 626},
+	{1059, 624},
+	{1059, 624},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType09_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType09_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0a_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0a_1[]=
+{
+	{1059, 626},
+	{1059, 624},
+	{1059, 626},
+	{1059, 624},
+	{1059, 624},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0b_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0b_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0c_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0c_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0d_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0d_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0e_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0e_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},  /* 640x480 */
+	{1343,   0},  /* 800x600 */
+	{ 0, 805},    /* 1024x768 */
+	{ 0, 794},    /* 1280x1024 */
+	{ 0,   0}     /* 1280x960 - not applicable */
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0f_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0f_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType00_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType00_2[]=
+{
+	{976, 527},
+	{976, 502},
+	{976, 527},
+	{976, 502},
+	{976, 567},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType01_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType01_2[]=
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType02_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType02_2[]=
+{
+	{976, 527},
+	{976, 502},
+	{976, 527},
+	{976, 502},
+	{976, 567},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType03_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType03_2[]=
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805},
+	{1152, 622},
+	{1152, 597}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType04_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType04_2[]=
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType05_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType05_2[]=
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType06_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType06_2[]=
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType07_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType07_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType08_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType08_2[]=
+{
+ 	{976, 527},
+ 	{976, 502},
+ 	{976, 527},
+ 	{976, 502},
+ 	{976, 567},
+ 	{  0, 627},
+ 	{  0, 627},
+ 	{  0,   0},
+ 	{  0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType09_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType09_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0a_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0a_2[]=
+{
+ 	{976, 527},
+ 	{976, 502},
+ 	{976, 527},
+ 	{976, 502},
+ 	{976, 567},
+ 	{  0, 627},
+ 	{  0, 627},
+ 	{  0,   0},
+ 	{  0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0b_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0b_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0c_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0c_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0d_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0d_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0e_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0e_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0f_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0f_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-/*301b*/
-SiS300_LVDSDesStruct SiS300_PanelType1076_1[] = {
-	{0x00, 0x00}
+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}
 };
-SiS300_LVDSDesStruct SiS300_PanelType1210_1[] = {
-	{0x00, 0x00}
+
+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   }
 };
-SiS300_LVDSDesStruct SiS300_PanelType1296_1[] = {
-	{0x00, 0x00}
+
+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}
 };
-SiS300_LVDSDesStruct SiS300_PanelType1076_2[] = {
-	{0x00, 0x00}
+
+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}
 };
-SiS300_LVDSDesStruct SiS300_PanelType1210_2[] = {
-	{0x00, 0x00}
+
+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}
 };
-SiS300_LVDSDesStruct SiS300_PanelType1296_2[] = {
-	{0x00, 0x00}
+
+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}
 };
-/*end 301b*/
 
-SiS300_LVDSDesStruct SiS300_CHTVUNTSCDesData[] = {
-	{0x00, 0x00}
+
+/* TW: New */
+SiS300_LVDSDesStruct  SiS300_CHTVUNTSCDesData[]=
+{
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_CHTVONTSCDesData[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_CHTVONTSCDesData[]=
+{
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_CHTVUPALDesData[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_CHTVUPALDesData[]=
+{
+ 	{256,   0},
+ 	{256,   0},
+ 	{256,   0},
+ 	{256,   0},
+ 	{  0,   0},
+ 	{  0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_CHTVOPALDesData[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_CHTVOPALDesData[]=
+{
+ 	{256,   0},
+ 	{256,   0},
+ 	{256,   0},
+ 	{256,   0},
+ 	{  0,   0},
+ 	{  0,   0}
 };
+/* TW: New end */
 
-typedef struct _SiS300_LVDSCRT1DataStruct {
-	UCHAR CR[15];
+typedef struct _SiS300_LVDSCRT1DataStruct
+{
+UCHAR CR[15];
 } SiS300_LVDSCRT1DataStruct;
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1[]=
+{
+	{{0x65,0x4f,0x89,0x56,0x83,0xaf,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,0x56,0x83,0xaf,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,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 }}
+};
+
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_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} }
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+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 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+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 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[]=
+{
+	{{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00 }},
+	{{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+	  0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
+	  0x00}},
+	{{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+	{{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+	  0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
+	  0x00}},
+	{{0x37,0x27,0x9B,0x2b,0x94,0x04,0x3e,
+	  0xE2,0x89,0xDf,0x05,0x00,0x00,0x44,
+	  0x00}},
+	{{0x41,0x31,0x85,0x35,0x1d,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 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[]=
+{
+	{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+	  0x00 }},
+	{{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+	  0x00 }},
+	{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+	  0x00 }},
+	{{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+	  0x00 }},
+	{{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
+	  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 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2[]=
+{
+	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+	  0x00 }},
+	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+	  0x00 }},
+	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+	  0x00 }},
+	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+	  0x00 }},
+	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
+	  0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
+	  0x00 }},
+	{{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+	  0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_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 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+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 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+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 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_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 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[]=
+{
+	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x31,0x93,0x3e,0x86,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}}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+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}}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+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}}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+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}}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+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}}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+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}}
 };
 
-typedef struct _SiS300_CHTVRegDataStruct {
-	UCHAR Reg[5];
+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}}
+};
+
+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}}
+};
+
+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 */
+SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[]=
+{
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
+	  0x18,0x84,0xdf,0x57,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
+	  0x90,0x8c,0x57,0xed,0x20,0x00,0x06,
+	  0x01 }}
+};
+
+SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1ONTSC[]=
+{
+	{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+	  0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+	  0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+	  0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+	  0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
+	  0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
+	  0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,
+	  0x01 }}
+};
+
+SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UPAL[]=
+{
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
+	  0x50,0x84,0xdf,0xed,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
+	  0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,
+	  0x01 }}
+};
+
+SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1OPAL[]=
+{
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
+	  0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
+	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+	  0x01 }}
+};
+/* TW: New end */
+
+/* TW: New */
+typedef struct _SiS300_CHTVRegDataStruct
+{
+	UCHAR Reg[16];
 } SiS300_CHTVRegDataStruct;
+
 SiS300_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] = {
-	{{0x00, 0x00, 0x00, 0x00, 0x00}}
+	{{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x6a,0x6a,0x00,0x2d,0xfa,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 17: 640x480 NTSC 7/8  */
+	{{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 24: 800x600 NTSC 7/10 */
 };
 
 SiS300_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] = {
-	{{0x00, 0x00, 0x00, 0x00, 0x00}}
+	{{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x69,0x6a,0x00,0x1e,0xfd,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 16: 640x480 NTSC 1/1 */
+	{{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 23: 800x600 NTSC 3/4 */
 };
 
 SiS300_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] = {
-	{{0x00, 0x00, 0x00, 0x00, 0x00}}
+	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x63,0x94,0x01,0x50,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 15: 640x480 PAL 5/6 */
+	/* TW: For 800x600, 3/4 is VERY underscan */
+	{{0x84,0x64,0x01,0x4e,0x2f,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 21: 800x600 PAL 3/4 */
+	/* TW: Mode 20 is still underscan, use it instead? */
+	/* {{0x83,0x76,0x01,0x40,0x31}} */ /* Mode 20: 800x600 PAL 5/6 */
 };
 
 SiS300_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] = {
-	{{0x00, 0x00, 0x00, 0x00, 0x00}}
+	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
+	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x61,0x94,0x01,0x36,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 14: 640x480 PAL 1/1 */
+	{{0x83,0x76,0x01,0x40,0x31,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 20: 800x600 PAL 5/6 */
+	/* {{0x81,0x12,0x01,0x50,0x34}}  */ /* TW: (test) Mode 19: 800x600 PAL 1/1 */
 };
+/* TW: New end */
+
+/* TW: New */
+UCHAR SiS300_CHTVVCLKUNTSC[] = {0x29,0x29,0x29,0x29,0x2a,0x2e};
+
+UCHAR SiS300_CHTVVCLKONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
 
-UCHAR SiS300_CHTVVCLKUNTSC[] = { 0x00 };
+UCHAR SiS300_CHTVVCLKUPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31};
 
-UCHAR SiS300_CHTVVCLKONTSC[] = { 0x00 };
+UCHAR SiS300_CHTVVCLKOPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
+/* TW: New end */
 
-UCHAR SiS300_CHTVVCLKUPAL[] = { 0x00 };
 
-UCHAR SiS300_CHTVVCLKOPAL[] = { 0x00 };
diff -Nru a/drivers/video/sis/310vtbl.h b/drivers/video/sis/310vtbl.h
--- a/drivers/video/sis/310vtbl.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/sis/310vtbl.h	Wed Jul 24 14:03:38 2002
@@ -1,4 +1,10 @@
-typedef struct _SiS310_StStruct {
+
+
+/* Register settings for SiS 310/325 series */
+
+
+typedef struct _SiS310_StStruct
+{
 	UCHAR St_ModeID;
 	USHORT St_ModeFlag;
 	UCHAR St_StTableIndex;
@@ -9,31 +15,32 @@
 	UCHAR VB_StTVYFilterIndex;
 } SiS310_StStruct;
 
-SiS310_StStruct SiS310_SModeIDTable[] =
+SiS310_StStruct SiS310_SModeIDTable[]=
 {
-	{0x01, 0x9208, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
-	{0x01, 0x1210, 0x14, 0x01, 0x01, 0x00, 0x01, 0x00},
-	{0x01, 0x1010, 0x17, 0x02, 0x02, 0x00, 0x01, 0x01},
-	{0x03, 0x8208, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02},
-	{0x03, 0x0210, 0x16, 0x01, 0x01, 0x00, 0x01, 0x02},
-	{0x03, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x01, 0x03},
-	{0x05, 0x9209, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x06, 0x8209, 0x06, 0x00, 0x00, 0x00, 0x00, 0x05},
-	{0x07, 0x0000, 0x07, 0x03, 0x03, 0x00, 0x01, 0x03},
-	{0x07, 0x0000, 0x19, 0x02, 0x02, 0x00, 0x01, 0x03},
-	{0x0d, 0x920a, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x0e, 0x820a, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x05},
-	{0x0f, 0x0202, 0x11, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0x10, 0x0212, 0x12, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0x11, 0x0212, 0x1a, 0x04, 0x04, 0x00, 0x00, 0x05},
-	{0x12, 0x0212, 0x1b, 0x04, 0x04, 0x00, 0x00, 0x05},
-	{0x13, 0x021b, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x12, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x00, 0x05},
-	{0x12, 0x0210, 0x18, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0xff, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+	{0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00},
+	{0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00},
+	{0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01},
+	{0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02},
+	{0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02},
+	{0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03},
+	{0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04},
+	{0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05},
+	{0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03},
+	{0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03},
+	{0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04},
+	{0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05},
+	{0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05},
+	{0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05},
+	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05},
+	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05},
+	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04},
+	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05},
+	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05},
+	{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS310_StandTableStruct {
+typedef struct _SiS310_StandTableStruct
+{
 	UCHAR CRT_COLS;
 	UCHAR ROWS;
 	UCHAR CHAR_HEIGHT;
@@ -45,448 +52,450 @@
 	UCHAR GRC[9];
 } SiS310_StandTableStruct;
 
-SiS310_StandTableStruct SiS310_StandTable[] = {
+SiS310_StandTableStruct SiS310_StandTable[]=
+{
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* MD_3_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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
-	{
-	 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}
-	 },
+ {
+  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}
+ },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* ExtVGATable */
-	{
-	 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* MD_3_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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* MD_2_3_400 */
-	{
-	 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* ExtEGATable */
-	{
-	 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 }
+ {
+  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 {
+typedef struct _SiS310_ExtStruct
+{
 	UCHAR Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
-	USHORT Ext_Point;
+	USHORT Ext_Point;    /* TW: Address of table entry in (older) BIOS image */
 	USHORT Ext_VESAID;
 	UCHAR Ext_VESAMEMSize;
 	UCHAR Ext_RESINFO;
@@ -495,651 +504,733 @@
 	UCHAR VB_ExtTVYFilterIndex;
 	UCHAR REFindex;
 } SiS310_ExtStruct;
-SiS310_ExtStruct SiS310_EModeIDTable[] = {
-	
-	    {0x6a, 0x2212, 0x0407, 0x3a81, 0x0102, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x2e, 0x0a1b, 0x0306, 0x3a57, 0x0101, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x2f, 0x0a1b, 0x0305, 0x3a50, 0x0100, 0x08, 0x05, 0x00, 0x00, 0x05,
-	 0x10},
-	{0x30, 0x2a1b, 0x0407, 0x3a81, 0x0103, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x31, 0x0a1b, 0x030d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x32, 0x0a1b, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x33, 0x0a1d, 0x0a0d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x34, 0x2a1d, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x35, 0x0a1f, 0x0a0d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x36, 0x2a1f, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x37, 0x0212, 0x0508, 0x3aab, 0x0104, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x38, 0x0a1b, 0x0508, 0x3aab, 0x0105, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x3a, 0x0e3b, 0x0609, 0x3adc, 0x0107, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x3c, 0x063b, 0x070a, 0x3af2, 0x0130, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{0x3d, 0x067d, 0x070a, 0x3af2, 0x0131, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{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},
-	{0x46, 0x2a1c, 0x0407, 0x3a81, 0x0113, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x47, 0x2a1d, 0x0407, 0x3a81, 0x0114, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x49, 0x0a3c, 0x0508, 0x3aab, 0x0116, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x4a, 0x0a3d, 0x0508, 0x3aab, 0x0117, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x4c, 0x0e7c, 0x0609, 0x3adc, 0x0119, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x4d, 0x0e7d, 0x0609, 0x3adc, 0x011a, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x50, 0x9a1b, 0x0001, 0x3a3b, 0x0132, 0x08, 0x01, 0x00, 0x00, 0x04,
-	 0x26},
-	{0x51, 0xba1b, 0x0103, 0x3a42, 0x0133, 0x08, 0x03, 0x00, 0x00, 0x07,
-	 0x27},
-	{0x52, 0x9a1b, 0x0204, 0x3a49, 0x0134, 0x08, 0x04, 0x00, 0x00, 0x00,
-	 0x28},
-	{0x56, 0x9a1d, 0x0001, 0x3a3b, 0x0135, 0x08, 0x01, 0x00, 0x00, 0x04,
-	 0x26},
-	{0x57, 0xba1d, 0x0103, 0x3a42, 0x0136, 0x08, 0x03, 0x00, 0x00, 0x07,
-	 0x27},
-	{0x58, 0x9a1d, 0x0204, 0x3a49, 0x0137, 0x08, 0x04, 0x00, 0x00, 0x00,
-	 0x28},
-	{0x59, 0x9a1b, 0x0000, 0x3a34, 0x0138, 0x08, 0x00, 0x00, 0x00, 0x04,
-	 0x25},
-	{0x5d, 0x0a1d, 0x0305, 0x3a50, 0x0139, 0x08, 0x05, 0x00, 0x00, 0x07,
-	 0x10},
-	{0x62, 0x0a3f, 0x0306, 0x3a57, 0x013a, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x63, 0x2a3f, 0x0407, 0x3a81, 0x013b, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x64, 0x0a7f, 0x0508, 0x3aab, 0x013c, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x65, 0x0eff, 0x0609, 0x3adc, 0x013d, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x66, 0x06ff, 0x070a, 0x3af2, 0x013e, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{0x68, 0x067b, 0x080b, 0x3b17, 0x013f, 0x08, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x69, 0x06fd, 0x080b, 0x3b17, 0x0140, 0x08, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x6b, 0x07ff, 0x080b, 0x3b17, 0x0141, 0x10, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x6c, 0x067b, 0x090c, 0x3b37, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x6d, 0x06fd, 0x090c, 0x3b37, 0x0000, 0x10, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x6e, 0x07ff, 0x090c, 0x3b37, 0x0000, 0x10, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x70, 0x2a1b, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x71, 0x0a1b, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x74, 0x0a1d, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x75, 0x0a3d, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x76, 0x2a1f, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x77, 0x0a1f, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x78, 0x0a3f, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x79, 0x0a3b, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x7a, 0x2a1d, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x7b, 0x0e3b, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0x7c, 0x0e7d, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0x7d, 0x0eff, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0xff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00,
-	 0x00}
+
+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,0x00,0x13},          /* 1024x768x? */
+	{0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},          /* 1024x768x8 */
+/*	{0x38,0x021b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},    */    /* 1024x768x8 - 650/LVDS BIOS (no CRt2Mode)  */
+	{0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x8 */
+/*	{0x3a,0x063b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},    */    /* 1280x1024x8 - 650/LVDS BIOS*/
+	{0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x8 */
+/*	{0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},    */    /* 1600x1200x8 - 650/LVDS BIOS */
+	{0x3d,0x067d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x16 */
+	{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,0x00,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},
+/*	{0x50,0x921b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},     */   /* 650/LVDS BIOS */
+	{0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
+/*	{0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},  */
+  	{0x52,0xba1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},          /* 650/301 BIOS */
+/*	{0x52,0xb21b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},     */   /* 650/LVDS BIOS (no CRT2Mode) */
+	{0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
+	{0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
+/*	{0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},  */
+ 	{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},
+/*	{0x59,0x921b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},     */   /* 650/LVDS BIOS (no CRT2Mode) */
+	{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},
+	{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,0x00,0x13},          /* 1024x768x32 */
+	{0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x32 */
+	{0x66,0x06ff,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,0x063b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},  */      /* 1280x768x8 - 650/LVDS BIOS */
+	{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 */
+/*	{0x26,0x063b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},    */    /* 1400x1050x8 - 650/LVDS BIOS */
+	{0x27,0x0e7d,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x16 */
+	{0x28,0x0eff,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x32*/
+	{0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS310_Ext2Struct {
+typedef struct _SiS310_Ext2Struct
+{
 	USHORT Ext_InfoFlag;
 	UCHAR Ext_CRT1CRTC;
 	UCHAR Ext_CRTVCLK;
 	UCHAR Ext_CRT2CRTC;
-	UCHAR ModeID;
+	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
 	USHORT ROM_OFFSET;
 } SiS310_Ext2Struct;
-SiS310_Ext2Struct SiS310_RefIndex[] = {
-	{0x005f, 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 */
-	{0x4147, 0x12, 0x0d, 0x00, 0x6a, 800, 600, 0x3a9a},	/* 0x5 */
-	{0x4047, 0x13, 0x13, 0x00, 0x6a, 800, 600, 0x3a9f},	/* 0x6 */
-	{0x4047, 0x14, 0x1c, 0x00, 0x6a, 800, 600, 0x3aa4},	/* 0x7 */
-	{0xc05f, 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 */
-	{0x4047, 0x09, 0x05, 0x00, 0x2e, 640, 480, 0x3a6b},	/* 0xc */
-	{0x4047, 0x0a, 0x09, 0x00, 0x2e, 640, 480, 0x3a70},	/* 0xd */
-	{0x4047, 0x0b, 0x0e, 0x00, 0x2e, 640, 480, 0x3a75},	/* 0xe */
-	{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 301b TV1024x768 */
-	{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 */
-	{0x4047, 0x1a, 0x1b, 0x00, 0x37, 1024, 768, 0x3ac4},	/* 0x18 */
-	{0x4047, 0x1b, 0x1f, 0x00, 0x37, 1024, 768, 0x3ac9},	/* 0x19 */
-	{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 */
-	{0x0007, 0x20, 0x21, 0x00, 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 */
-	{0x0047, 0x3a, 0x20, 0x0a, 0x75, 1280, 720, 0x3b7e},	/* 0x3c */
-	{0x0027, 0x3b, 0x19, 0x08, 0x7b, 1280, 960, 0x3ad0},	/* 0x3d */
-	{0x0027, 0x3b, 0x19, 0x08, 0x7b, 1280, 960, 0x3ad5},	/* 0x3e */
-	{0xffff, 0x00, 0x00, 0x00, 0x00, 0000, 0000, 0x0000}
+
+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 */
+	{0x4147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 */
+	{0x4047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 */
+	{0x4047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 */
+/*	{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 */
+	{0x4047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc */
+	{0x4047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd */
+	{0x4047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe */
+	{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 301b TV1024x768*/
+	{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 */
+	{0x4047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 */
+	{0x4047,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 */
+	{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 */
+	{0x0007,0x20,0x21,0x00,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 */
+	{0x0047,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
+	{0x0027,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */
+	{0x0027,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad5}, /* 0x3e */
+	{0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */    /* FSTN mode */
+        {0x0077,0x42,0x12,0x07,0x23,1280, 768,0x0000}, /* 0x40 */    /* TW: 650/LVDS new mode */
+	{0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */    /* TW: 650/LVDS new mode */
+	{0xffff,0x00,0x00,0x00,0x00,0000,0000,0x0000}
 };
 
-typedef struct _SiS310_CRT1TableStruct {
-	UCHAR CR[17];
+typedef struct _SiS310_CRT1TableStruct
+{
+ 	UCHAR CR[17];
 } SiS310_CRT1TableStruct;
-
-SiS310_CRT1TableStruct SiS310_CRT1Table[] = {
-	{{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	  0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x00,
-	  0x00}},		/* 0x0 */
-	{{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x00,
-	  0x00}},		/* 0x1 */
-	{{0x3d, 0x31, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x05,
-	  0x01}},		/* 0x2 */
-	{{0x4f, 0x3f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x01,
-	  0x01}},		/* 0x3 */
-	{{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x05,
-	  0x00}},		/* 0x4 */
-	{{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	  0x00}},		/* 0x5 */
-	{{0x63, 0x4f, 0x50, 0x86, 0x56, 0x9b, 0x06, 0x3e,
-	  0xe8, 0x8b, 0xdf, 0xe7, 0xff, 0x10, 0x00, 0x01,
-	  0x00}},		/* 0x6 */
-	{{0x64, 0x4f, 0x4f, 0x88, 0x55, 0x9d, 0xf2, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xf3, 0x10, 0x00, 0x01,
-	  0x00}},		/* 0x7 */
-	{{0x63, 0x4f, 0x4f, 0x87, 0x5a, 0x81, 0xfb, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x05,
-	  0x00}},		/* 0x8 */
-	{{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0xfb, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x00, 0x00, 0x05,
-	  0x61}},		/* 0x9 */
-	{{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0x01, 0x3e,
-	  0xe0, 0x83, 0xdf, 0xdf, 0x02, 0x00, 0x00, 0x05,
-	  0x61}},		/* 0xa */
-	{{0x67, 0x4f, 0x4f, 0x8b, 0x58, 0x81, 0x0d, 0x3e,
-	  0xe0, 0x83, 0xdf, 0xdf, 0x0e, 0x10, 0x00, 0x05,
-	  0x61}},		/* 0xb */
-	{{0x65, 0x4f, 0x4f, 0x89, 0x57, 0x9f, 0xfb, 0x1f,
-	  0xe6, 0x8a, 0xe5, 0xe5, 0xfc, 0x00, 0x00, 0x01,
-	  0x00}},		/* 0xc */
-	{{0x7b, 0x63, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	  0x58, 0x8a, 0x57, 0x57, 0x70, 0x20, 0x00, 0x05,
-	  0x01}},		/* 0xd */
-	{{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x06,
-	  0x01}},		/* 0xe */
-	{{0x7d, 0x63, 0x63, 0x81, 0x6e, 0x1d, 0x98, 0xf0,
-	  0x7c, 0x82, 0x57, 0x57, 0x99, 0x00, 0x00, 0x06,
-	  0x01}},		/* 0xf */
-	{{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x70, 0x20, 0x00, 0x06,
-	  0x01}},		/* 0x10 */
-	{{0x7e, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06,
-	  0x01}},		/* 0x11 */
-	{{0x81, 0x63, 0x63, 0x85, 0x6d, 0x18, 0x7a, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x7b, 0x20, 0x00, 0x06,
-	  0x61}},		/* 0x12 */
-	{{0x83, 0x63, 0x63, 0x87, 0x6e, 0x19, 0x81, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x82, 0x20, 0x00, 0x06,
-	  0x61}},		/* 0x13 */
-	{{0x85, 0x63, 0x63, 0x89, 0x6f, 0x1a, 0x91, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x92, 0x20, 0x00, 0x06,
-	  0x61}},		/* 0x14 */
-	{{0x99, 0x7f, 0x7f, 0x9d, 0x84, 0x1a, 0x96, 0x1f,
-	  0x7f, 0x83, 0x7f, 0x7f, 0x97, 0x10, 0x00, 0x02,
-	  0x00}},		/* 0x15 */
-	{{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}},		/* 0x16 */
-	{{0xa1, 0x7f, 0x7f, 0x85, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}},		/* 0x17 */
-	{{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x1f, 0x10, 0x00, 0x02,
-	  0x01}},		/* 0x18 */
-	{{0xa7, 0x7f, 0x7f, 0x8b, 0x89, 0x95, 0x26, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x27, 0x10, 0x00, 0x02,
-	  0x01}},		/* 0x19 */
-	{{0xa9, 0x7f, 0x7f, 0x8d, 0x8c, 0x9a, 0x2c, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x2d, 0x14, 0x00, 0x02,
-	  0x62}},		/* 0x1a */
-	{{0xab, 0x7f, 0x7f, 0x8f, 0x8d, 0x9b, 0x35, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x36, 0x14, 0x00, 0x02,
-	  0x62}},		/* 0x1b */
-	{{0xcf, 0x9f, 0x9f, 0x93, 0xb2, 0x01, 0x14, 0xba,
-	  0x00, 0x83, 0xff, 0xff, 0x15, 0x00, 0x00, 0x03,
-	  0x00}},		/* 0x1c */
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	  0x01}},		/* 0x1d */
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	  0x01}},		/* 0x1e */
-	{{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x2f, 0x09, 0x00, 0x07,
-	  0x01}},		/* 0x1f */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x20 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x21 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x22 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x23 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x24 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x25 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x26 */
-	{{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	  0x00}},		/* 0x27 */
-	{{0x43, 0xef, 0xef, 0x87, 0x06, 0x00, 0xd4, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xd5, 0x1f, 0x41, 0x05,
-	  0x63}},		/* 0x28 */
-	{{0x45, 0xef, 0xef, 0x89, 0x07, 0x01, 0xd9, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xda, 0x1f, 0x41, 0x05,
-	  0x63}},		/* 0x29 */
-	{{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	  0x00}},		/* 0x2a */
-	{{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	  0x00}},		/* 0x2b */
-	{{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	  0x00}},		/* 0x2c */
-	{{0x59, 0xff, 0xff, 0x9d, 0x17, 0x13, 0x33, 0xba,
-	  0x00, 0x83, 0xff, 0xff, 0x34, 0x0f, 0x41, 0x05,
-	  0x44}},		/* 0x2d */
-	{{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x38, 0xba,
-	  0x00, 0x83, 0xff, 0xff, 0x39, 0x0f, 0x41, 0x05,
-	  0x44}},		/* 0x2e */
-	{{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x3d, 0xba,
-	  0x00, 0x83, 0xff, 0xff, 0x3e, 0x0f, 0x41, 0x05,
-	  0x44}},		/* 0x2f */
-	{{0x5d, 0xff, 0xff, 0x81, 0x19, 0x95, 0x41, 0xba,
-	  0x00, 0x84, 0xff, 0xff, 0x42, 0x0f, 0x41, 0x05,
-	  0x44}},		/* 0x30 */
-	{{0x55, 0xff, 0xff, 0x99, 0x0d, 0x0c, 0x3e, 0xba,
-	  0x00, 0x84, 0xff, 0xff, 0x3f, 0x0f, 0x41, 0x05,
-	  0x00}},		/* 0x31 */
-	{{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xba,
-	  0x27, 0x8b, 0xdf, 0xdf, 0x73, 0x00, 0x00, 0x06,
-	  0x01}},		/* 0x32 */
-	{{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xba,
-	  0x26, 0x89, 0xdf, 0xdf, 0x6f, 0x00, 0x00, 0x06,
-	  0x01}},		/* 0x33 */
-	{{0x7f, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xba,
-	  0x29, 0x8c, 0xdf, 0xdf, 0x75, 0x00, 0x00, 0x06,
-	  0x01}},		/* 0x34 */
-	{{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf1,
-	  0xaf, 0x85, 0x3f, 0x3f, 0x25, 0x30, 0x00, 0x02,
-	  0x01}},		/* 0x35 */
-	{{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf1,
-	  0xad, 0x81, 0x3f, 0x3f, 0x1f, 0x30, 0x00, 0x02,
-	  0x01}},		/* 0x36 */
-	{{0xa7, 0x7f, 0x7f, 0x88, 0x89, 0x15, 0x26, 0xf1,
-	  0xb1, 0x85, 0x3f, 0x3f, 0x27, 0x30, 0x00, 0x02,
-	  0x01}},		/* 0x37 */
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0xc4,
-	  0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	  0x01}},		/* 0x38 */
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0xd4,
-	  0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	  0x01}},		/* 0x39 */
-	{{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0xd4,
-	  0x7d, 0x81, 0xcf, 0xcf, 0x2f, 0x21, 0x00, 0x07,
-	  0x01}},		/* 0x3a */
-	{{0xdc, 0x9f, 0x9f, 0x00, 0xab, 0x19, 0xe6, 0xef,
-	  0xc0, 0xc3, 0xbf, 0xbf, 0xe7, 0x10, 0x00, 0x07,
-	  0x01}},		/* 0x3b */
-	{{0x6b, 0x59, 0x59, 0x8f, 0x5e, 0x8c, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	  0x00}},		/* 0x3c */
-	{{0x7b, 0x59, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	  0x58, 0x8a, 0x3f, 0x57, 0x70, 0x20, 0x00, 0x05,
-	  0x01}}		/* 0x3d */
+SiS310_CRT1TableStruct SiS310_CRT1Table[]=
+{
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+   0x00}}, /* 0x0 */
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}, /* 0x1 */
+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+   0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+   0x01}}, /* 0x2 */
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+   0x01}}, /* 0x3 */
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
+   0x00}}, /* 0x4 */
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+   0x00}}, /* 0x5 */
+ {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
+   0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
+   0x00}}, /* 0x6 */
+ {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
+   0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
+   0x00}}, /* 0x7 */
+ {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
+   0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
+   0x00}}, /* 0x8 */
+ {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
+   0xe0,0x83,0xdf,0xdf,0xfc,0x00,0x00,0x05,
+   0x61}}, /* 0x9 */
+ {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
+   0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
+   0x61}}, /* 0xa */
+ {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
+   0xe0,0x83,0xdf,0xdf,0x0e,0x10,0x00,0x05,
+   0x61}}, /* 0xb */
+ {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
+   0xe6,0x8a,0xe5,0xe5,0xfc,0x00,0x00,0x01,
+   0x00}}, /* 0xc */
+ {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+   0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
+   0x01}}, /* 0xd */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
+   0x01}}, /* 0xe */
+ {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
+   0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
+   0x01}}, /* 0xf */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
+   0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
+   0x01}}, /* 0x10 */
+ {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
+   0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
+   0x01}}, /* 0x11 */
+ {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
+   0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
+   0x61}}, /* 0x12 */
+ {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
+   0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
+   0x61}}, /* 0x13 */
+ {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
+   0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
+   0x61}}, /* 0x14 */
+ {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
+   0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
+   0x00}}, /* 0x15 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+   0x01}}, /* 0x16 */
+ {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+   0x01}}, /* 0x17 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
+   0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
+   0x01}}, /* 0x18 */
+ {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
+   0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
+   0x01}}, /* 0x19 */
+ {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
+   0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
+   0x62}}, /* 0x1a */
+ {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
+   0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
+   0x62}}, /* 0x1b */
+ {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
+   0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
+   0x00}}, /* 0x1c */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
+   0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+   0x01}}, /* 0x1d */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
+   0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+   0x01}}, /* 0x1e */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
+   0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
+   0x01}}, /* 0x1f */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+   0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+   0x00}}, /* 0x20 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+   0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+   0x00}}, /* 0x21 @ 4084 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+   0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+   0x00}}, /* 0x22 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+   0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+   0x00}}, /* 0x23 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+   0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+   0x00}}, /* 0x24 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+   0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+   0x00}}, /* 0x25 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+   0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+   0x00}}, /* 0x26 */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+   0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+   0x00}}, /* 0x27 */
+ {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
+   0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
+   0x63}}, /* 0x28 */
+ {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
+   0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
+   0x63}}, /* 0x29 */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+   0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+   0x00}}, /* 0x2a */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+   0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+   0x00}}, /* 0x2b */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+   0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+   0x00}}, /* 0x2c */
+ {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
+   0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
+   0x44}}, /* 0x2d */
+ {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
+   0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
+   0x44}}, /* 0x2e */
+ {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
+   0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
+   0x44}}, /* 0x2f */
+ {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
+  0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
+  0x44}}, /* 0x30 */
+ {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
+  0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
+  0x00}}, /* 0x31 */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
+   0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+   0x01}}, /* 0x32 */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+   0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+   0x01}}, /* 0x33 */
+ {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+   0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+   0x01}}, /* 0x34 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+   0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+   0x01}}, /* 0x35 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+   0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+   0x01}}, /* 0x36 */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
+   0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+   0x01}}, /* 0x37 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+   0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+   0x01}}, /* 0x38 */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+   0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+   0x01}}, /* 0x39 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+   0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+   0x01}}, /* 0x3a */
+ {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,
+   0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+   0x01}}, /* 0x3b */
+ {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+   0x00}}, /* 0x3c */
+ {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
+   0x01}}, /* 0x3d */
+ {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15,
+   0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02,
+   0x00}}, /* 0x3e */
+ {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
+   0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
+   0x00}}, /* 0x3f */
+ /* TW: New from 650/LVDS BIOS */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+   0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
+   0x01}},  /* 0x40 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+   0x01}},  /* 0x41 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,
+   0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
+   0x01}},  /* 0x42 */
+ {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10,
+   0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03,
+   0x00}}   /* 0x43 */
 };
 
-typedef struct _SiS310_MCLKDataStruct {
-	UCHAR SR28, SR29, SR2A;
+typedef struct _SiS310_MCLKDataStruct
+{
+	UCHAR SR28,SR29,SR2A;
 	USHORT CLOCK;
 } SiS310_MCLKDataStruct;
-SiS310_MCLKDataStruct SiS310_MCLKData[] = {
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166}
+
+SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
+{
+	{ 0x3b,0x22,0x01,143},   /* TW: Was { 0x5c,0x23,0x01,166}, */
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166}
 };
 
-typedef struct _SiS310_ECLKDataStruct {
-	UCHAR SR2E, SR2F, SR30;
-	USHORT CLOCK;
+SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =	/* @ 0x54 */
+{
+	{ 0x5a,0x64,0x82, 66},
+	{ 0xb3,0x45,0x82, 83},
+	{ 0x37,0x61,0x82,100},
+	{ 0x37,0x22,0x82,133},
+	{ 0x37,0x61,0x82,100},
+	{ 0x37,0x22,0x82,133},
+	{ 0x37,0x22,0x82,133},
+	{ 0x37,0x22,0x82,133}
+};
+
+SiS310_MCLKDataStruct SiS310_MCLKData_1[] =	/* @ 0x155 */
+{
+        { 0x29,0x21,0x82,150},
+	{ 0x5c,0x23,0x82,166},
+	{ 0x65,0x23,0x82,183},
+	{ 0x37,0x21,0x82,200},
+	{ 0x37,0x22,0x82,133},
+	{ 0x37,0x22,0x82,133},
+	{ 0x37,0x22,0x82,133},
+	{ 0x37,0x22,0x82,133}
+};
+
+typedef struct _SiS310_ECLKDataStruct
+{
+ 	UCHAR SR2E,SR2F,SR30;
+ 	USHORT CLOCK;
 } SiS310_ECLKDataStruct;
-SiS310_ECLKDataStruct SiS310_ECLKData[] = {
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166}
+SiS310_ECLKDataStruct SiS310_ECLKData[]=
+{
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166}
 };
 
-typedef struct _SiS310_VCLKDataStruct {
-	UCHAR SR2B, SR2C;
+typedef struct _SiS310_VCLKDataStruct
+{
+	UCHAR SR2B,SR2C;
 	USHORT CLOCK;
 } SiS310_VCLKDataStruct;
-SiS310_VCLKDataStruct SiS310_VCLKData[] = {
-	{0x1b, 0xe1, 25},	/* 0x0 */
-	{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 */
-	{0x6c, 0xc3, 65},	/* 0xb */
-	{0x46, 0x44, 67},	/* 0xc */
-	{0xb1, 0x46, 68},	/* 0xd */
-	{0xd3, 0x4a, 72},	/* 0xe */
-	{0x29, 0x61, 75},	/* 0xf */
-	{0x6e, 0x46, 76},	/* 0x10 */
-	{0x2b, 0x61, 78},	/* 0x11 */
-	{0x31, 0x42, 79},	/* 0x12 */
-	{0xab, 0x44, 83},	/* 0x13 */
-	{0x46, 0x25, 84},	/* 0x14 */
-	{0x78, 0x29, 86},	/* 0x15 */
-	{0x62, 0x44, 94},	/* 0x16 */
-	{0x2b, 0x41, 104},	/* 0x17 */
-	{0x3a, 0x23, 105},	/* 0x18 */
-	{0x70, 0x44, 108},	/* 0x19 */
-	{0x3c, 0x23, 109},	/* 0x1a */
-	{0x5e, 0x43, 113},	/* 0x1b */
-	{0xbc, 0x44, 116},	/* 0x1c */
-	{0xe0, 0x46, 132},	/* 0x1d */
-	{0x54, 0x42, 135},	/* 0x1e */
-	{0xea, 0x2a, 139},	/* 0x1f */
-	{0x41, 0x22, 157},	/* 0x20 */
-	{0x70, 0x24, 162},	/* 0x21 */
-	{0x30, 0x21, 175},	/* 0x22 */
-	{0x4e, 0x22, 189},	/* 0x23 */
-	{0xde, 0x26, 194},	/* 0x24 */
-	{0x62, 0x06, 202},	/* 0x25 */
-	{0x3f, 0x03, 229},	/* 0x26 */
-	{0xb8, 0x06, 234},	/* 0x27 */
-	{0x34, 0x02, 253},	/* 0x28 */
-	{0x58, 0x04, 255},	/* 0x29 */
-	{0x24, 0x01, 265},	/* 0x2a */
-	{0x9b, 0x02, 267},	/* 0x2b */
-	{0x70, 0x05, 270},	/* 0x2c */
-	{0x25, 0x01, 272},	/* 0x2d */
-	{0x9c, 0x02, 277},	/* 0x2e */
-	{0x27, 0x01, 286},	/* 0x2f */
-	{0x3c, 0x02, 291},	/* 0x30 */
-	{0xef, 0x0a, 292},	/* 0x31 */
-	{0xf6, 0x0a, 310},	/* 0x32 */
-	{0x95, 0x01, 315},	/* 0x33 */
-	{0xf0, 0x09, 324},	/* 0x34 */
-	{0xfe, 0x0a, 331},	/* 0x35 */
-	{0xf3, 0x09, 332},	/* 0x36 */
-	{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 */
-	{0x31, 0xc2, 39}	/* 0x40 */
+
+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 */
+	{ 0x6e,0x46, 76}, /* 0x10 */
+	{ 0x2b,0x61, 78}, /* 0x11 */
+	{ 0x31,0x42, 79}, /* 0x12 */
+	{ 0xab,0x44, 83}, /* 0x13 */
+	{ 0x46,0x25, 84}, /* 0x14 */
+	{ 0x78,0x29, 86}, /* 0x15 */
+	{ 0x62,0x44, 94}, /* 0x16 */
+	{ 0x2b,0x41,104}, /* 0x17 */
+	{ 0x3a,0x23,105}, /* 0x18 */
+	{ 0x70,0x44,108}, /* 0x19 */
+	{ 0x3c,0x23,109}, /* 0x1a */
+	{ 0x5e,0x43,113}, /* 0x1b */
+	{ 0xbc,0x44,116}, /* 0x1c */
+	{ 0xe0,0x46,132}, /* 0x1d */
+	{ 0x54,0x42,135}, /* 0x1e */
+	{ 0xea,0x2a,139}, /* 0x1f */
+	{ 0x41,0x22,157}, /* 0x20 */
+	{ 0x70,0x24,162}, /* 0x21 */
+	{ 0x30,0x21,175}, /* 0x22 */
+	{ 0x4e,0x22,189}, /* 0x23 */
+	{ 0xde,0x26,194}, /* 0x24 */
+	{ 0x62,0x06,202}, /* 0x25 */
+	{ 0x3f,0x03,229}, /* 0x26 */
+	{ 0xb8,0x06,234}, /* 0x27 */
+	{ 0x34,0x02,253}, /* 0x28 */
+	{ 0x58,0x04,255}, /* 0x29 */
+	{ 0x24,0x01,265}, /* 0x2a */
+	{ 0x9b,0x02,267}, /* 0x2b */
+	{ 0x70,0x05,270}, /* 0x2c */
+	{ 0x25,0x01,272}, /* 0x2d */
+	{ 0x9c,0x02,277}, /* 0x2e */
+	{ 0x27,0x01,286}, /* 0x2f */
+	{ 0x3c,0x02,291}, /* 0x30 */
+	{ 0xef,0x0a,292}, /* 0x31 */
+	{ 0xf6,0x0a,310}, /* 0x32 */
+	{ 0x95,0x01,315}, /* 0x33 */
+	{ 0xf0,0x09,324}, /* 0x34 */
+	{ 0xfe,0x0a,331}, /* 0x35 */
+	{ 0xf3,0x09,332}, /* 0x36 */
+	{ 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 */
+	{ 0x31,0xc2, 39}, /* 0x40 */
+	/* TW: 650/LVDS BIOS @ 0x574b new: */
+	{ 0x60,0x36, 30}, /* 0x41 */  /* Chrontel */
+	{ 0x40,0x4a, 28}, /* 0x42 */  /* Chrontel */
+	{ 0x9f,0x46, 44}, /* 0x43 */  /* Chrontel */
+	{ 0x97,0x2c, 26}, /* 0x44 */
+	{ 0x44,0xe4, 25}, /* 0x45 */  /* Chrontel */
+	{ 0x7e,0x32, 47}, /* 0x46 */  /* Chrontel */
+	{ 0x8a,0x24, 31}, /* 0x47 */  /* Chrontel */
+	{ 0x97,0x2c, 26}, /* 0x48 */  /* Chrontel */
+	{ 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 */
+	{ 0x66,0x43,123}, /* 0x4d */  /* Modes 0x26-0x28 (1400x1050) */
+	{ 0x41,0x4e, 21}, /* 0x4e */
+	{ 0xa1,0x4a, 29}, /* 0x4f */  /* Chrontel */
+	{ 0x19,0x42, 42}, /* 0x50 */
+	{ 0x54,0x46, 58}, /* 0x51 */  /* Chrontel */
+	{ 0x25,0x42, 61}, /* 0x52 */
+	{ 0x44,0x44, 66}, /* 0x53 */  /* Chrontel */
+	{ 0x3a,0x62, 70}  /* 0x54 */  /* Chrontel */
 };
 
-typedef struct _SiS310_VBVCLKDataStruct {
-	UCHAR Part4_A, Part4_B;
+typedef struct _SiS310_VBVCLKDataStruct
+{
+	UCHAR Part4_A,Part4_B;
 	USHORT CLOCK;
 } SiS310_VBVCLKDataStruct;
-SiS310_VBVCLKDataStruct SiS310_VBVCLKData[] = {
-	{0x1b, 0xe1, 25},	/* 0x0 */
-	{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 */
-	{0x5a, 0x64, 65},	/* 0xb */
-	{0x46, 0x44, 67},	/* 0xc */
-	{0xb1, 0x46, 68},	/* 0xd */
-	{0xd3, 0x4a, 72},	/* 0xe */
-	{0x29, 0x61, 75},	/* 0xf */
-	{0x6d, 0x46, 75},	/* 0x10 */
-	{0x41, 0x43, 78},	/* 0x11 */
-	{0x31, 0x42, 79},	/* 0x12 */
-	{0xab, 0x44, 83},	/* 0x13 */
-	{0x46, 0x25, 84},	/* 0x14 */
-	{0x78, 0x29, 86},	/* 0x15 */
-	{0x62, 0x44, 94},	/* 0x16 */
-	{0x2b, 0x22, 104},	/* 0x17 */
-	{0x49, 0x24, 105},	/* 0x18 */
-	{0xf8, 0x2f, 108},	/* 0x19 */
-	{0x3c, 0x23, 109},	/* 0x1a */
-	{0x5e, 0x43, 113},	/* 0x1b */
-	{0xbc, 0x44, 116},	/* 0x1c */
-	{0xe0, 0x46, 132},	/* 0x1d */
-	{0xd4, 0x28, 135},	/* 0x1e */
-	{0xea, 0x2a, 139},	/* 0x1f */
-	{0x41, 0x22, 157},	/* 0x20 */
-	{0x70, 0x24, 162},	/* 0x21 */
-	{0x30, 0x21, 175},	/* 0x22 */
-	{0x4e, 0x22, 189},	/* 0x23 */
-	{0xde, 0x26, 194},	/* 0x24 */
-	{0x70, 0x07, 202},	/* 0x25 */
-	{0x3f, 0x03, 229},	/* 0x26 */
-	{0xb8, 0x06, 234},	/* 0x27 */
-	{0x34, 0x02, 253},	/* 0x28 */
-	{0x58, 0x04, 255},	/* 0x29 */
-	{0x24, 0x01, 265},	/* 0x2a */
-	{0x9b, 0x02, 267},	/* 0x2b */
-	{0x70, 0x05, 270},	/* 0x2c */
-	{0x25, 0x01, 272},	/* 0x2d */
-	{0x9c, 0x02, 277},	/* 0x2e */
-	{0x27, 0x01, 286},	/* 0x2f */
-	{0x3c, 0x02, 291},	/* 0x30 */
-	{0xef, 0x0a, 292},	/* 0x31 */
-	{0xf6, 0x0a, 310},	/* 0x32 */
-	{0x95, 0x01, 315},	/* 0x33 */
-	{0xf0, 0x09, 324},	/* 0x34 */
-	{0xfe, 0x0a, 331},	/* 0x35 */
-	{0xf3, 0x09, 332},	/* 0x36 */
-	{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 */
-	{0x31, 0xc2, 39}	/* 0x40 */
+
+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 */
+	{ 0x6d,0x46, 75}, /* 0x10 */
+	{ 0x41,0x43, 78}, /* 0x11 */
+	{ 0x31,0x42, 79}, /* 0x12 */
+	{ 0xab,0x44, 83}, /* 0x13 */
+	{ 0x46,0x25, 84}, /* 0x14 */
+	{ 0x78,0x29, 86}, /* 0x15 */
+	{ 0x62,0x44, 94}, /* 0x16 */
+	{ 0x2b,0x22,104}, /* 0x17 */
+	{ 0x49,0x24,105}, /* 0x18 */
+	{ 0xf8,0x2f,108}, /* 0x19 */
+	{ 0x3c,0x23,109}, /* 0x1a */
+	{ 0x5e,0x43,113}, /* 0x1b */
+	{ 0xbc,0x44,116}, /* 0x1c */
+	{ 0xe0,0x46,132}, /* 0x1d */
+	{ 0xd4,0x28,135}, /* 0x1e */
+	{ 0xea,0x2a,139}, /* 0x1f */
+	{ 0x41,0x22,157}, /* 0x20 */
+	{ 0x70,0x24,162}, /* 0x21 */
+	{ 0x30,0x21,175}, /* 0x22 */
+	{ 0x4e,0x22,189}, /* 0x23 */
+	{ 0xde,0x26,194}, /* 0x24 */
+	{ 0x70,0x07,202}, /* 0x25 */
+	{ 0x3f,0x03,229}, /* 0x26 */
+	{ 0xb8,0x06,234}, /* 0x27 */
+	{ 0x34,0x02,253}, /* 0x28 */
+	{ 0x58,0x04,255}, /* 0x29 */
+	{ 0x24,0x01,265}, /* 0x2a */
+	{ 0x9b,0x02,267}, /* 0x2b */
+	{ 0x70,0x05,270}, /* 0x2c */
+	{ 0x25,0x01,272}, /* 0x2d */
+	{ 0x9c,0x02,277}, /* 0x2e */
+	{ 0x27,0x01,286}, /* 0x2f */
+	{ 0x3c,0x02,291}, /* 0x30 */
+	{ 0xef,0x0a,292}, /* 0x31 */
+	{ 0xf6,0x0a,310}, /* 0x32 */
+	{ 0x95,0x01,315}, /* 0x33 */
+	{ 0xf0,0x09,324}, /* 0x34 */
+	{ 0xfe,0x0a,331}, /* 0x35 */
+	{ 0xf3,0x09,332}, /* 0x36 */
+	{ 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 */
+	{ 0x31,0xc2, 39}, /* 0x40 */
+	/* TW: 650/LVDS+301 BIOS (@ 0x58a0 in LVDS) new: */
+	{ 0x2e,0x48, 25}, /* 0x41 */
+	{ 0x24,0x46, 25}, /* 0x42 */
+	{ 0x26,0x64, 28}, /* 0x43 */
+	{ 0x37,0x64, 40}, /* 0x44 */
+	{ 0xa1,0x42,108}, /* 0x45 */
+	{ 0x37,0x61,100}, /* 0x46 */
+	{ 0x78,0x27,108}  /* 0x47 */
+	/* --- 0x58bc --- */
 };
 
-UCHAR SiS310_ScreenOffset[] =
-    { 0x14, 0x19, 0x20, 0x28, 0x32, 0x40, 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35 };
+UCHAR SiS310_ScreenOffset[]= { 0x14,0x19,0x20,0x28,0x32,0x40,
+                               0x50,0x64,0x78,0x80,0x2d,0x35,0x57};  /* TW: Added 1400x1050 offset */
 
-typedef struct _SiS310_StResInfoStruct {
+typedef struct _SiS310_StResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
 } SiS310_StResInfoStruct;
-SiS310_StResInfoStruct SiS310_StResInfo[] = {
-	{640, 400},
-	{640, 350},
-	{720, 400},
-	{720, 350},
-	{640, 480}
+
+SiS310_StResInfoStruct SiS310_StResInfo[]=
+{
+	{ 640,400},
+	{ 640,350},
+	{ 720,400},
+	{ 720,350},
+	{ 640,480}
 };
 
-typedef struct _SiS310_ModeResInfoStruct {
+typedef struct _SiS310_ModeResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
-	UCHAR XChar;
-	UCHAR YChar;
+	UCHAR  XChar;
+	UCHAR  YChar;
 } SiS310_ModeResInfoStruct;
-SiS310_ModeResInfoStruct SiS310_ModeResInfo[] = {
-	{320, 200, 8, 8},
-	{320, 240, 8, 8},
-	{320, 400, 8, 8},
-	{400, 300, 8, 8},
-	{512, 384, 8, 8},
-	{640, 400, 8, 16},
-	{640, 480, 8, 16},
-	{800, 600, 8, 16},
-	{1024, 768, 8, 16},
-	{1280, 1024, 8, 16},
-	{1600, 1200, 8, 16},
-	{1920, 1440, 8, 16},
-	{2048, 1536, 8, 16},
-	{720, 480, 8, 16},
-	{720, 576, 8, 16},
-	{1280, 960, 8, 16},
-	{800, 480, 8, 16},
-	{1024, 576, 8, 16},
-	{1280, 720, 8, 16}
+
+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 19; TW: New from 650/LVDS BIOS */
+	{ 1280, 768, 8,16},   /* 0x14 20; TW: New from 650/LVDS BIOS */
+	{ 1400,1050, 8,16}    /* 0x15 21; TW: New from 650/LVDS BIOS */
 };
 
 UCHAR SiS310_OutputSelect = 0x40;
-UCHAR SiS310_SoftSetting = 30;
+
+UCHAR SiS310_SoftSetting  = 0x30;   /* TW: RAM setting */
+
 UCHAR SiS310_SR07 = 0x18;
-UCHAR SiS310_SR15[8][4] = {
-	{0x0, 0x4, 0x60, 0x60},
-	{0xf, 0xf, 0xf, 0xf},
-	{0xba, 0xba, 0xba, 0xba},
-	{0xa9, 0xa9, 0xac, 0xac},
-	{0xa0, 0xa0, 0xa0, 0xa8},
-	{0x0, 0x0, 0x2, 0x2},
-	{0x30, 0x30, 0x40, 0x40},
-	{0x0, 0xa5, 0xfb, 0xf6}
-};
-UCHAR SiS310_CR40[5][4] = {
-	{0x77, 0x77, 0x33, 0x33},
-	{0x77, 0x77, 0x33, 0x33},
-	{0x0, 0x0, 0x0, 0x0},
-	{0x5b, 0x5b, 0x3, 0x3},
-	{0x0, 0x0, 0xf0, 0xf8}
+
+UCHAR SiS310_SR15[8][4]={
+	{0x00,0x04,0x60,0x60},
+	{0x0f,0x0f,0x0f,0x0f},
+	{0xba,0xba,0xba,0xba},
+	{0xa9,0xa9,0xac,0xac},
+	{0xa0,0xa0,0xa0,0xa8},
+	{0x00,0x00,0x02,0x02},
+ 	{0x30,0x30,0x40,0x40},
+	{0x00,0xa5,0xfb,0xf6}
+};
+
+UCHAR SiS310_CR40[5][4]={
+	{0x77,0x77,0x33,0x33},
+	{0x77,0x77,0x33,0x33},
+	{0x00,0x00,0x00,0x00},
+	{0x5b,0x5b,0x03,0x03},
+	{0x00,0x00,0xf0,0xf8}
 };
-UCHAR SiS310_CR49[] = { 0xaa, 0x88 };
+
+UCHAR SiS310_CR49[] = {0xaa,0x88};
 UCHAR SiS310_SR1F = 0x0;
 UCHAR SiS310_SR21 = 0xa5;
 UCHAR SiS310_SR22 = 0xfb;
 UCHAR SiS310_SR23 = 0xf6;
 UCHAR SiS310_SR24 = 0xd;
-UCHAR SiS310_SR25[] = { 0x33, 0x3 };
-UCHAR SiS310_SR31 = 0x0;
+UCHAR SiS310_SR25[] = {0x33,0x3};
+UCHAR SiS310_SR31 = 0x00;
 UCHAR SiS310_SR32 = 0x11;
-UCHAR SiS310_SR33 = 0x0;
-UCHAR SiS310_CRT2Data_1_2 = 0x0;
-UCHAR SiS310_CRT2Data_4_D = 0x0;
-UCHAR SiS310_CRT2Data_4_E = 0x0;
+UCHAR SiS310_SR33 = 0x00;
+UCHAR SiS310_CRT2Data_1_2 = 0x00;
+UCHAR SiS310_CRT2Data_4_D = 0x00;
+UCHAR SiS310_CRT2Data_4_E = 0x00;
 UCHAR SiS310_CRT2Data_4_10 = 0x80;
-USHORT SiS310_RGBSenseData = 0xd1;
-USHORT SiS310_VideoSenseData = 0xb9;
-USHORT SiS310_YCSenseData = 0xb3;
-USHORT SiS310_RGBSenseData2 = 0x0190;	/*301b */
+USHORT SiS310_RGBSenseData    = 0xd1;
+USHORT SiS310_VideoSenseData  = 0xb9;
+USHORT SiS310_YCSenseData     = 0xb3;
+USHORT SiS310_RGBSenseData2   = 0x0190;     /*301b*/
 USHORT SiS310_VideoSenseData2 = 0x0174;
 USHORT SiS310_YCSenseData2 = 0x016b;
-UCHAR SiS310_NTSCPhase[] = { 0x21, 0xed, 0x8a, 0x8 };
-UCHAR SiS310_PALPhase[] = { 0x2a, 0x5, 0xd3, 0x0 };
-UCHAR SiS310_NTSCPhase2[] = { 0x21, 0xF0, 0x7B, 0xD6 };	/*301b */
-UCHAR SiS310_PALPhase2[] = { 0x2a, 0x09, 0x86, 0xe9 };
-UCHAR SiS310_PALMPhase[] = { 0x21, 0xE4, 0x2E, 0x9B };	/*palmn */
-UCHAR SiS310_PALNPhase[] = { 0x21, 0xF4, 0x3E, 0xBA };
+UCHAR SiS310_NTSCPhase[]  = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
+UCHAR SiS310_PALPhase[]   = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00}; */
+UCHAR SiS310_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};
+UCHAR SiS310_PALPhase2[]  = {0x2a,0x09,0x86,0xe9};
+UCHAR SiS310_PALMPhase[]  = {0x21,0xE4,0x2E,0x9B}; /* TW: palm*/
+UCHAR SiS310_PALNPhase[]  = {0x21,0xF4,0x3E,0xBA}; /* TW: paln*/
+UCHAR SiS310_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
+UCHAR SiS310_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
 
-typedef struct _SiS310_LCDDataStruct {
+typedef struct _SiS310_LCDDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -1147,99 +1238,132 @@
 	USHORT LCDHT;
 	USHORT LCDVT;
 } SiS310_LCDDataStruct;
-SiS310_LCDDataStruct SiS310_StLCD1024x768Data[] = {
-	{62, 25, 800, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{104, 45, 945, 496, 1344, 806},
-	{62, 25, 800, 546, 1344, 806},
-	{31, 18, 1008, 624, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-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}
-};
-
-SiS310_LCDDataStruct SiS310_St2LCD1024x768Data[] = {
-	{62, 25, 800, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{104, 45, 945, 496, 1344, 806},
-	{62, 25, 800, 546, 1344, 806},
-	{31, 18, 1008, 624, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS310_LCDDataStruct SiS310_StLCD1280x1024Data[] = {
-	{22, 5, 800, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] = {
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 500, 1688, 1066},
-	{211, 75, 1024, 625, 1688, 1066},
-	{211, 120, 1280, 798, 1688, 1066},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_St2LCD1280x1024Data[] = {
-	{22, 5, 800, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_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}
-};
-
-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}
+
+SiS310_LCDDataStruct  SiS310_StLCD1024x768Data[]=
+{
+	{   62,  25, 800, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{  104,  45, 945, 496,1344, 806},
+	{   62,  25, 800, 546,1344, 806},
+	{   31,  18,1008, 624,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =   /* TW: Checked */
+{
+	{   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}
+};
+
+SiS310_LCDDataStruct  SiS310_St2LCD1024x768Data[] =  /* TW: Checked */
+{
+	{   62,  25, 800, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+/*	{   32,  15, 930, 546,1344, 806},   */
+        {   62,  25, 800, 546,1344, 806},    /* TW: Different in 650/301LV BIOS */
+	{  104,  45, 945, 496,1344, 806},
+	{   62,  25, 800, 546,1344, 806},
+	{   31,  18,1008, 624,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+SiS310_LCDDataStruct  SiS310_StLCD1280x1024Data[] =
+{
+	{   22,   5, 800, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{   13,   5,1024, 675,1560,1152},
+	{   16,   9,1266, 804,1688,1072},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] =  /* TW: Checked */
+{
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 500,1688,1066},
+	{  211,  75,1024, 625,1688,1066},
+	{  211, 120,1280, 798,1688,1066},
+	{    1,   1,1688,1066,1688,1066}
 };
 
-typedef struct _SiS310_TVDataStruct {
+SiS310_LCDDataStruct  SiS310_St2LCD1280x1024Data[] =
+{
+	{   22,   5, 800, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{   13,   5,1024, 675,1560,1152},
+	{   16,   9,1266, 804,1688,1072},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_NoScaleData1024x768[] =  /* TW: Checked */
+{
+        {    1,   1,1344, 806,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+#if 0
+	{    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}
+#endif
+};
+
+SiS310_LCDDataStruct  SiS310_NoScaleData1280x1024[] =  /* TW: New; Checked */
+{
+        {    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}
+};
+
+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}
+};
+
+typedef struct _SiS310_TVDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -1254,1351 +1378,2259 @@
 	UCHAR RY3COE;
 	UCHAR RY4COE;
 } SiS310_TVDataStruct;
-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}
+
+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}
 };
 
-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},
-	{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}	/*301b */
+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},
+ {   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}     /*301b*/
 };
 
-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}
+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}
 };
 
-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},
-	{143, 120, 1056, 643, 1270, 440, 0, 128, 0, 0xf4, 0x10, 0x1c, 0x00},
-	{2, 1, 858, 503, 1270, 480, 0, 128, 0, 0xee, 0x0c, 0x22, 0x08},
-	{65, 64, 1056, 791, 1270, 480, 638, 0, 0, 0xEE, 0x0C, 0x22, 0x08}	/*301b */
+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},
+ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
+ {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},
+ {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} /*301b*/     
 };
 
-SiS310_TVDataStruct SiS310_St1HiTVData[] = {
-	{0x00}
+/* TW: These tables will need data ! */
+SiS310_TVDataStruct  SiS310_St1HiTVData[]=
+{
+   	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+SiS310_TVDataStruct  SiS310_St2HiTVData[]=
+{
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-SiS310_TVDataStruct SiS310_St2HiTVData[] = {
-	{0x00}
+SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
+{
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-SiS310_TVDataStruct SiS310_ExtHiTVData[] = {
-	{0x00}
+UCHAR SiS310_NTSCTiming[] = {   /* TW: New */
+	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
+};
+
+UCHAR SiS310_PALTiming[] = {   /* TW: New */
+	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
+};
+
+UCHAR SiS310_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
+};
+
+UCHAR SiS310_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
+};
+
+UCHAR SiS310_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
+};
+
+UCHAR SiS310_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
+};
+
+UCHAR SiS310_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
+};
+
+UCHAR SiS310_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
+};
+
+UCHAR SiS310_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
 };
 
-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
+typedef struct _SiS310_PanelDelayTblStruct
+{
+ 	UCHAR timer[2];
+} SiS310_PanelDelayTblStruct;
+
+SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=  /* TW: New 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}},
+	{{0x28,0xc8}}
 };
 
-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
+SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=  
+{
+	{{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}},
+	{{0x28,0xc8}}
 };
 
-UCHAR SiS310_HiTVExtTiming[] = { 0x00 };
+typedef struct _SiS310_LVDSDataStruct
+{
+	USHORT VGAHT;
+	USHORT VGAVT;
+	USHORT LCDHT;
+	USHORT LCDVT;
+} SiS310_LVDSDataStruct;
+
+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}
+};
 
-UCHAR SiS310_HiTVSt1Timing[] = { 0x00 };
+SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_1[]=   /* TW: New */
+{
+	{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}
+};
 
-UCHAR SiS310_HiTVSt2Timing[] = { 0x00 };
+SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_2[]=   /* TW: New */
+{
+	{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}
+};
 
-UCHAR SiS310_HiTVTextTiming[] = { 0x00 };
+SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_1[]=   /* TW: New */
+{
+	{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}
+};
 
-UCHAR SiS310_HiTVGroup3Data[] = { 0x00 };
+SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_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}
+};
 
-UCHAR SiS310_HiTVGroup3Simu[] = { 0x00 };
+SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_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}
+};
 
-UCHAR SiS310_HiTVGroup3Text[] = { 0x00 };
+SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_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}
+};
 
-typedef struct _SiS310_PanelDelayTblStruct {
-	UCHAR timer[2];
-} SiS310_PanelDelayTblStruct;
-SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[] = {
-	{{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}}
+SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_1[]=   /* TW: New */
+{
+        {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}
 };
 
-typedef struct _SiS310_LVDSDataStruct {
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT LCDHT;
-	USHORT LCDVT;
-} SiS310_LVDSDataStruct;
-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}
-};
-
-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}
-};
-
-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},
-	{1050, 638, 1344, 806},
-	{1344, 806, 1344, 806},
-	{800, 449, 1280, 801},
-	{800, 525, 1280, 813}
-};
-
-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}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_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}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_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}
+SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_2[]=   /* TW: New */
+{
+        {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},
+};
+
+/* TW: New: - from 300 series */
+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}
+};
+
+/* TW: New: - from 300 series */
+SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_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: New: - from 300 series */
+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}
 };
 
-SiS310_LVDSDataStruct SiS310_LVDS640x480Data_1[] = {
+/* TW: New: - from 300 series */
+SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_2[]=
+{
+	{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}
+};
+
+/* TW: New in 650/LVDS BIOS - resolution unknown */
+SiS310_LVDSDataStruct  SiS310_LVDSXXXxXXXData_1[]=   /* TW: New */
+{
+        { 800, 449, 800, 449},
+	{ 800, 449, 800, 449},
+	{ 900, 449, 900, 449},
+	{ 900, 449, 900, 449},
+	{ 800, 525, 800, 525},
+	{1056, 628,1056, 628},
+	{1344, 806,1344, 806},
+	{1688, 806,1688, 806}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS640x480Data_1[]=   /* TW: New */
+{
 	{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}
-};
-
-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}
-};
-
-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}
-};
-
-SiS310_LVDSDataStruct SiS310_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}
-};
-
-SiS310_LVDSDataStruct SiS310_CHTVOPALData[] = {
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{840, 625, 840, 625},
-	{960, 750, 960, 750}
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628}
+};
+
+SiS310_LVDSDataStruct  SiS310_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}
+};
+
+SiS310_LVDSDataStruct  SiS310_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}
+};
+
+SiS310_LVDSDataStruct  SiS310_CHTVUNTSCData[]=   /* TW: New */
+{
+	{ 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 */
+};
+
+SiS310_LVDSDataStruct  SiS310_CHTVONTSCData[]=   /* TW: New */
+{
+	{ 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 */
+};
+
+SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=   /* TW: New */
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{ 840, 625, 840, 625},
+	{ 960, 750, 960, 750},
+	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
 };
 
-typedef struct _SiS310_LVDSDesStruct {
+SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]=   /* TW: New */
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{ 840, 625, 840, 625},
+	{ 944, 625, 944, 625},
+        {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
+};
+
+typedef struct _SiS310_LVDSDesStruct
+{
 	USHORT LCDHDES;
 	USHORT LCDVDES;
 } SiS310_LVDSDesStruct;
-SiS310_LVDSDesStruct SiS310_PanelType00_1[] = {
-	{0, 626},
-	{0, 624},
-	{0, 626},
-	{0, 624},
-	{0, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+
+/* TW: PanelType arrays taken from 650/LVDS BIOS 1.10.0 */
+
+SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=   /* TW: New */
+{
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType01_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType02_1[] = {
-	{0, 626},
-	{0, 624},
-	{0, 626},
-	{0, 624},
-	{0, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType03_1[] = {
-	{8, 436},
-	{8, 440},
-	{8, 436},
-	{8, 440},
-	{8, 512},
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794}
+SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=   /* TW: New */
+{
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 805},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType04_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=   /* TW: New */
+{
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 1065},
+	{ 0, 0},
+	{ 0, 0}
+};
+
+
+SiS310_LVDSDesStruct  SiS310_PanelType03_1[]=   /* TW: New */
+{
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=   /* TW: New */
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType05_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType05_1[]=   /* TW: New */
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType06_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=   /* TW: New */
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType07_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType07_1[]=   /* TW: New */
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType08_1[] = {
-	{1059, 626},
-	{1059, 624},
-	{1059, 626},
-	{1059, 624},
-	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=   /* TW: New */
+{
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType09_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+SiS310_LVDSDesStruct  SiS310_PanelType09_1[]=   /* TW: New */
+{
+	{ 0, 448},
+	{ 0, 448},
+	{ 0, 448},
+	{ 0, 448},
+	{ 0, 524},
+	{ 0, 627},
+	{ 0, 805},
+	{ 0, 805},
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0a_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=   /* TW: New */
+{
 	{1059, 626},
 	{1059, 624},
 	{1059, 626},
 	{1059, 624},
 	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0b_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=   /* TW: New */
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0c_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=   /* TW: New */
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0d_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=   /* TW: New */
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0e_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=   /* TW: New */
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0f_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=   /* TW: New */
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType00_2[] = {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=   /* TW: New */
+{
+	{980, 528},
+	{980, 503},
+	{980, 528},
+	{980, 503},
+	{980, 568},
+	{ 0, 628},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType01_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType01_2[]=   /* TW: New */
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 806},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType02_2[] = {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+SiS310_LVDSDesStruct  SiS310_PanelType02_2[]=   /* TW: New */
+{
+	{1368, 754},
+	{1368, 729},
+	{1368, 754},
+	{1368, 729},
+	{1368, 794},
+	{1448, 854},
+	{1560, 938},
+	{   0,1066},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType03_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{1152, 622},
-	{1152, 597}
+SiS310_LVDSDesStruct  SiS310_PanelType03_2[]=   /* TW: New */
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType04_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+SiS310_LVDSDesStruct  SiS310_PanelType04_2[]=   /* TW: New */
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType05_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=   /* TW: New */
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType06_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=   /* TW: New */
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType07_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=   /* TW: New */
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType08_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=   /* TW: New */
+{
 	{976, 527},
 	{976, 502},
 	{976, 527},
 	{976, 502},
 	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType09_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+SiS310_LVDSDesStruct  SiS310_PanelType09_2[]=   /* TW: New */
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0a_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=   /* TW: New */
+{
 	{976, 527},
 	{976, 502},
 	{976, 527},
 	{976, 502},
 	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0b_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=   /* TW: New */
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0c_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=   /* TW: New */
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0d_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0d_2[]=   /* TW: New */
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0e_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]=   /* TW: New */
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0f_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0f_2[] =   /* TW: New */
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-/*301b*/
-SiS310_LVDSDesStruct SiS310_PanelType1076_1[] = {
-	{0x00, 0x00}
-};
-SiS310_LVDSDesStruct SiS310_PanelType1210_1[] = {
-	{0x00, 0x00}
-};
-SiS310_LVDSDesStruct SiS310_PanelType1296_1[] = {
-	{0x00, 0x00}
-};
-SiS310_LVDSDesStruct SiS310_PanelType1076_2[] = {
-	{0x00, 0x00}
-};
-SiS310_LVDSDesStruct SiS310_PanelType1210_2[] = {
-	{0x00, 0x00}
-};
-SiS310_LVDSDesStruct SiS310_PanelType1296_2[] = {
-	{0x00, 0x00}
-};
-/*end 301b*/
-
-SiS310_LVDSDesStruct SiS310_CHTVUNTSCDesData[] = {
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVONTSCDesData[] = {
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVUPALDesData[] = {
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVOPALDesData[] = {
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{0, 0},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-/*add for LCDA*/
-typedef struct _SiS310_LCDACRT1DataStruct {
-	UCHAR CR[17];
-} SiS310_LCDACRT1DataStruct;
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_1[] = {
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0xaf, 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, 0x56, 0x83, 0xaf, 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, 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}}
+SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=   /* TW: New */
+{
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1[] = {
-	{{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
-	  0x60, 0x87, 0x5d, 0x5d, 0x83, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
-	  0x60, 0x87, 0x5d, 0x5d, 0x83, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x04, 0x3e,
-	  0xE2, 0x89, 0xDf, 0xDf, 0x05, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x87, 0x63, 0x63, 0x8B, 0x69, 0x1A, 0x7c, 0xf0,
-	  0x5A, 0x8F, 0x57, 0x57, 0x7D, 0x20, 0x00, 0x26,
-	  0x01}},
-	{{0xA3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xFf, 0xFf, 0x25, 0x10, 0x00, 0x02,
-	  0x01}}
+SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=   /* TW: New */
+{
+	{ 1152, 622 },
+	{ 1152, 597 },
+	{ 1152, 622 },
+	{ 1152, 597 },
+	{ 1152, 622 },
+	{ 1232, 722 },
+	{    0, 0   },
+	{    0, 794 },
+	{    0, 0   }
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_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}}
+SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=   /* TW: New */
+{
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_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}}
+SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=   /* TW: New */
+{
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1_H[] = {
-	{{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
-	  0x60, 0x87, 0x5D, 0x5D, 0x83, 0x01, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
-	  0x60, 0x87, 0x5D, 0x5D, 0x83, 0x01, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x04, 0x3e,
-	  0xE2, 0x89, 0xDf, 0xDf, 0x05, 0x00, 0x00, 0x44,
-	  0x00}},
-	{{0x41, 0x31, 0x31, 0x85, 0x35, 0x1d, 0x7c, 0xf0,
-	  0x5A, 0x8F, 0x57, 0x57, 0x7D, 0x20, 0x00, 0x55,
-	  0x01}},
-	{{0x4f, 0x3F, 0x3F, 0x93, 0x45, 0x0D, 0x24, 0xf5,
-	  0x02, 0x88, 0xFf, 0xFf, 0x25, 0x10, 0x00, 0x01,
-	  0x01}}
+SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=   /* TW: New */
+{
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1_H[] = {
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x04, 0x3e,
-	  0xe2, 0x89, 0xdf, 0x05, 0x00, 0x00, 0x04,
-	  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}}
+SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=   /* TW: New */
+{
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_2[] = {
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0xba,
-	  0x1c, 0x80, 0xdf, 0x73, 0x00, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x06,
-	  0x01}}
+SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]= 
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_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}}
+SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_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}}
+SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
+{
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_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}}
+SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
+{
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_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}}
+typedef struct _SiS310_Part2PortTblStruct
+{
+ 	UCHAR CR[12];
+} SiS310_Part2PortTblStruct;
+
+SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
+{
+ {{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,0x16,0x0c,0xe6,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}}
 };
 
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2_H[] = {
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x31, 0x93, 0x3e, 0x86, 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}}
+SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
+{
+ {{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}}
+};
+
+SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
+{
+ {{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,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_2[] =
+{
+ {{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}}
+};
+
+
+SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
+{
+ {{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}}
+};
+
+SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
+{
+ {{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}}
+};
+
+/*add for LCDA*/
+typedef struct _SiS310_LCDACRT1DataStruct
+{
+ 	UCHAR CR[17];
+}SiS310_LCDACRT1DataStruct;
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1[] =
+{
+ {{0x65,0x4f,0x89,0x56,0x83,0xaf,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,0x56,0x83,0xaf,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,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}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
+{
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
+   0x00}},
+ {{0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26,
+   0x01}},
+ {{0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_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}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_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}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
+{
+ {{0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x27,0x9B,0x2b,0x94,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x44,
+   0x00}},
+ {{0x41,0x31,0x31,0x85,0x35,0x1d,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
+   0x01}},
+ {{0x4f,0x3F,0x3F,0x93,0x45,0x0D,0x24,0xf5,
+   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x01,
+   0x01}}
 };
 
-typedef struct _SiS310_LVDSCRT1DataStruct {
-	UCHAR CR[15];
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
+{
+ {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+   0x00}},
+{{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+   0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+   0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+   0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+   0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
+   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}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2[]=
+{ 
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+   0x00}},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+   0x00}},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+   0x00}},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+   0x00}},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
+   0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_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}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_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}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_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}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_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 }}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
+{ 
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x31,0x93,0x3e,0x86,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 }}
+};
+
+typedef struct _SiS310_LVDSCRT1DataStruct
+{
+ 	UCHAR CR[15];
 } SiS310_LVDSCRT1DataStruct;
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] = {
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0xaf, 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, 0x56, 0x83, 0xaf, 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, 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}}
+
+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 }}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] = {
-	{{0x73, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x97, 0x55, 0x86, 0x04, 0x3e,
-	  0xE2, 0x89, 0xDf, 0x05, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x87, 0x63, 0x8B, 0x69, 0x1A, 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}}
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =   /* TW: New */
+{
+ {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0xfa,0x1f,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 }},
+ {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_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}}
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[] =    /* TW: New */
+{
+ {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x97,0x53,0x84,0x04,0x3e,
+   0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
+   0x00}},
+ {{0x87,0x63,0x8B,0x67,0x18,0x7c,0xf0,
+   0x5A,0x81,0x57,0x7D,0x00,0x00,0x06,
+   0x01}},
+ {{0xA3,0x7f,0x87,0x83,0x94,0x24,0xf5,
+   0x02,0x89,0xFf,0x25,0x10,0x00,0x02,
+   0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_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}}
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[] =    /* TW: New */
+{
+ {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f,
+   0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
+   0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f,
+   0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
+   0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f,
+   0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
+   0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f,
+   0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
+   0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0x08,0x3e,
+   0xe0,0x84,0xdf,0x09,0x00,0x00,0x06,
+   0x00 }},
+ {{0x92,0x63,0x96,0x6a,0x18,0x80,0xf0,
+   0x58,0x8c,0x57,0x81,0x20,0x00,0x06,
+   0x01 }},
+ {{0xae,0x7f,0x92,0x86,0x94,0x28,0xf5,
+   0x00,0x84,0xff,0x29,0x10,0x00,0x02,
+   0x01 }},
+ {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a,
+   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+   0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] = {
-	{{0x37, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
-	  0x60, 0x87, 0x5D, 0x83, 0x01, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
-	  0x60, 0x87, 0x5D, 0x83, 0x01, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x9B, 0x2b, 0x94, 0x04, 0x3e,
-	  0xE2, 0x89, 0xDf, 0x05, 0x00, 0x00, 0x44,
-	  0x00}},
-	{{0x41, 0x31, 0x85, 0x35, 0x1d, 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}}
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[] =    /* TW: New */
+{
+ {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 }},
+ {{0x4d,0x31,0x91,0x37,0x07,0x72,0xf0,
+   0x58,0x8d,0x57,0x73,0x20,0x00,0x01,
+   0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] = {
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x04, 0x3e,
-	  0xe2, 0x89, 0xdf, 0x05, 0x00, 0x00, 0x04,
-	  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}}
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[] =    /* TW: New */
+{
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+   0x00 }},
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
+   0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
+   0x00}},
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
+   0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
+   0x00}},
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0x04,0x3e,
+   0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
+   0x00}},
+ {{0x55,0x31,0x99,0x35,0x06,0x7c,0xf0,
+   0x5A,0x81,0x57,0x7D,0x00,0x00,0x01,
+   0x01}},
+ {{0x63,0x3F,0x87,0x43,0x94,0x24,0xf5,
+   0x02,0x89,0xFf,0x25,0x10,0x00,0x01,
+   0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[] = {
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0xba,
-	  0x1c, 0x80, 0xdf, 0x73, 0x00, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x06,
-	  0x01}}
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[] =   /* TW: New */
+{
+ {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f,
+   0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
+   0x00 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f,
+   0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
+   0x00 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f,
+   0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
+   0x00 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f,
+   0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
+   0x01 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0x08,0x3e,
+   0xe0,0x84,0xdf,0x09,0x00,0x00,0x05,
+   0x00 }},
+ {{0x60,0x31,0x84,0x38,0x86,0x80,0xf0,
+   0x58,0x8c,0x57,0x81,0x20,0x00,0x01,
+   0x01 }},
+ {{0x6e,0x3f,0x92,0x46,0x94,0x28,0xf5,
+   0x00,0x84,0xff,0x29,0x10,0x00,0x01,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=   /* TW: New */
+{
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
+   0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
+   0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
+   0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
+   0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
+   0x27,0x8c,0xdf,0x73,0x00,0x00,0x06,
+   0x00 }},
+ {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
+   0x58,0x8d,0x57,0x73,0x20,0x00,0x06,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[] =   /* TW: New */
+{ 
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
+   0x01 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x7f,0x86,0xdf,0x25,0x10,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xbb,0x82,0x57,0x25,0x10,0x00,0x02,
+   0x01 }},
+ {{0xa3,0x7f,0x87,0x83,0x94,0x24,0xf5,
+   0x02,0x89,0xff,0x25,0x10,0x00,0x02,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[] =  /* TW: New */
+{
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
+   0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+   0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
+   0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
+   0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+   0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
+   0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9e,
+   0x03,0x87,0xdf,0x29,0x01,0x00,0x03,
+   0x00 }},
+ {{0xce,0x63,0x92,0x8b,0x19,0x28,0xd4,
+   0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
+   0x01 }},
+ {{0xce,0x7f,0x92,0x99,0x07,0x28,0xd4,
+   0x93,0x87,0xff,0x29,0x21,0x00,0x07,
+   0x01 }},
+ {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a,
+   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+   0x01}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[] =   /* TW: New */
+{ 
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+   0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
+   0x00 }},
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+   0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
+   0x00 }},
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+   0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
+   0x00 }},
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+   0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
+   0x00 }},
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0xba,
+   0x27,0x8c,0xdf,0x73,0x00,0x00,0x01,
+   0x00 }},
+ {{0x4d,0x31,0x91,0x3a,0x0a,0x72,0xf0,
+   0x63,0x88,0x57,0x73,0x00,0x00,0x01,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[] =   /* TW: New */
+{ 
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x7f,0x86,0xdf,0x25,0x10,0x00,0x01,
+   0x00 }},
+ {{0x71,0x31,0x95,0x46,0x97,0x24,0xf1,
+   0xbb,0x82,0x57,0x25,0x10,0x00,0x01,
+   0x01 }},
+ {{0x63,0x3f,0x87,0x46,0x97,0x24,0xf5,
+   0x0f,0x86,0xff,0x25,0x30,0x00,0x01,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[] =   /* TW: New */
+{
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
+   0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+   0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
+   0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
+   0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+   0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
+   0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9e,
+   0x03,0x87,0xdf,0x29,0x01,0x00,0x06,
+   0x00 }},
+ {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4,
+   0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
+   0x01 }},
+ {{0x8e,0x3f,0x92,0x79,0x07,0x28,0xd4,
+   0x93,0x87,0xff,0x29,0x21,0x00,0x06,
+   0x01}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1[] =   /* TW: New */
+{
+ {{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,0xa9,0x17,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
+   0x01}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1_H[] =   /* TW: New */
+{
+ {{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}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =   /* TW: New */
+{
+ {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f,
+   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
+   0x00}},
+ {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0,
+   0x5a,0x8e,0x57,0x67,0x20,0x00,0x06,
+   0x01}},
+ {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
+   0x02,0x86,0xff,0x0f,0x10,0x00,0x02,
+   0x01}},
+ {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
+   0x02,0x86,0xff,0x0f,0x09,0x00,0x07,
+   0x01}},
+ {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
+   0x1a,0x80,0x19,0x29,0x0f,0x00,0x03,
+   0x00}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1_H[] =   /* TW: New */
+{
+ {{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}},
+ {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
+   0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
+   0x00}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2[] =    /* TW: New */
+{
+ {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
+   0x00}},
+ {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
+   0x01}},
+ {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
+   0x00}},
+ {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
+   0x00}},
+ {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
+   0x03,0x87,0xdf,0x29,0x01,0x00,0x03,
+   0x00}},
+ {{0xce,0x63,0x92,0x96,0x04,0x28,0xd4,
+   0x3f,0x83,0x57,0x29,0x01,0x00,0x07,
+   0x01}},
+ {{0xce,0x7f,0x92,0xa4,0x12,0x28,0xd4,
+   0x93,0x87,0xff,0x29,0x21,0x00,0x07,
+   0x01}},
+ {{0xce,0x9f,0x92,0xb4,0x02,0x28,0x5a,
+   0x13,0x87,0xff,0x29,0x29,0x00,0x03,
+   0x01}},
+ {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
+   0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
+   0x00}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2_H[] =    /* TW: New */
+{
+ {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9e,
+   0x03,0x87,0xdf,0x29,0x01,0x00,0x06,
+   0x00}},
+ {{0x9c,0x31,0x80,0x64,0x92,0x28,0xd4,
+   0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
+   0x01}},
+ {{0x8e,0x3f,0x92,0x64,0x12,0x28,0xd4,
+   0x93,0x87,0xff,0x29,0x21,0x00,0x06,
+   0x01}},
+ {{0x7e,0x4f,0x82,0x64,0x12,0x28,0x5a,
+   0x13,0x87,0xff,0x29,0x29,0x00,0x06,
+   0x01}},
+ {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
+   0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
+   0x00}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] = {
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1[] =
+{
+        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
 	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
+        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
 	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
+        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
 	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
+        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
 	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x06,
+        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
+	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
 	  0x00}},
-	{{0xa3, 0x63, 0x87, 0x78, 0x89, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x02,
+        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
+	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
 	  0x01}},
-	{{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
+        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_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,
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1_H[] =
+{
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
 	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
+        {{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}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
 	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x06,
+        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
 	  0x00}},
-	{{0xa3, 0x63, 0x87, 0x78, 0x89, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x02,
+        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
 	  0x01}},
-	{{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] = {
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x05,
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2[] =
+{
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
 	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x05,
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
 	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x05,
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
 	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x3a, 0x1a, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x05,
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
 	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0xba,
-	  0x1c, 0x80, 0xdf, 0x73, 0x00, 0x00, 0x05,
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
 	  0x00}},
-	{{0x3d, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x05,
+        {{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}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] = {
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
+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,
+        {{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,
+        {{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,
+        {{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,
+        {{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,
+        {{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,
+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] = {
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1[] =
+{
+        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
 	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
+        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
 	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
+        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
 	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
+        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
 	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x01,
+        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
 	  0x00}},
-	{{0x4f, 0x31, 0x93, 0x3e, 0x86, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x01,
+        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
 	  0x01}},
-	{{0x4f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x01,
+        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] = {
-	{{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
-	  0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01,
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1_H[] =
+{
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
 	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
-	  0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01,
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
 	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
-	  0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01,
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
 	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
-	  0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01,
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
 	  0x00}},
-	{{0x5d, 0x4f, 0x81, 0x53, 0x9c, 0x56, 0xba,
-	  0x18, 0x84, 0xdf, 0x57, 0x00, 0x00, 0x01,
+        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
 	  0x00}},
-	{{0x80, 0x63, 0x84, 0x6c, 0x17, 0xec, 0xf0,
-	  0x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x06,
+        {{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}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] = {
-	{{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
-	  0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01,
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2[] =
+{
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
 	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
-	  0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01,
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
 	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
-	  0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01,
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
 	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
-	  0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01,
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
 	  0x00}},
-	{{0x5d, 0x4f, 0x81, 0x56, 0x9c, 0x0b, 0x3e,
-	  0xe8, 0x84, 0xdf, 0x0c, 0x00, 0x00, 0x01,
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
 	  0x00}},
-	{{0x7d, 0x63, 0x81, 0x6a, 0x16, 0xba, 0xf0,
-	  0x7f, 0x86, 0x57, 0xbb, 0x00, 0x00, 0x06,
+        {{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}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] = {
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2_H[] =
+{
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
 	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
 	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
 	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
 	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x55, 0x80, 0xec, 0xba,
-	  0x50, 0x84, 0xdf, 0xed, 0x00, 0x00, 0x05,
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
 	  0x00}},
-	{{0x70, 0x63, 0x94, 0x68, 0x8d, 0x42, 0xf1,
-	  0xc8, 0x8c, 0x57, 0xe9, 0x20, 0x00, 0x05,
+        {{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}}
 };
 
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] = {
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x55, 0x80, 0x6f, 0xba,
-	  0x20, 0x83, 0xdf, 0x70, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x63, 0x97, 0x69, 0x8e, 0xec, 0xf0,
-	  0x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x05,
-	  0x01}}
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[] =    /* TW: New */
+{ 
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+   0x00 }},
+ {{0x5d,0x4f,0x81,0x56,0x99,0x56,0xba,
+   0x0a,0x84,0xdf,0x57,0x00,0x00,0x01,
+   0x00 }},
+ {{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
+   0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
+   0x01 }},
+ {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,  /* TW: 1024x768 */
+   0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
+   0x01}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[] =    /* TW: New */
+{ 
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+   0x00 }},
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+   0x00 }},
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+   0x00 }},
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+   0x00 }},
+ {{0x5d,0x4f,0x81,0x58,0x9d,0x0b,0x3e,
+   0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
+   0x00 }},
+ {{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
+   0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
+   0x01 }},
+ {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,   /* TW: 1024x768 */
+   0x15,0x88,0xff,0x47,0x70,0x00,0x02,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[] =    /* TW: New */
+{ 
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x6f,0xba,
+   0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
+   0x00 }},
+ {{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
+   0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+   0x01 }},
+ {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,   /* TW: 1024x768 */
+   0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
+   0x01}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[] =    /* TW: New */
+{ 
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
+   0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
+   0x00 }},
+ {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
+   0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
+   0x01 }},
+ {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
+   0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
+   0x01 }}
 };
 
-typedef struct _SiS310_CHTVRegDataStruct {
-	UCHAR Reg[5];
+/* TW: New data for Chrontel 7019 (From 650/LVDS BIOS 1.10.0) */
+typedef struct _SiS310_CHTVRegDataStruct
+{
+ 	UCHAR Reg[16];
 } SiS310_CHTVRegDataStruct;
+
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] = {
-	{{0x00}}
+	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x6a,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x7e,0x80,0x98,0x00}},
+	{{0xcf,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x88,0x30,0x7f,0x00}},
+	{{0xee,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xd3,0xf2,0x36,0x00}}
 };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] = {
-	{{0x00}}
+	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x69,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x43,0x04,0x00}},
+	{{0xce,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1c,0x00,0x82,0x97,0x00}},
+	{{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
 };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] = {
-	{{0x00}}
+	{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
+	{{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x1f,0x84,0x3d,0x28,0x00}},
+	{{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
 };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] = {
-	{{0x00}}
+	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
+	{{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}},
+	{{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
 };
 
-UCHAR SiS310_CHTVVCLKUNTSC[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKUNTSC[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
 
-UCHAR SiS310_CHTVVCLKONTSC[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKONTSC[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
 
-UCHAR SiS310_CHTVVCLKUPAL[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKUPAL[]  = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
 
-UCHAR SiS310_CHTVVCLKOPAL[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKOPAL[]  = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
+/* TW: New end */
diff -Nru a/drivers/video/sis/325vtbl.h b/drivers/video/sis/325vtbl.h
--- a/drivers/video/sis/325vtbl.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/sis/325vtbl.h	Wed Jul 24 14:03:38 2002
@@ -1,4 +1,5 @@
-typedef struct _SiS310_StStruct {
+typedef struct _SiS310_StStruct
+{
 	UCHAR St_ModeID;
 	USHORT St_ModeFlag;
 	UCHAR St_StTableIndex;
@@ -8,31 +9,32 @@
 	UCHAR VB_StTVEdgeIndex;
 	UCHAR VB_StTVYFilterIndex;
 } SiS310_StStruct;
-SiS310_StStruct SiS310_SModeIDTable[] =
-{ 
-	{0x01, 0x9208, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
-	{0x01, 0x1210, 0x14, 0x01, 0x01, 0x00, 0x01, 0x00},
-	{0x01, 0x1010, 0x17, 0x02, 0x02, 0x00, 0x01, 0x01},
-	{0x03, 0x8208, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02},
-	{0x03, 0x0210, 0x16, 0x01, 0x01, 0x00, 0x01, 0x02},
-	{0x03, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x01, 0x03},
-	{0x05, 0x9209, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x06, 0x8209, 0x06, 0x00, 0x00, 0x00, 0x00, 0x05},
-	{0x07, 0x0000, 0x07, 0x03, 0x03, 0x00, 0x01, 0x03},
-	{0x07, 0x0000, 0x19, 0x02, 0x02, 0x00, 0x01, 0x03},
-	{0x0d, 0x920a, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x0e, 0x820a, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x05},
-	{0x0f, 0x0202, 0x11, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0x10, 0x0212, 0x12, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0x11, 0x0212, 0x1a, 0x04, 0x04, 0x00, 0x00, 0x05},
-	{0x12, 0x0212, 0x1b, 0x04, 0x04, 0x00, 0x00, 0x05},
-	{0x13, 0x021b, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x12, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x00, 0x05},
-	{0x12, 0x0210, 0x18, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0xff, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+SiS310_StStruct SiS310_SModeIDTable[]=
+{
+	{0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00},
+	{0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00},
+	{0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01},
+	{0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02},
+	{0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02},
+	{0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03},
+	{0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04},
+	{0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05},
+	{0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03},
+	{0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03},
+	{0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04},
+	{0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05},
+	{0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05},
+	{0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05},
+	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05},
+	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05},
+	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04},
+	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05},
+	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05},
+	{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS310_StandTableStruct {
+typedef struct _SiS310_StandTableStruct
+{
 	UCHAR CRT_COLS;
 	UCHAR ROWS;
 	UCHAR CHAR_HEIGHT;
@@ -44,444 +46,446 @@
 	UCHAR GRC[9];
 } SiS310_StandTableStruct;
 
-SiS310_StandTableStruct SiS310_StandTable[] = {
+SiS310_StandTableStruct SiS310_StandTable[]=
+{
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* MD_3_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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
-	{
-	 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}
-	 },
+ {
+  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}
+ },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* ExtVGATable */
-	{
-	 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* MD_3_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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* MD_2_3_400 */
-	{
-	 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 },
+ {
+  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}
+ },
 /* ExtEGATable */
-	{
-	 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}
-	 },
+ {
+  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}
+ },
 /* 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}
-	 }
+ {
+  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 {
+typedef struct _SiS310_ExtStruct
+{
 	UCHAR Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
@@ -494,632 +498,599 @@
 	UCHAR VB_ExtTVYFilterIndex;
 	UCHAR REFindex;
 } SiS310_ExtStruct;
-SiS310_ExtStruct SiS310_EModeIDTable[] = {
-	
-	    {0x6a, 0x2212, 0x0407, 0x3a81, 0x0102, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x2e, 0x0a1b, 0x0306, 0x3a57, 0x0101, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x2f, 0x0a1b, 0x0305, 0x3a50, 0x0100, 0x08, 0x05, 0x00, 0x00, 0x05,
-	 0x10},
-	{0x30, 0x2a1b, 0x0407, 0x3a81, 0x0103, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x31, 0x0a1b, 0x030d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x32, 0x0a1b, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x33, 0x0a1d, 0x0a0d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x34, 0x2a1d, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x35, 0x0a1f, 0x0a0d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x36, 0x2a1f, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x37, 0x0212, 0x0508, 0x3aab, 0x0104, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x38, 0x0a1b, 0x0508, 0x3aab, 0x0105, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x3a, 0x0e3b, 0x0609, 0x3adc, 0x0107, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x3c, 0x063b, 0x070a, 0x3af2, 0x0130, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{0x3d, 0x067d, 0x070a, 0x3af2, 0x0131, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{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},
-	{0x46, 0x2a1c, 0x0407, 0x3a81, 0x0113, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x47, 0x2a1d, 0x0407, 0x3a81, 0x0114, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x49, 0x0a3c, 0x0508, 0x3aab, 0x0116, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x4a, 0x0a3d, 0x0508, 0x3aab, 0x0117, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x4c, 0x0e7c, 0x0609, 0x3adc, 0x0119, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x4d, 0x0e7d, 0x0609, 0x3adc, 0x011a, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x50, 0x9a1b, 0x0001, 0x3a3b, 0x0132, 0x08, 0x01, 0x00, 0x00, 0x04,
-	 0x26},
-	{0x51, 0xba1b, 0x0103, 0x3a42, 0x0133, 0x08, 0x03, 0x00, 0x00, 0x07,
-	 0x27},
-	{0x52, 0x9a1b, 0x0204, 0x3a49, 0x0134, 0x08, 0x04, 0x00, 0x00, 0x00,
-	 0x28},
-	{0x56, 0x9a1d, 0x0001, 0x3a3b, 0x0135, 0x08, 0x01, 0x00, 0x00, 0x04,
-	 0x26},
-	{0x57, 0xba1d, 0x0103, 0x3a42, 0x0136, 0x08, 0x03, 0x00, 0x00, 0x07,
-	 0x27},
-	{0x58, 0x9a1d, 0x0204, 0x3a49, 0x0137, 0x08, 0x04, 0x00, 0x00, 0x00,
-	 0x28},
-	{0x59, 0x9a1b, 0x0000, 0x3a34, 0x0138, 0x08, 0x00, 0x00, 0x00, 0x04,
-	 0x25},
-	{0x5d, 0x0a1d, 0x0305, 0x3a50, 0x0139, 0x08, 0x05, 0x00, 0x00, 0x07,
-	 0x10},
-	{0x62, 0x0a3f, 0x0306, 0x3a57, 0x013a, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x63, 0x2a3f, 0x0407, 0x3a81, 0x013b, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x64, 0x0a7f, 0x0508, 0x3aab, 0x013c, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x65, 0x0eff, 0x0609, 0x3adc, 0x013d, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x66, 0x06ff, 0x070a, 0x3af2, 0x013e, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{0x68, 0x067b, 0x080b, 0x3b17, 0x013f, 0x08, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x69, 0x06fd, 0x080b, 0x3b17, 0x0140, 0x08, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x6b, 0x07ff, 0x080b, 0x3b17, 0x0141, 0x10, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x6c, 0x067b, 0x090c, 0x3b37, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x6d, 0x06fd, 0x090c, 0x3b37, 0x0000, 0x10, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x6e, 0x07ff, 0x090c, 0x3b37, 0x0000, 0x10, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x70, 0x2a1b, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x71, 0x0a1b, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x74, 0x0a1d, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x75, 0x0a3d, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x76, 0x2a1f, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x77, 0x0a1f, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x78, 0x0a3f, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x79, 0x0a3b, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x7a, 0x2a1d, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x7b, 0x0e3b, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0x7c, 0x0e7d, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0x7d, 0x0eff, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0xff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00,
-	 0x00}
+
+SiS310_ExtStruct  SiS310_EModeIDTable[]=
+{
+ {0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},
+ {0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},
+ {0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
+ {0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
+ {0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
+ {0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
+ {0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
+ {0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
+ {0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
+ {0x3d,0x067d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
+ {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},
+ {0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},
+ {0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
+ {0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},
+ {0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
+ {0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
+ {0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},
+ {0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},
+ {0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
+ {0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08},
+ {0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x66,0x06ff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
+ {0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},
+ {0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},
+ {0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},
+ {0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f},
+ {0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
+ {0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
+ {0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
+ {0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
+ {0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
+ {0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
+ {0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
+ {0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
+ {0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
+ {0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
+ {0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
+ {0x7b,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
+ {0x7c,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
+ {0x7d,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
+ {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS310_Ext2Struct {
+typedef struct _SiS310_Ext2Struct
+{
 	USHORT Ext_InfoFlag;
 	UCHAR Ext_CRT1CRTC;
 	UCHAR Ext_CRTVCLK;
 	UCHAR Ext_CRT2CRTC;
-	UCHAR ModeID;
+	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
 	USHORT ROM_OFFSET;
 } SiS310_Ext2Struct;
-SiS310_Ext2Struct SiS310_RefIndex[] = {
-	{0x005f, 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 */
-	{0x4147, 0x12, 0x0d, 0x00, 0x6a, 800, 600, 0x3a9a},	/* 0x5 */
-	{0x4047, 0x13, 0x13, 0x00, 0x6a, 800, 600, 0x3a9f},	/* 0x6 */
-	{0x4047, 0x14, 0x1c, 0x00, 0x6a, 800, 600, 0x3aa4},	/* 0x7 */
-	{0xc05f, 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 */
-	{0x4047, 0x09, 0x05, 0x00, 0x2e, 640, 480, 0x3a6b},	/* 0xc */
-	{0x4047, 0x0a, 0x09, 0x00, 0x2e, 640, 480, 0x3a70},	/* 0xd */
-	{0x4047, 0x0b, 0x0e, 0x00, 0x2e, 640, 480, 0x3a75},	/* 0xe */
-	{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 301b TV1024x768 */
-	{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 */
-	{0x4047, 0x1a, 0x1b, 0x00, 0x37, 1024, 768, 0x3ac4},	/* 0x18 */
-	{0x4047, 0x1b, 0x1f, 0x00, 0x37, 1024, 768, 0x3ac9},	/* 0x19 */
-	{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 */
-	{0x0007, 0x20, 0x21, 0x00, 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 */
-	{0x0047, 0x3a, 0x20, 0x0a, 0x75, 1280, 720, 0x3b7e},	/* 0x3c */
-	{0x0027, 0x3b, 0x19, 0x08, 0x7b, 1280, 960, 0x3ad0},	/* 0x3d */
-	{0x0027, 0x3b, 0x19, 0x08, 0x7b, 1280, 960, 0x3ad5},	/* 0x3e */
-	{0xffff, 0x00, 0x00, 0x00, 0x00, 0000, 0000, 0x0000}
+SiS310_Ext2Struct SiS310_RefIndex[]=
+{
+ {0x005f,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 */
+ {0x4147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 */
+ {0x4047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 */
+ {0x4047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 */
+ {0xc05f,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 */
+ {0x4047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc */
+ {0x4047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd */
+ {0x4047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe */
+ {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 301b TV1024x768*/
+ {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 */
+ {0x4047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 */
+ {0x4047,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 */
+ {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 */
+ {0x0007,0x20,0x21,0x00,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 */
+ {0x0047,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
+ {0x0027,0x3b,0x19,0x08,0x7b,1280, 960,0x3ad0}, /* 0x3d */
+ {0x0027,0x3b,0x19,0x08,0x7b,1280, 960,0x3ad5}, /* 0x3e */
+ {0xffff,0x00,0x00,0x00,0x00,0000,0000,0x0000}
 };
 
-typedef struct _SiS310_CRT1TableStruct {
+typedef struct _SiS310_CRT1TableStruct
+{
 	UCHAR CR[17];
 } SiS310_CRT1TableStruct;
-SiS310_CRT1TableStruct SiS310_CRT1Table[] = {
-	{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	 0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x00,
-	 0x00},			/* 0x0 */
-	{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0x0b, 0x3e,
-	 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x00,
-	 0x00},			/* 0x1 */
-	{0x3d, 0x31, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	 0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x05,
-	 0x01},			/* 0x2 */
-	{0x4f, 0x3f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x01,
-	 0x01},			/* 0x3 */
-	{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	 0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x05,
-	 0x00},			/* 0x4 */
-	{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
-	 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	 0x00},			/* 0x5 */
-	{0x63, 0x4f, 0x50, 0x86, 0x56, 0x9b, 0x06, 0x3e,
-	 0xe8, 0x8b, 0xdf, 0xe7, 0xff, 0x10, 0x00, 0x01,
-	 0x00},			/* 0x6 */
-	{0x64, 0x4f, 0x4f, 0x88, 0x55, 0x9d, 0xf2, 0x1f,
-	 0xe0, 0x83, 0xdf, 0xdf, 0xf3, 0x10, 0x00, 0x01,
-	 0x00},			/* 0x7 */
-	{0x63, 0x4f, 0x4f, 0x87, 0x5a, 0x81, 0xfb, 0x1f,
-	 0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x05,
-	 0x00},			/* 0x8 */
-	{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0xfb, 0x1f,
-	 0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x00, 0x00, 0x05,
-	 0x61},			/* 0x9 */
-	{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0x01, 0x3e,
-	 0xe0, 0x83, 0xdf, 0xdf, 0x02, 0x00, 0x00, 0x05,
-	 0x61},			/* 0xa */
-	{0x67, 0x4f, 0x4f, 0x8b, 0x58, 0x81, 0x0d, 0x3e,
-	 0xe0, 0x83, 0xdf, 0xdf, 0x0e, 0x10, 0x00, 0x05,
-	 0x61},			/* 0xb */
-	{0x65, 0x4f, 0x4f, 0x89, 0x57, 0x9f, 0xfb, 0x1f,
-	 0xe6, 0x8a, 0xe5, 0xe5, 0xfc, 0x00, 0x00, 0x01,
-	 0x00},			/* 0xc */
-	{0x7b, 0x63, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	 0x58, 0x8a, 0x57, 0x57, 0x70, 0x20, 0x00, 0x05,
-	 0x01},			/* 0xd */
-	{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	 0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x06,
-	 0x01},			/* 0xe */
-	{0x7d, 0x63, 0x63, 0x81, 0x6e, 0x1d, 0x98, 0xf0,
-	 0x7c, 0x82, 0x57, 0x57, 0x99, 0x00, 0x00, 0x06,
-	 0x01},			/* 0xf */
-	{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xf0,
-	 0x58, 0x8b, 0x57, 0x57, 0x70, 0x20, 0x00, 0x06,
-	 0x01},			/* 0x10 */
-	{0x7e, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xf0,
-	 0x58, 0x8b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06,
-	 0x01},			/* 0x11 */
-	{0x81, 0x63, 0x63, 0x85, 0x6d, 0x18, 0x7a, 0xf0,
-	 0x58, 0x8b, 0x57, 0x57, 0x7b, 0x20, 0x00, 0x06,
-	 0x61},			/* 0x12 */
-	{0x83, 0x63, 0x63, 0x87, 0x6e, 0x19, 0x81, 0xf0,
-	 0x58, 0x8b, 0x57, 0x57, 0x82, 0x20, 0x00, 0x06,
-	 0x61},			/* 0x13 */
-	{0x85, 0x63, 0x63, 0x89, 0x6f, 0x1a, 0x91, 0xf0,
-	 0x58, 0x8b, 0x57, 0x57, 0x92, 0x20, 0x00, 0x06,
-	 0x61},			/* 0x14 */
-	{0x99, 0x7f, 0x7f, 0x9d, 0x84, 0x1a, 0x96, 0x1f,
-	 0x7f, 0x83, 0x7f, 0x7f, 0x97, 0x10, 0x00, 0x02,
-	 0x00},			/* 0x15 */
-	{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	 0x01},			/* 0x16 */
-	{0xa1, 0x7f, 0x7f, 0x85, 0x86, 0x97, 0x24, 0xf5,
-	 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	 0x01},			/* 0x17 */
-	{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf5,
-	 0x00, 0x83, 0xff, 0xff, 0x1f, 0x10, 0x00, 0x02,
-	 0x01},			/* 0x18 */
-	{0xa7, 0x7f, 0x7f, 0x8b, 0x89, 0x95, 0x26, 0xf5,
-	 0x00, 0x83, 0xff, 0xff, 0x27, 0x10, 0x00, 0x02,
-	 0x01},			/* 0x19 */
-	{0xa9, 0x7f, 0x7f, 0x8d, 0x8c, 0x9a, 0x2c, 0xf5,
-	 0x00, 0x83, 0xff, 0xff, 0x2d, 0x14, 0x00, 0x02,
-	 0x62},			/* 0x1a */
-	{0xab, 0x7f, 0x7f, 0x8f, 0x8d, 0x9b, 0x35, 0xf5,
-	 0x00, 0x83, 0xff, 0xff, 0x36, 0x14, 0x00, 0x02,
-	 0x62},			/* 0x1b */
-	{0xcf, 0x9f, 0x9f, 0x93, 0xb2, 0x01, 0x14, 0xba,
-	 0x00, 0x83, 0xff, 0xff, 0x15, 0x00, 0x00, 0x03,
-	 0x00},			/* 0x1c */
-	{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0x5a,
-	 0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	 0x01},			/* 0x1d */
-	{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0x5a,
-	 0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	 0x01},			/* 0x1e */
-	{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0x5a,
-	 0x00, 0x83, 0xff, 0xff, 0x2f, 0x09, 0x00, 0x07,
-	 0x01},			/* 0x1f */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x20 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x21 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x22 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x23 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x24 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x25 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x26 */
-	{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	 0x00},			/* 0x27 */
-	{0x43, 0xef, 0xef, 0x87, 0x06, 0x00, 0xd4, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xd5, 0x1f, 0x41, 0x05,
-	 0x63},			/* 0x28 */
-	{0x45, 0xef, 0xef, 0x89, 0x07, 0x01, 0xd9, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xda, 0x1f, 0x41, 0x05,
-	 0x63},			/* 0x29 */
-	{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	 0x00},			/* 0x2a */
-	{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	 0x00},			/* 0x2b */
-	{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	 0x00},			/* 0x2c */
-	{0x59, 0xff, 0xff, 0x9d, 0x17, 0x13, 0x33, 0xba,
-	 0x00, 0x83, 0xff, 0xff, 0x34, 0x0f, 0x41, 0x05,
-	 0x44},			/* 0x2d */
-	{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x38, 0xba,
-	 0x00, 0x83, 0xff, 0xff, 0x39, 0x0f, 0x41, 0x05,
-	 0x44},			/* 0x2e */
-	{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x3d, 0xba,
-	 0x00, 0x83, 0xff, 0xff, 0x3e, 0x0f, 0x41, 0x05,
-	 0x44},			/* 0x2f */
-	{0x5d, 0xff, 0xff, 0x81, 0x19, 0x95, 0x41, 0xba,
-	 0x00, 0x84, 0xff, 0xff, 0x42, 0x0f, 0x41, 0x05,
-	 0x44},			/* 0x30 */
-	{0x55, 0xff, 0xff, 0x99, 0x0d, 0x0c, 0x3e, 0xba,
-	 0x00, 0x84, 0xff, 0xff, 0x3f, 0x0f, 0x41, 0x05,
-	 0x00},			/* 0x31 */
-	{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xba,
-	 0x27, 0x8b, 0xdf, 0xdf, 0x73, 0x00, 0x00, 0x06,
-	 0x01},			/* 0x32 */
-	{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xba,
-	 0x26, 0x89, 0xdf, 0xdf, 0x6f, 0x00, 0x00, 0x06,
-	 0x01},			/* 0x33 */
-	{0x7f, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xba,
-	 0x29, 0x8c, 0xdf, 0xdf, 0x75, 0x00, 0x00, 0x06,
-	 0x01},			/* 0x34 */
-	{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf1,
-	 0xaf, 0x85, 0x3f, 0x3f, 0x25, 0x30, 0x00, 0x02,
-	 0x01},			/* 0x35 */
-	{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf1,
-	 0xad, 0x81, 0x3f, 0x3f, 0x1f, 0x30, 0x00, 0x02,
-	 0x01},			/* 0x36 */
-	{0xa7, 0x7f, 0x7f, 0x88, 0x89, 0x15, 0x26, 0xf1,
-	 0xb1, 0x85, 0x3f, 0x3f, 0x27, 0x30, 0x00, 0x02,
-	 0x01},			/* 0x37 */
-	{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0xc4,
-	 0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	 0x01},			/* 0x38 */
-	{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0xd4,
-	 0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	 0x01},			/* 0x39 */
-	{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0xd4,
-	 0x7d, 0x81, 0xcf, 0xcf, 0x2f, 0x21, 0x00, 0x07,
-	 0x01},			/* 0x3a */
-	{0xdc, 0x9f, 0x9f, 0x00, 0xab, 0x19, 0xe6, 0xef,
-	 0xc0, 0xc3, 0xbf, 0xbf, 0xe7, 0x10, 0x00, 0x07,
-	 0x01},			/* 0x3b */
-	{0x6b, 0x59, 0x59, 0x8f, 0x5e, 0x8c, 0x0b, 0x3e,
-	 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	 0x00},			/* 0x3c */
-	{0x7b, 0x59, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	 0x58, 0x8a, 0x3f, 0x57, 0x70, 0x20, 0x00, 0x05,
-	 0x01}			/* 0x3d */
-};
-
-typedef struct _SiS310_MCLKDataStruct {
-	UCHAR SR28, SR29, SR2A;
+SiS310_CRT1TableStruct SiS310_CRT1Table[]=
+{
+ {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+  0x00}, /* 0x0 */
+ {0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+  0x00}, /* 0x1 */
+ {0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+  0x01}, /* 0x2 */
+ {0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+  0x01}, /* 0x3 */
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
+  0x00}, /* 0x4 */
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+  0x00}, /* 0x5 */
+ {0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
+  0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
+  0x00}, /* 0x6 */
+ {0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
+  0x00}, /* 0x7 */
+ {0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
+  0x00}, /* 0x8 */
+ {0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xfc,0x00,0x00,0x05,
+  0x61}, /* 0x9 */
+ {0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
+  0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
+  0x61}, /* 0xa */
+ {0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
+  0xe0,0x83,0xdf,0xdf,0x0e,0x10,0x00,0x05,
+  0x61}, /* 0xb */
+ {0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
+  0xe6,0x8a,0xe5,0xe5,0xfc,0x00,0x00,0x01,
+  0x00}, /* 0xc */
+ {0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+  0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
+  0x01}, /* 0xd */
+ {0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
+  0x01}, /* 0xe */
+ {0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
+  0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
+  0x01}, /* 0xf */
+ {0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
+  0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
+  0x01}, /* 0x10 */
+ {0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
+  0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
+  0x01}, /* 0x11 */
+ {0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
+  0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
+  0x61}, /* 0x12 */
+ {0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
+  0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
+  0x61}, /* 0x13 */
+ {0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
+  0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
+  0x61}, /* 0x14 */
+ {0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
+  0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
+  0x00}, /* 0x15 */
+ {0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}, /* 0x16 */
+ {0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}, /* 0x17 */
+ {0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
+  0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
+  0x01}, /* 0x18 */
+ {0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
+  0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
+  0x01}, /* 0x19 */
+ {0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
+  0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
+  0x62}, /* 0x1a */
+ {0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
+  0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
+  0x62}, /* 0x1b */
+ {0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
+  0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
+  0x00}, /* 0x1c */
+ {0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
+  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+  0x01}, /* 0x1d */
+ {0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
+  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+  0x01}, /* 0x1e */
+ {0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
+  0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
+  0x01}, /* 0x1f */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x20 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x21 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x22 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x23 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x24 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x25 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x26 */
+ {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}, /* 0x27 */
+ {0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
+  0x63}, /* 0x28 */
+ {0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
+  0x63}, /* 0x29 */
+ {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}, /* 0x2a */
+ {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}, /* 0x2b */
+ {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}, /* 0x2c */
+ {0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
+  0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
+  0x44}, /* 0x2d */
+ {0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
+  0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
+  0x44}, /* 0x2e */
+ {0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
+  0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
+  0x44}, /* 0x2f */
+ {0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
+  0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
+  0x44}, /* 0x30 */
+ {0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
+  0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
+  0x00}, /* 0x31 */
+ {0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
+  0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+  0x01}, /* 0x32 */
+ {0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+  0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+  0x01}, /* 0x33 */
+ {0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+  0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+  0x01}, /* 0x34 */
+ {0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+  0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+  0x01}, /* 0x35 */
+ {0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+  0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+  0x01}, /* 0x36 */
+ {0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
+  0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+  0x01}, /* 0x37 */
+ {0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+  0x01}, /* 0x38 */
+ {0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+  0x01}, /* 0x39 */
+ {0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+  0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+  0x01}, /* 0x3a */
+ {0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,
+  0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+  0x01}, /* 0x3b */
+ {0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+  0x00}, /* 0x3c */
+ {0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+  0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
+  0x01} /* 0x3d */
+};
+
+typedef struct _SiS310_MCLKDataStruct
+{
+	UCHAR SR28,SR29,SR2A;
 	USHORT CLOCK;
 } SiS310_MCLKDataStruct;
-SiS310_MCLKDataStruct SiS310_MCLKData[] = {
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166}
+
+SiS310_MCLKDataStruct SiS310_MCLKData[]=
+{
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166}
 };
 
-typedef struct _SiS310_ECLKDataStruct {
-	UCHAR SR2E, SR2F, SR30;
+typedef struct _SiS310_ECLKDataStruct
+{
+	UCHAR SR2E,SR2F,SR30;
 	USHORT CLOCK;
 } SiS310_ECLKDataStruct;
-SiS310_ECLKDataStruct SiS310_ECLKData[] = {
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166}
+SiS310_ECLKDataStruct SiS310_ECLKData[]=
+{
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166}
 };
 
-typedef struct _SiS310_VCLKDataStruct {
-	UCHAR SR2B, SR2C;
+typedef struct _SiS310_VCLKDataStruct
+{
+	UCHAR SR2B,SR2C;
 	USHORT CLOCK;
 } SiS310_VCLKDataStruct;
-SiS310_VCLKDataStruct SiS310_VCLKData[] = {
-	{0x1b, 0xe1, 25},	/* 0x0 */
-	{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 */
-	{0x6c, 0xc3, 65},	/* 0xb */
-	{0x46, 0x44, 67},	/* 0xc */
-	{0xb1, 0x46, 68},	/* 0xd */
-	{0xd3, 0x4a, 72},	/* 0xe */
-	{0x29, 0x61, 75},	/* 0xf */
-	{0x6e, 0x46, 76},	/* 0x10 */
-	{0x2b, 0x61, 78},	/* 0x11 */
-	{0x31, 0x42, 79},	/* 0x12 */
-	{0xab, 0x44, 83},	/* 0x13 */
-	{0x46, 0x25, 84},	/* 0x14 */
-	{0x78, 0x29, 86},	/* 0x15 */
-	{0x62, 0x44, 94},	/* 0x16 */
-	{0x2b, 0x41, 104},	/* 0x17 */
-	{0x3a, 0x23, 105},	/* 0x18 */
-	{0x70, 0x44, 108},	/* 0x19 */
-	{0x3c, 0x23, 109},	/* 0x1a */
-	{0x5e, 0x43, 113},	/* 0x1b */
-	{0xbc, 0x44, 116},	/* 0x1c */
-	{0xe0, 0x46, 132},	/* 0x1d */
-	{0x54, 0x42, 135},	/* 0x1e */
-	{0xea, 0x2a, 139},	/* 0x1f */
-	{0x41, 0x22, 157},	/* 0x20 */
-	{0x70, 0x24, 162},	/* 0x21 */
-	{0x30, 0x21, 175},	/* 0x22 */
-	{0x4e, 0x22, 189},	/* 0x23 */
-	{0xde, 0x26, 194},	/* 0x24 */
-	{0x62, 0x06, 202},	/* 0x25 */
-	{0x3f, 0x03, 229},	/* 0x26 */
-	{0xb8, 0x06, 234},	/* 0x27 */
-	{0x34, 0x02, 253},	/* 0x28 */
-	{0x58, 0x04, 255},	/* 0x29 */
-	{0x24, 0x01, 265},	/* 0x2a */
-	{0x9b, 0x02, 267},	/* 0x2b */
-	{0x70, 0x05, 270},	/* 0x2c */
-	{0x25, 0x01, 272},	/* 0x2d */
-	{0x9c, 0x02, 277},	/* 0x2e */
-	{0x27, 0x01, 286},	/* 0x2f */
-	{0x3c, 0x02, 291},	/* 0x30 */
-	{0xef, 0x0a, 292},	/* 0x31 */
-	{0xf6, 0x0a, 310},	/* 0x32 */
-	{0x95, 0x01, 315},	/* 0x33 */
-	{0xf0, 0x09, 324},	/* 0x34 */
-	{0xfe, 0x0a, 331},	/* 0x35 */
-	{0xf3, 0x09, 332},	/* 0x36 */
-	{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 */
-	{0x31, 0xc2, 39}	/* 0x40 */
-};
-
-typedef struct _SiS310_VBVCLKDataStruct {
-	UCHAR Part4_A, Part4_B;
+SiS310_VCLKDataStruct SiS310_VCLKData[]=
+{
+	{ 0x1b,0xe1, 25}, /* 0x0 */
+	{ 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 */
+	{ 0x6c,0xc3, 65}, /* 0xb */
+	{ 0x46,0x44, 67}, /* 0xc */
+	{ 0xb1,0x46, 68}, /* 0xd */
+	{ 0xd3,0x4a, 72}, /* 0xe */
+	{ 0x29,0x61, 75}, /* 0xf */
+	{ 0x6e,0x46, 76}, /* 0x10 */
+	{ 0x2b,0x61, 78}, /* 0x11 */
+	{ 0x31,0x42, 79}, /* 0x12 */
+	{ 0xab,0x44, 83}, /* 0x13 */
+	{ 0x46,0x25, 84}, /* 0x14 */
+	{ 0x78,0x29, 86}, /* 0x15 */
+	{ 0x62,0x44, 94}, /* 0x16 */
+	{ 0x2b,0x41,104}, /* 0x17 */
+	{ 0x3a,0x23,105}, /* 0x18 */
+	{ 0x70,0x44,108}, /* 0x19 */
+	{ 0x3c,0x23,109}, /* 0x1a */
+	{ 0x5e,0x43,113}, /* 0x1b */
+	{ 0xbc,0x44,116}, /* 0x1c */
+	{ 0xe0,0x46,132}, /* 0x1d */
+	{ 0x54,0x42,135}, /* 0x1e */
+	{ 0xea,0x2a,139}, /* 0x1f */
+	{ 0x41,0x22,157}, /* 0x20 */
+	{ 0x70,0x24,162}, /* 0x21 */
+	{ 0x30,0x21,175}, /* 0x22 */
+	{ 0x4e,0x22,189}, /* 0x23 */
+	{ 0xde,0x26,194}, /* 0x24 */
+	{ 0x62,0x06,202}, /* 0x25 */
+	{ 0x3f,0x03,229}, /* 0x26 */
+	{ 0xb8,0x06,234}, /* 0x27 */
+	{ 0x34,0x02,253}, /* 0x28 */
+	{ 0x58,0x04,255}, /* 0x29 */
+	{ 0x24,0x01,265}, /* 0x2a */
+	{ 0x9b,0x02,267}, /* 0x2b */
+	{ 0x70,0x05,270}, /* 0x2c */
+	{ 0x25,0x01,272}, /* 0x2d */
+	{ 0x9c,0x02,277}, /* 0x2e */
+	{ 0x27,0x01,286}, /* 0x2f */
+	{ 0x3c,0x02,291}, /* 0x30 */
+	{ 0xef,0x0a,292}, /* 0x31 */
+	{ 0xf6,0x0a,310}, /* 0x32 */
+	{ 0x95,0x01,315}, /* 0x33 */
+	{ 0xf0,0x09,324}, /* 0x34 */
+	{ 0xfe,0x0a,331}, /* 0x35 */
+	{ 0xf3,0x09,332}, /* 0x36 */
+	{ 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 */
+	{ 0x31,0xc2, 39}  /* 0x40 */
+};
+
+typedef struct _SiS310_VBVCLKDataStruct
+{
+	UCHAR Part4_A,Part4_B;
 	USHORT CLOCK;
 } SiS310_VBVCLKDataStruct;
-SiS310_VBVCLKDataStruct SiS310_VBVCLKData[] = {
-	{0x1b, 0xe1, 25},	/* 0x0 */
-	{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 */
-	{0x5a, 0x64, 65},	/* 0xb */
-	{0x46, 0x44, 67},	/* 0xc */
-	{0xb1, 0x46, 68},	/* 0xd */
-	{0xd3, 0x4a, 72},	/* 0xe */
-	{0x29, 0x61, 75},	/* 0xf */
-	{0x6d, 0x46, 75},	/* 0x10 */
-	{0x41, 0x43, 78},	/* 0x11 */
-	{0x31, 0x42, 79},	/* 0x12 */
-	{0xab, 0x44, 83},	/* 0x13 */
-	{0x46, 0x25, 84},	/* 0x14 */
-	{0x78, 0x29, 86},	/* 0x15 */
-	{0x62, 0x44, 94},	/* 0x16 */
-	{0x2b, 0x22, 104},	/* 0x17 */
-	{0x49, 0x24, 105},	/* 0x18 */
-	{0xf8, 0x2f, 108},	/* 0x19 */
-	{0x3c, 0x23, 109},	/* 0x1a */
-	{0x5e, 0x43, 113},	/* 0x1b */
-	{0xbc, 0x44, 116},	/* 0x1c */
-	{0xe0, 0x46, 132},	/* 0x1d */
-	{0xd4, 0x28, 135},	/* 0x1e */
-	{0xea, 0x2a, 139},	/* 0x1f */
-	{0x41, 0x22, 157},	/* 0x20 */
-	{0x70, 0x24, 162},	/* 0x21 */
-	{0x30, 0x21, 175},	/* 0x22 */
-	{0x4e, 0x22, 189},	/* 0x23 */
-	{0xde, 0x26, 194},	/* 0x24 */
-	{0x70, 0x07, 202},	/* 0x25 */
-	{0x3f, 0x03, 229},	/* 0x26 */
-	{0xb8, 0x06, 234},	/* 0x27 */
-	{0x34, 0x02, 253},	/* 0x28 */
-	{0x58, 0x04, 255},	/* 0x29 */
-	{0x24, 0x01, 265},	/* 0x2a */
-	{0x9b, 0x02, 267},	/* 0x2b */
-	{0x70, 0x05, 270},	/* 0x2c */
-	{0x25, 0x01, 272},	/* 0x2d */
-	{0x9c, 0x02, 277},	/* 0x2e */
-	{0x27, 0x01, 286},	/* 0x2f */
-	{0x3c, 0x02, 291},	/* 0x30 */
-	{0xef, 0x0a, 292},	/* 0x31 */
-	{0xf6, 0x0a, 310},	/* 0x32 */
-	{0x95, 0x01, 315},	/* 0x33 */
-	{0xf0, 0x09, 324},	/* 0x34 */
-	{0xfe, 0x0a, 331},	/* 0x35 */
-	{0xf3, 0x09, 332},	/* 0x36 */
-	{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 */
-	{0x31, 0xc2, 39}	/* 0x40 */
+
+SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
+{
+	{ 0x1b,0xe1, 25}, /* 0x0 */
+	{ 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 */
+	{ 0x5a,0x64, 65}, /* 0xb */
+	{ 0x46,0x44, 67}, /* 0xc */
+	{ 0xb1,0x46, 68}, /* 0xd */
+	{ 0xd3,0x4a, 72}, /* 0xe */
+	{ 0x29,0x61, 75}, /* 0xf */
+	{ 0x6d,0x46, 75}, /* 0x10 */
+	{ 0x41,0x43, 78}, /* 0x11 */
+	{ 0x31,0x42, 79}, /* 0x12 */
+	{ 0xab,0x44, 83}, /* 0x13 */
+	{ 0x46,0x25, 84}, /* 0x14 */
+	{ 0x78,0x29, 86}, /* 0x15 */
+	{ 0x62,0x44, 94}, /* 0x16 */
+	{ 0x2b,0x22,104}, /* 0x17 */
+	{ 0x49,0x24,105}, /* 0x18 */
+	{ 0xf8,0x2f,108}, /* 0x19 */
+	{ 0x3c,0x23,109}, /* 0x1a */
+	{ 0x5e,0x43,113}, /* 0x1b */
+	{ 0xbc,0x44,116}, /* 0x1c */
+	{ 0xe0,0x46,132}, /* 0x1d */
+	{ 0xd4,0x28,135}, /* 0x1e */
+	{ 0xea,0x2a,139}, /* 0x1f */
+	{ 0x41,0x22,157}, /* 0x20 */
+	{ 0x70,0x24,162}, /* 0x21 */
+	{ 0x30,0x21,175}, /* 0x22 */
+	{ 0x4e,0x22,189}, /* 0x23 */
+	{ 0xde,0x26,194}, /* 0x24 */
+	{ 0x70,0x07,202}, /* 0x25 */
+	{ 0x3f,0x03,229}, /* 0x26 */
+	{ 0xb8,0x06,234}, /* 0x27 */
+	{ 0x34,0x02,253}, /* 0x28 */
+	{ 0x58,0x04,255}, /* 0x29 */
+	{ 0x24,0x01,265}, /* 0x2a */
+	{ 0x9b,0x02,267}, /* 0x2b */
+	{ 0x70,0x05,270}, /* 0x2c */
+	{ 0x25,0x01,272}, /* 0x2d */
+	{ 0x9c,0x02,277}, /* 0x2e */
+	{ 0x27,0x01,286}, /* 0x2f */
+	{ 0x3c,0x02,291}, /* 0x30 */
+	{ 0xef,0x0a,292}, /* 0x31 */
+	{ 0xf6,0x0a,310}, /* 0x32 */
+	{ 0x95,0x01,315}, /* 0x33 */
+	{ 0xf0,0x09,324}, /* 0x34 */
+	{ 0xfe,0x0a,331}, /* 0x35 */
+	{ 0xf3,0x09,332}, /* 0x36 */
+	{ 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 */
+	{ 0x31,0xc2, 39}  /* 0x40 */
 };
 
-UCHAR SiS310_ScreenOffset[] =
-    { 0x14, 0x19, 0x20, 0x28, 0x32, 0x40, 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35 };
+UCHAR SiS310_ScreenOffset[]={ 0x14,0x19,0x20,0x28,0x32,0x40,
+                              0x50,0x64,0x78,0x80,0x2d,0x35 };
 
-typedef struct _SiS310_StResInfoStruct {
+typedef struct _SiS310_StResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
 } SiS310_StResInfoStruct;
-SiS310_StResInfoStruct SiS310_StResInfo[] = {
-	{640, 400},
-	{640, 350},
-	{720, 400},
-	{720, 350},
-	{640, 480}
+
+SiS310_StResInfoStruct SiS310_StResInfo[]=
+{
+	{ 640,400},
+	{ 640,350},
+	{ 720,400},
+	{ 720,350},
+	{ 640,480}
 };
 
-typedef struct _SiS310_ModeResInfoStruct {
+typedef struct _SiS310_ModeResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
-	UCHAR XChar;
-	UCHAR YChar;
+	UCHAR  XChar;
+	UCHAR  YChar;
 } SiS310_ModeResInfoStruct;
-SiS310_ModeResInfoStruct SiS310_ModeResInfo[] = {
-	{320, 200, 8, 8},
-	{320, 240, 8, 8},
-	{320, 400, 8, 8},
-	{400, 300, 8, 8},
-	{512, 384, 8, 8},
-	{640, 400, 8, 16},
-	{640, 480, 8, 16},
-	{800, 600, 8, 16},
-	{1024, 768, 8, 16},
-	{1280, 1024, 8, 16},
-	{1600, 1200, 8, 16},
-	{1920, 1440, 8, 16},
-	{2048, 1536, 8, 16},
-	{720, 480, 8, 16},
-	{720, 576, 8, 16},
-	{1280, 960, 8, 16},
-	{800, 480, 8, 16},
-	{1024, 576, 8, 16},
-	{1280, 720, 8, 16}
+
+SiS310_ModeResInfoStruct SiS310_ModeResInfo[]=
+{
+	{  320, 200, 8, 8},
+	{  320, 240, 8, 8},
+	{  320, 400, 8, 8},
+	{  400, 300, 8, 8},
+	{  512, 384, 8, 8},
+	{  640, 400, 8,16},
+	{  640, 480, 8,16},
+	{  800, 600, 8,16},
+	{ 1024, 768, 8,16},
+	{ 1280,1024, 8,16},
+	{ 1600,1200, 8,16},
+	{ 1920,1440, 8,16},
+	{ 2048,1536, 8,16},
+	{  720, 480, 8,16},
+	{  720, 576, 8,16},
+	{ 1280, 960, 8,16},
+	{  800, 480, 8,16},
+	{ 1024, 576, 8,16},
+	{ 1280, 720, 8,16}
 };
 
 UCHAR SiS310_OutputSelect = 0;
+
 UCHAR SiS310_SoftSetting = 30;
-UCHAR SiS310_SR07 = 0x18;
-UCHAR SiS310_SR15[8][4] = {
-	{0x0, 0x4, 0x60, 0x60},
-	{0xf, 0xf, 0xf, 0xf},
-	{0xba, 0xba, 0xba, 0xba},
-	{0xa9, 0xa9, 0xac, 0xac},
-	{0xa0, 0xa0, 0xa0, 0xa8},
-	{0x0, 0x0, 0x2, 0x2},
-	{0x30, 0x30, 0x40, 0x40},
-	{0x0, 0xa5, 0xfb, 0xf6}
-};
-UCHAR SiS310_CR40[5][4] = {
-	{0x77, 0x77, 0x33, 0x33},
-	{0x77, 0x77, 0x33, 0x33},
-	{0x0, 0x0, 0x0, 0x0},
-	{0x5b, 0x5b, 0x3, 0x3},
-	{0x0, 0x0, 0xf0, 0xf8}
-};
-UCHAR SiS310_CR49[] = { 0xaa, 0x88 };
-UCHAR SiS310_SR1F = 0x0;
-UCHAR SiS310_SR21 = 0xa5;
-UCHAR SiS310_SR22 = 0xfb;
-UCHAR SiS310_SR23 = 0xf6;
-UCHAR SiS310_SR24 = 0xd;
-UCHAR SiS310_SR25[] = { 0x33, 0x3 };
-UCHAR SiS310_SR31 = 0x0;
-UCHAR SiS310_SR32 = 0x11;
-UCHAR SiS310_SR33 = 0x0;
+
+UCHAR SiS310_SR07=0x18;
+
+UCHAR SiS310_SR15[8][4]={
+	{0x00,0x04,0x60,0x60},
+	{0x0f,0x0f,0x0f,0x0f},
+	{0xba,0xba,0xba,0xba},
+	{0xa9,0xa9,0xac,0xac},
+	{0xa0,0xa0,0xa0,0xa8},
+	{0x00,0x00,0x02,0x02},
+	{0x30,0x30,0x40,0x40},
+	{0x00,0xa5,0xfb,0xf6}
+};
+UCHAR SiS310_CR40[5][4]={
+	{0x77,0x77,0x33,0x33},
+	{0x77,0x77,0x33,0x33},
+	{0x00,0x00,0x00,0x00},
+	{0x5b,0x5b,0x03,0x03},
+	{0x00,0x00,0xf0,0xf8}
+};
+UCHAR SiS310_CR49[]={0xaa,0x88};
+UCHAR SiS310_SR1F=0x0;
+UCHAR SiS310_SR21=0xa5;
+UCHAR SiS310_SR22=0xfb;
+UCHAR SiS310_SR23=0xf6;
+UCHAR SiS310_SR24=0xd;
+UCHAR SiS310_SR25[]={0x33,0x3};
+UCHAR SiS310_SR31=0x0;
+UCHAR SiS310_SR32=0x11;
+UCHAR SiS310_SR33=0x0;
 UCHAR SiS310_CRT2Data_1_2 = 0x0;
 UCHAR SiS310_CRT2Data_4_D = 0x0;
 UCHAR SiS310_CRT2Data_4_E = 0x0;
@@ -1127,14 +1098,15 @@
 USHORT SiS310_RGBSenseData = 0xd1;
 USHORT SiS310_VideoSenseData = 0xb9;
 USHORT SiS310_YCSenseData = 0xb3;
-USHORT SiS310_RGBSenseData2 = 0x0190;	/*301b */
+USHORT SiS310_RGBSenseData2 = 0x0190;     /*301b*/
 USHORT SiS310_VideoSenseData2 = 0x0174;
 USHORT SiS310_YCSenseData2 = 0x016b;
-UCHAR SiS310_NTSCPhase[] = { 0x21, 0xed, 0x8a, 0x8 };
+UCHAR SiS310_NTSCPhase[] = {0x21,0xed,0x8a,0x8};
 
-UCHAR SiS310_PALPhase[] = { 0x2a, 0x5, 0xd3, 0x0 };
+UCHAR SiS310_PALPhase[] = {0x2a,0x5,0xd3,0x0};
 
-typedef struct _SiS310_LCDDataStruct {
+typedef struct _SiS310_LCDDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -1142,99 +1114,109 @@
 	USHORT LCDHT;
 	USHORT LCDVT;
 } SiS310_LCDDataStruct;
-SiS310_LCDDataStruct SiS310_StLCD1024x768Data[] = {
-	{62, 25, 800, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{104, 45, 945, 496, 1344, 806},
-	{62, 25, 800, 546, 1344, 806},
-	{31, 18, 1008, 624, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-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}
-};
-
-SiS310_LCDDataStruct SiS310_St2LCD1024x768Data[] = {
-	{62, 25, 800, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{104, 45, 945, 496, 1344, 806},
-	{62, 25, 800, 546, 1344, 806},
-	{31, 18, 1008, 624, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS310_LCDDataStruct SiS310_StLCD1280x1024Data[] = {
-	{22, 5, 800, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] = {
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 500, 1688, 1066},
-	{211, 75, 1024, 625, 1688, 1066},
-	{211, 120, 1280, 798, 1688, 1066},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_St2LCD1280x1024Data[] = {
-	{22, 5, 800, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_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}
-};
-
-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}
+
+SiS310_LCDDataStruct  SiS310_StLCD1024x768Data[]=
+{
+	{   62,  25, 800, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{  104,  45, 945, 496,1344, 806},
+	{   62,  25, 800, 546,1344, 806},
+	{   31,  18,1008, 624,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+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}
+};
+
+SiS310_LCDDataStruct  SiS310_St2LCD1024x768Data[]=
+{
+	{   62,  25, 800, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{  104,  45, 945, 496,1344, 806},
+	{   62,  25, 800, 546,1344, 806},
+	{   31,  18,1008, 624,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+SiS310_LCDDataStruct  SiS310_StLCD1280x1024Data[]=
+{
+	{   22,   5, 800, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{   13,   5,1024, 675,1560,1152},
+	{   16,   9,1266, 804,1688,1072},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[]=
+{
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 500,1688,1066},
+	{  211,  75,1024, 625,1688,1066},
+	{  211, 120,1280, 798,1688,1066},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_St2LCD1280x1024Data[]=
+{
+	{   22,   5, 800, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{   13,   5,1024, 675,1560,1152},
+	{   16,   9,1266, 804,1688,1072},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_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}
+};
+
+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}
 };
 
-typedef struct _SiS310_TVDataStruct {
+typedef struct _SiS310_TVDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -1249,1070 +1231,1105 @@
 	UCHAR RY3COE;
 	UCHAR RY4COE;
 } SiS310_TVDataStruct;
-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}
-};
-
-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},
-	{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}	/*301b */
-};
-
-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}
-};
-
-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},
-	{143, 120, 1056, 643, 1288, 440, 0, 128, 0, 0xf4, 0x10, 0x1c, 0x00},
-	{2, 1, 858, 503, 1270, 480, 0, 128, 0, 0xee, 0x0c, 0x22, 0x08},
-	{65, 64, 1056, 791, 1270, 480, 638, 0, 0, 0xEE, 0x0C, 0x22, 0x08}	/*301b */
-};
-
-SiS310_TVDataStruct SiS310_St1HiTVData[] = {
-	0x00
-};
-
-SiS310_TVDataStruct SiS310_St2HiTVData[] = {
-	0x00
-};
-
-SiS310_TVDataStruct SiS310_ExtHiTVData[] = {
-	0x00
-};
+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}
+};
+
+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},
+ {   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}     /*301b*/
+};
+
+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}
+};
+
+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},
+ {  143, 120,1056, 643,1288, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
+ {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},
+ {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} /*301b*/     
+};
+
+SiS310_TVDataStruct  SiS310_St1HiTVData[]=
+{
+0x00};
+
+SiS310_TVDataStruct  SiS310_St2HiTVData[]=
+{
+0x00};
+
+SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
+{
+0x00};
 
 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
-};
+  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};
 
 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
-};
+  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};
 
-UCHAR SiS310_HiTVExtTiming[] = { 0x00 };
+UCHAR SiS310_HiTVExtTiming[] = {0x00};
 
-UCHAR SiS310_HiTVSt1Timing[] = { 0x00 };
+UCHAR SiS310_HiTVSt1Timing[] = {0x00};
 
-UCHAR SiS310_HiTVSt2Timing[] = { 0x00 };
+UCHAR SiS310_HiTVSt2Timing[] = {0x00};
 
-UCHAR SiS310_HiTVTextTiming[] = { 0x00 };
+UCHAR SiS310_HiTVTextTiming[] = {0x00};
 
-UCHAR SiS310_HiTVGroup3Data[] = { 0x00 };
+UCHAR SiS310_HiTVGroup3Data[] = {0x00};
 
-UCHAR SiS310_HiTVGroup3Simu[] = { 0x00 };
+UCHAR SiS310_HiTVGroup3Simu[] = {0x00};
 
-UCHAR SiS310_HiTVGroup3Text[] = { 0x00 };
+UCHAR SiS310_HiTVGroup3Text[] = {0x00};
 
-typedef struct _SiS310_PanelDelayTblStruct {
-	UCHAR timer[2];
+typedef struct _SiS310_PanelDelayTblStruct
+{
+ UCHAR timer[2];
 } SiS310_PanelDelayTblStruct;
-SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[] = { {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}
-};
-
-typedef struct _SiS310_LVDSDataStruct {
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT LCDHT;
-	USHORT LCDVT;
+SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+{{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}};
+
+typedef struct _SiS310_LVDSDataStruct
+{
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
 } SiS310_LVDSDataStruct;
-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}
-};
-
-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}
-};
-
-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},
-	{1050, 638, 1344, 806},
-	{1344, 806, 1344, 806},
-	{800, 449, 1280, 801},
-	{800, 525, 1280, 813}
-};
-
-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}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_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}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_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}
-};
-
-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}
-};
-
-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}
-};
-
-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}
-};
-
-SiS310_LVDSDataStruct SiS310_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}
-};
-
-SiS310_LVDSDataStruct SiS310_CHTVOPALData[] = {
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{840, 625, 840, 625},
-	{960, 750, 960, 750}
-};
-
-typedef struct _SiS310_LVDSDesStruct {
-	USHORT LCDHDES;
-	USHORT LCDVDES;
+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}
+};
+
+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}
+};
+
+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},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+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}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_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}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_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}
+};
+
+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}
+};
+
+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}
+};
+
+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}
+};
+
+SiS310_LVDSDataStruct  SiS310_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}
+};
+
+SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]=
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {840, 625, 840, 625},
+ {960, 750, 960, 750}
+};
+
+typedef struct _SiS310_LVDSDesStruct
+{
+ USHORT LCDHDES;
+ USHORT LCDVDES;
 } SiS310_LVDSDesStruct;
-SiS310_LVDSDesStruct SiS310_PanelType00_1[] = {
-	{1059, 626},
-	{1059, 624},
-	{1059, 626},
-	{1059, 624},
-	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType01_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType02_1[] = {
-	{1059, 626},
-	{1059, 624},
-	{1059, 626},
-	{1059, 624},
-	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType03_1[] = {
-	{8, 436},
-	{8, 440},
-	{8, 436},
-	{8, 440},
-	{8, 512},
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType04_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType05_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType06_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType07_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType08_1[] = {
-	{1059, 626},
-	{1059, 624},
-	{1059, 626},
-	{1059, 624},
-	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType09_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0a_1[] = {
-	{1059, 626},
-	{1059, 624},
-	{1059, 626},
-	{1059, 624},
-	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0b_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0c_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0d_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0e_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0f_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType00_2[] = {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType01_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType02_2[] = {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType03_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{1152, 622},
-	{1152, 597}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType04_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType05_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType06_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType07_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType08_2[] = {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType09_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0a_2[] = {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0b_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0c_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0d_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0e_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0f_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType03_1[]=
+{
+ { 8, 436},
+ { 8, 440},
+ { 8, 436},
+ { 8, 440},
+ { 8, 512},
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType05_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType07_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType09_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType01_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType02_2[]=
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType03_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ {1152, 622},
+ {1152, 597}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType04_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType09_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0d_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0f_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
 };
 /*301b*/
-SiS310_LVDSDesStruct SiS310_PanelType1076_1[] = {
-	0x00, 0x00
-};
-SiS310_LVDSDesStruct SiS310_PanelType1210_1[] = {
-	0x00, 0x00
-};
-SiS310_LVDSDesStruct SiS310_PanelType1296_1[] = {
-	0x00, 0x00
-};
-SiS310_LVDSDesStruct SiS310_PanelType1076_2[] = {
-	0x00, 0x00
-};
-SiS310_LVDSDesStruct SiS310_PanelType1210_2[] = {
-	0x00, 0x00
-};
-SiS310_LVDSDesStruct SiS310_PanelType1296_2[] = {
-	0x00, 0x00
-};
+SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=
+{
+0x00,0x00};
+SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=
+{
+0x00,0x00};
+SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=
+{
+0x00,0x00};
+SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=
+{
+0x00,0x00};
+SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=
+{
+0x00,0x00};
+SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=
+{
+0x00,0x00};
 /*end 301b*/
 
-SiS310_LVDSDesStruct SiS310_CHTVUNTSCDesData[] = {
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVONTSCDesData[] = {
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVUPALDesData[] = {
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVOPALDesData[] = {
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{0, 0},
-	{0, 0}
-};
-
-typedef struct _SiS310_LVDSCRT1DataStruct {
-	UCHAR CR[17];
+SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]=
+{
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
+{
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
+{
+ {256,   0},
+ {256,   0},
+ {256,   0},
+ {256,   0},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
+{
+ {256,   0},
+ {256,   0},
+ {256,   0},
+ {256,   0},
+ { 0,   0},
+ { 0,   0}
+};
+
+typedef struct _SiS310_LVDSCRT1DataStruct
+{
+ UCHAR CR[17];
 } SiS310_LVDSCRT1DataStruct;
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] =
-    { {0x65, 0x4f, 0x89, 0x56, 0x83, 0xaf, 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, 0x56, 0x83, 0xaf, 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, 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}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] =
-    { {0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
-       0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x05,
-       0x00},
-{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
- 0x60, 0x87, 0x5d, 0x5d, 0x83, 0x10, 0x00, 0x05,
- 0x00},
-{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
- 0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x05,
- 0x00},
-{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
- 0x60, 0x87, 0x5d, 0x5d, 0x83, 0x10, 0x00, 0x05,
- 0x00},
-{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x04, 0x3e,
- 0xE2, 0x89, 0xDf, 0xDf, 0x05, 0x00, 0x00, 0x05,
- 0x00},
-{0x87, 0x63, 0x63, 0x8B, 0x69, 0x1A, 0x7c, 0xf0,
- 0x5A, 0x8F, 0x57, 0x57, 0x7D, 0x20, 0x00, 0x26,
- 0x01},
-{0xA3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
- 0x02, 0x88, 0xFf, 0xFf, 0x25, 0x10, 0x00, 0x02,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_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}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_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}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] =
-    { {0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
-       0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x44,
-       0x00},
-{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
- 0x60, 0x87, 0x5D, 0x5D, 0x83, 0x01, 0x00, 0x44,
- 0x00},
-{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
- 0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x44,
- 0x00},
-{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
- 0x60, 0x87, 0x5D, 0x5D, 0x83, 0x01, 0x00, 0x44,
- 0x00},
-{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x04, 0x3e,
- 0xE2, 0x89, 0xDf, 0xDf, 0x05, 0x00, 0x00, 0x44,
- 0x00},
-{0x41, 0x31, 0x31, 0x85, 0x35, 0x1d, 0x7c, 0xf0,
- 0x5A, 0x8F, 0x57, 0x57, 0x7D, 0x20, 0x00, 0x55,
- 0x01},
-{0x4f, 0x3F, 0x3F, 0x93, 0x45, 0x0D, 0x24, 0xf5,
- 0x02, 0x88, 0xFf, 0xFf, 0x25, 0x10, 0x00, 0x01,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] =
-    { {0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
-       0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
-       0x00},
-{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
- 0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
- 0x00},
-{0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
- 0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
- 0x00},
-{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
- 0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
- 0x00},
-{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x04, 0x3e,
- 0xe2, 0x89, 0xdf, 0x05, 0x00, 0x00, 0x04,
- 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}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[] =
-    { {0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-       0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
-       0x00},
-{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
- 0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
- 0x00},
-{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
- 0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
- 0x00},
-{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
- 0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
- 0x00},
-{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0xba,
- 0x1c, 0x80, 0xdf, 0x73, 0x00, 0x00, 0x06,
- 0x00},
-{0x7f, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
- 0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x06,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_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}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_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}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_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}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_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}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] =
-    { {0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-       0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-       0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
- 0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
- 0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
- 0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
- 0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x31, 0x93, 0x3e, 0x86, 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}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] =
-    { {0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
-       0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01,
-       0x00},
-{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
- 0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01,
- 0x00},
-{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
- 0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01,
- 0x00},
-{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
- 0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01,
- 0x00},
-{0x5d, 0x4f, 0x81, 0x53, 0x9c, 0x56, 0xba,
- 0x18, 0x84, 0xdf, 0x57, 0x00, 0x00, 0x01,
- 0x00},
-{0x80, 0x63, 0x84, 0x6c, 0x17, 0xec, 0xf0,
- 0x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x06,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] =
-    { {0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
-       0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01,
-       0x00},
-{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
- 0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01,
- 0x00},
-{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
- 0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01,
- 0x00},
-{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
- 0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01,
- 0x00},
-{0x5d, 0x4f, 0x81, 0x56, 0x9c, 0x0b, 0x3e,
- 0xe8, 0x84, 0xdf, 0x0c, 0x00, 0x00, 0x01,
- 0x00},
-{0x7d, 0x63, 0x81, 0x6a, 0x16, 0xba, 0xf0,
- 0x7f, 0x86, 0x57, 0xbb, 0x00, 0x00, 0x06,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] =
-    { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-       0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
-       0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
- 0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
- 0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
- 0x00},
-{0x64, 0x4f, 0x88, 0x55, 0x80, 0xec, 0xba,
- 0x50, 0x84, 0xdf, 0xed, 0x00, 0x00, 0x05,
- 0x00},
-{0x70, 0x63, 0x94, 0x68, 0x8d, 0x42, 0xf1,
- 0xc8, 0x8c, 0x57, 0xe9, 0x20, 0x00, 0x05,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] =
-    { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-       0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
-       0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
- 0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
- 0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
- 0x00},
-{0x64, 0x4f, 0x88, 0x55, 0x80, 0x6f, 0xba,
- 0x20, 0x83, 0xdf, 0x70, 0x00, 0x00, 0x05,
- 0x00},
-{0x73, 0x63, 0x97, 0x69, 0x8e, 0xec, 0xf0,
- 0x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x05,
- 0x01}
-};
-
-typedef struct _SiS310_CHTVRegDataStruct {
-	UCHAR Reg[5];
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[]=
+{{0x65,0x4f,0x89,0x56,0x83,0xaf,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,0x56,0x83,0xaf,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,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 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[]=
+{{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00 },
+ {0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00 },
+ {0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00},
+ {0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00 },
+ {0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
+   0x00},
+ {0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26,
+   0x01},
+ {0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_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 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_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 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[]=
+{{0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+   0x00 },
+ {0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+   0x00},
+ {0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+   0x00},
+ {0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+   0x00},
+ {0x37,0x27,0x27,0x9B,0x2b,0x94,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x44,
+   0x00},
+ {0x41,0x31,0x31,0x85,0x35,0x1d,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
+   0x01},
+ {0x4f,0x3F,0x3F,0x93,0x45,0x0D,0x24,0xf5,
+   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x01,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[]=
+{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+   0x00 },
+ {0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+   0x00 },
+ {0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+   0x00 },
+ {0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+   0x00 },
+ {0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+   0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
+   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 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=
+{ {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+   0x00 },
+ {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+   0x00 },
+ {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+   0x00 },
+ {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+   0x00 },
+ {0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
+   0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
+   0x00 },
+ {0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_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 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_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 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_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 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_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 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[]=
+{ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x31,0x93,0x3e,0x86,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 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[]=
+{ {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+   0x00 },
+ {0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
+   0x18,0x84,0xdf,0x57,0x00,0x00,0x01,
+   0x00 },
+ {0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
+   0x90,0x8c,0x57,0xed,0x20,0x00,0x06,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[]=
+{ {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+   0x00 },
+ {0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
+   0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
+   0x00 },
+ {0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
+   0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[]=
+{ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 },
+ {0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
+   0x50,0x84,0xdf,0xed,0x00,0x00,0x05,
+   0x00 },
+ {0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
+   0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[]=
+{ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 },
+ {0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
+   0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
+   0x00 },
+ {0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
+   0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+   0x01 }};
+
+typedef struct _SiS310_CHTVRegDataStruct
+{
+ UCHAR Reg[5];
 } SiS310_CHTVRegDataStruct;
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] = {
-	0x00
-};
+0x00 };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] = {
-	0x00
-};
+0x00 };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] = {
-	0x00
-};
+0x00 };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] = {
-	0x00
-};
+0x00 };
+
+UCHAR SiS310_CHTVVCLKUNTSC[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKUNTSC[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKONTSC[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKONTSC[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKUPAL[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKUPAL[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKOPAL[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKOPAL[] = { 0x00 };
diff -Nru a/drivers/video/sis/init.c b/drivers/video/sis/init.c
--- a/drivers/video/sis/init.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/sis/init.c	Wed Jul 24 14:03:37 2002
@@ -1,809 +1,958 @@
-/* Function: Support NT X.0  MM function  */
-/* Version : V 0.80      [ynlai] 04/12/98 */
+/* $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
+ * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+ *
+ * Assembler-To-C translation
+ * Parts Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Based on BIOS
+ *     1.10.07 (1.10a) for SiS650/LVDS+CH7019
+ *     1.07.1b for SiS650/301(B/LV)
+ *     2.04.50 (I) and 2.04.5c (II) for SiS630/301(B)
+ *     2.02.3b, 2.03.02 and 2.04.5c for 630/LVDS/LVDS+CH7005
+ *     1.09b for 315/301(B)
+ *
+ * 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.
+ *
+ */
 
 #include "init.h"
-#ifdef CONFIG_FB_SIS_300
+
+#ifdef SIS300
 #include "300vtbl.h"
 #endif
-#ifdef CONFIG_FB_SIS_315
+
+#ifdef SIS315H
 #include "310vtbl.h"
 #endif
 
-BOOLEAN SiSInit (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN SiSSetMode (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
+#ifdef LINUX_XF86
+BOOLEAN SiSBIOSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                       ScrnInfoPtr pScrn, DisplayModePtr mode);
+#ifdef SISDUALHEAD /* TW: For dual head */
+BOOLEAN SiSBIOSSetModeCRT1(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                       ScrnInfoPtr pScrn, DisplayModePtr mode);
+BOOLEAN SiSBIOSSetModeCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                       ScrnInfoPtr pScrn, DisplayModePtr mode);
+#endif /* dual head */
+#endif /* linux_xf86 */
+
+#ifndef LINUX_XF86
+BOOLEAN SiSInit(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#endif
+
+#ifdef LINUX_XF86
+BOOLEAN SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                   ScrnInfoPtr pScrn,USHORT ModeNo);
+#else
+BOOLEAN SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo);
+#endif
 
 #if defined(ALLOC_PRAGMA)
 #pragma alloc_text(PAGE,SiSSetMode)
 #pragma alloc_text(PAGE,SiSInit)
 #endif
 
-void SiS_SetReg1 (USHORT, USHORT, USHORT);
-void SiS_SetReg2 (USHORT, USHORT, USHORT);
-void SiS_SetReg3 (USHORT, USHORT);
-void SiS_SetReg4 (USHORT, ULONG);
-UCHAR SiS_GetReg1 (USHORT, USHORT);
-UCHAR SiS_GetReg2 (USHORT);
-ULONG SiS_GetReg3 (USHORT);
-void SiS_ClearDAC (ULONG);
-
-#ifdef CONFIG_FB_SIS_300
-void
-InitTo300Pointer (void)
-{
-	SiS_SModeIDTable = (SiS_StStruct *) SiS300_SModeIDTable;
-	SiS_VBModeIDTable = (SiS_VBModeStruct *) SiS300_VBModeIDTable;	/*add for 300 oem util */
-	SiS_StandTable = (SiS_StandTableStruct *) SiS300_StandTable;
-	SiS_EModeIDTable = (SiS_ExtStruct *) SiS300_EModeIDTable;
-	SiS_RefIndex = (SiS_Ext2Struct *) SiS300_RefIndex;
-	SiS_CRT1Table = (SiS_CRT1TableStruct *) SiS300_CRT1Table;
-	SiS_MCLKData = (SiS_MCLKDataStruct *) SiS300_MCLKData;
-	SiS_ECLKData = (SiS_ECLKDataStruct *) SiS300_ECLKData;
-	SiS_VCLKData = (SiS_VCLKDataStruct *) SiS300_VCLKData;
-	SiS_VBVCLKData = (SiS_VBVCLKDataStruct *) SiS300_VCLKData;
-	SiS_ScreenOffset = SiS300_ScreenOffset;
-	SiS_StResInfo = (SiS_StResInfoStruct *) SiS300_StResInfo;
-	SiS_ModeResInfo = (SiS_ModeResInfoStruct *) SiS300_ModeResInfo;
-
-	pSiS_OutputSelect = &SiS300_OutputSelect;
-	pSiS_SoftSetting = &SiS300_SoftSetting;
-	pSiS_SR07 = &SiS300_SR07;
-	SiS_SR15 = SiS300_SR15;
-	SiS_CR40 = SiS300_CR40;
-	SiS_CR49 = SiS300_CR49;
-	pSiS_SR1F = &SiS300_SR1F;
-	pSiS_SR21 = &SiS300_SR21;
-	pSiS_SR22 = &SiS300_SR22;
-	pSiS_SR23 = &SiS300_SR23;
-	pSiS_SR24 = &SiS300_SR24;
-	SiS_SR25 = SiS300_SR25;
-	pSiS_SR31 = &SiS300_SR31;
-	pSiS_SR32 = &SiS300_SR32;
-	pSiS_SR33 = &SiS300_SR33;
-	pSiS_CRT2Data_1_2 = &SiS300_CRT2Data_1_2;
-	pSiS_CRT2Data_4_D = &SiS300_CRT2Data_4_D;
-	pSiS_CRT2Data_4_E = &SiS300_CRT2Data_4_E;
-	pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
-	pSiS_RGBSenseData = &SiS300_RGBSenseData;
-	pSiS_VideoSenseData = &SiS300_VideoSenseData;
-	pSiS_YCSenseData = &SiS300_YCSenseData;
-	pSiS_RGBSenseData2 = &SiS300_RGBSenseData2;
-	pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
-	pSiS_YCSenseData2 = &SiS300_YCSenseData2;
-
-	SiS_NTSCPhase = SiS300_NTSCPhase;
-	SiS_PALPhase = SiS300_PALPhase;
-	SiS_NTSCPhase2 = SiS300_NTSCPhase2;
-	SiS_PALPhase2 = SiS300_PALPhase2;
-	SiS_PALMPhase = SiS300_PALMPhase;	/*add for PALMN */
-	SiS_PALNPhase = SiS300_PALNPhase;
-
-	SiS_StLCD1024x768Data = (SiS_LCDDataStruct *) SiS300_StLCD1024x768Data;
-	SiS_ExtLCD1024x768Data =
-	    (SiS_LCDDataStruct *) SiS300_ExtLCD1024x768Data;
-	SiS_St2LCD1024x768Data =
-	    (SiS_LCDDataStruct *) SiS300_St2LCD1024x768Data;
-	SiS_StLCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS300_StLCD1280x1024Data;
-	SiS_ExtLCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS300_ExtLCD1280x1024Data;
-	SiS_St2LCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS300_St2LCD1280x1024Data;
-	SiS_NoScaleData = (SiS_LCDDataStruct *) SiS300_NoScaleData;
-	SiS_LCD1280x960Data = (SiS_LCDDataStruct *) SiS300_LCD1280x960Data;
-	SiS_StPALData = (SiS_TVDataStruct *) SiS300_StPALData;
-	SiS_ExtPALData = (SiS_TVDataStruct *) SiS300_ExtPALData;
-	SiS_StNTSCData = (SiS_TVDataStruct *) SiS300_StNTSCData;
-	SiS_ExtNTSCData = (SiS_TVDataStruct *) SiS300_ExtNTSCData;
-	SiS_St1HiTVData = (SiS_TVDataStruct *) SiS300_St1HiTVData;
-	SiS_St2HiTVData = (SiS_TVDataStruct *) SiS300_St2HiTVData;
-	SiS_ExtHiTVData = (SiS_TVDataStruct *) SiS300_ExtHiTVData;
-	SiS_NTSCTiming = SiS300_NTSCTiming;
-	SiS_PALTiming = SiS300_PALTiming;
-	SiS_HiTVSt1Timing = SiS300_HiTVSt1Timing;
-	SiS_HiTVSt2Timing = SiS300_HiTVSt2Timing;
-	SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
-	SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
-	SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
-	SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
-
-	SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *) SiS300_PanelDelayTbl;
-	SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *) SiS300_LVDS800x600Data_1;
-	SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *) SiS300_LVDS800x600Data_2;
-	SiS_LVDS1024x768Data_1 =
-	    (SiS_LVDSDataStruct *) SiS300_LVDS1024x768Data_1;
-	SiS_LVDS1024x768Data_2 =
-	    (SiS_LVDSDataStruct *) SiS300_LVDS1024x768Data_2;
-	SiS_LVDS1280x1024Data_1 =
-	    (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_1;
-	SiS_LVDS1280x1024Data_2 =
-	    (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_2;
-	SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *) SiS300_LVDS640x480Data_1;
-	SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *) SiS300_CHTVUNTSCData;
-	SiS_CHTVONTSCData = (SiS_LVDSDataStruct *) SiS300_CHTVONTSCData;
-	SiS_CHTVUPALData = (SiS_LVDSDataStruct *) SiS300_CHTVUPALData;
-	SiS_CHTVOPALData = (SiS_LVDSDataStruct *) SiS300_CHTVOPALData;
-	SiS_PanelType00_1 = (SiS_LVDSDesStruct *) SiS300_PanelType00_1;
-	SiS_PanelType01_1 = (SiS_LVDSDesStruct *) SiS300_PanelType01_1;
-	SiS_PanelType02_1 = (SiS_LVDSDesStruct *) SiS300_PanelType02_1;
-	SiS_PanelType03_1 = (SiS_LVDSDesStruct *) SiS300_PanelType03_1;
-	SiS_PanelType04_1 = (SiS_LVDSDesStruct *) SiS300_PanelType04_1;
-	SiS_PanelType05_1 = (SiS_LVDSDesStruct *) SiS300_PanelType05_1;
-	SiS_PanelType06_1 = (SiS_LVDSDesStruct *) SiS300_PanelType06_1;
-	SiS_PanelType07_1 = (SiS_LVDSDesStruct *) SiS300_PanelType07_1;
-	SiS_PanelType08_1 = (SiS_LVDSDesStruct *) SiS300_PanelType08_1;
-	SiS_PanelType09_1 = (SiS_LVDSDesStruct *) SiS300_PanelType09_1;
-	SiS_PanelType0a_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0a_1;
-	SiS_PanelType0b_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0b_1;
-	SiS_PanelType0c_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0c_1;
-	SiS_PanelType0d_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0d_1;
-	SiS_PanelType0e_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0e_1;
-	SiS_PanelType0f_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0f_1;
-	SiS_PanelType00_2 = (SiS_LVDSDesStruct *) SiS300_PanelType00_2;
-	SiS_PanelType01_2 = (SiS_LVDSDesStruct *) SiS300_PanelType01_2;
-	SiS_PanelType02_2 = (SiS_LVDSDesStruct *) SiS300_PanelType02_2;
-	SiS_PanelType03_2 = (SiS_LVDSDesStruct *) SiS300_PanelType03_2;
-	SiS_PanelType04_2 = (SiS_LVDSDesStruct *) SiS300_PanelType04_2;
-	SiS_PanelType05_2 = (SiS_LVDSDesStruct *) SiS300_PanelType05_2;
-	SiS_PanelType06_2 = (SiS_LVDSDesStruct *) SiS300_PanelType06_2;
-	SiS_PanelType07_2 = (SiS_LVDSDesStruct *) SiS300_PanelType07_2;
-	SiS_PanelType08_2 = (SiS_LVDSDesStruct *) SiS300_PanelType08_2;
-	SiS_PanelType09_2 = (SiS_LVDSDesStruct *) SiS300_PanelType09_2;
-	SiS_PanelType0a_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0a_2;
-	SiS_PanelType0b_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0b_2;
-	SiS_PanelType0c_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0c_2;
-	SiS_PanelType0d_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0d_2;
-	SiS_PanelType0e_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0e_2;
-	SiS_PanelType0f_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0f_2;
-	SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *) SiS300_CHTVUNTSCDesData;
-	SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *) SiS300_CHTVONTSCDesData;
-	SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *) SiS300_CHTVUPALDesData;
-	SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *) SiS300_CHTVOPALDesData;
-	SiS_LVDSCRT1800x600_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_1;
-	SiS_LVDSCRT11024x768_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_1;
-	SiS_LVDSCRT11280x1024_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_1;
-	SiS_LVDSCRT1800x600_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_1_H;
-	SiS_LVDSCRT11024x768_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_1_H;
-	SiS_LVDSCRT11280x1024_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_1_H;
-	SiS_LVDSCRT1800x600_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_2;
-	SiS_LVDSCRT11024x768_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_2;
-	SiS_LVDSCRT11280x1024_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_2;
-	SiS_LVDSCRT1800x600_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_2_H;
-	SiS_LVDSCRT11024x768_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_2_H;
-	SiS_LVDSCRT11280x1024_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_2_H;
-	SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1UNTSC;
-	SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1ONTSC;
-	SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1UPAL;
-	SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1OPAL;
-	SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_UNTSC;
-	SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_ONTSC;
-	SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_UPAL;
-	SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_OPAL;
-	SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
-	SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
-	SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL;
-	SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL;
-	/* 300 customization related */
-}
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-void
-InitTo310Pointer (void)
-{
-	SiS_SModeIDTable = (SiS_StStruct *) SiS310_SModeIDTable;
-	SiS_StandTable = (SiS_StandTableStruct *) SiS310_StandTable;
-	SiS_EModeIDTable = (SiS_ExtStruct *) SiS310_EModeIDTable;
-	SiS_RefIndex = (SiS_Ext2Struct *) SiS310_RefIndex;
-	SiS_CRT1Table = (SiS_CRT1TableStruct *) SiS310_CRT1Table;
-	SiS_MCLKData = (SiS_MCLKDataStruct *) SiS310_MCLKData;
-	SiS_ECLKData = (SiS_ECLKDataStruct *) SiS310_ECLKData;
-	SiS_VCLKData = (SiS_VCLKDataStruct *) SiS310_VCLKData;
-	SiS_VBVCLKData = (SiS_VBVCLKDataStruct *) SiS310_VBVCLKData;
-	SiS_ScreenOffset = SiS310_ScreenOffset;
-	SiS_StResInfo = (SiS_StResInfoStruct *) SiS310_StResInfo;
-	SiS_ModeResInfo = (SiS_ModeResInfoStruct *) SiS310_ModeResInfo;
-
-	pSiS_OutputSelect = &SiS310_OutputSelect;
-	pSiS_SoftSetting = &SiS310_SoftSetting;
-	pSiS_SR07 = &SiS310_SR07;
-	SiS_SR15 = SiS310_SR15;
-	SiS_CR40 = SiS310_CR40;
-	SiS_CR49 = SiS310_CR49;
-	pSiS_SR1F = &SiS310_SR1F;
-	pSiS_SR21 = &SiS310_SR21;
-	pSiS_SR22 = &SiS310_SR22;
-	pSiS_SR23 = &SiS310_SR23;
-	pSiS_SR24 = &SiS310_SR24;
-	SiS_SR25 = SiS310_SR25;
-	pSiS_SR31 = &SiS310_SR31;
-	pSiS_SR32 = &SiS310_SR32;
-	pSiS_SR33 = &SiS310_SR33;
-	pSiS_CRT2Data_1_2 = &SiS310_CRT2Data_1_2;
-	pSiS_CRT2Data_4_D = &SiS310_CRT2Data_4_D;
-	pSiS_CRT2Data_4_E = &SiS310_CRT2Data_4_E;
-	pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
-	pSiS_RGBSenseData = &SiS310_RGBSenseData;
-	pSiS_VideoSenseData = &SiS310_VideoSenseData;
-	pSiS_YCSenseData = &SiS310_YCSenseData;
-	pSiS_RGBSenseData2 = &SiS310_RGBSenseData2;
-	pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
-	pSiS_YCSenseData2 = &SiS310_YCSenseData2;
-	SiS_NTSCPhase = SiS310_NTSCPhase;
-	SiS_PALPhase = SiS310_PALPhase;
-	SiS_NTSCPhase2 = SiS310_NTSCPhase2;
-	SiS_PALPhase2 = SiS310_PALPhase2;
-	SiS_PALMPhase = SiS310_PALMPhase;	/*add for PALMN */
-	SiS_PALNPhase = SiS310_PALNPhase;
-
-	SiS_StLCD1024x768Data = (SiS_LCDDataStruct *) SiS310_StLCD1024x768Data;
-	SiS_ExtLCD1024x768Data =
-	    (SiS_LCDDataStruct *) SiS310_ExtLCD1024x768Data;
-	SiS_St2LCD1024x768Data =
-	    (SiS_LCDDataStruct *) SiS310_St2LCD1024x768Data;
-	SiS_StLCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS310_StLCD1280x1024Data;
-	SiS_ExtLCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS310_ExtLCD1280x1024Data;
-	SiS_St2LCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS310_St2LCD1280x1024Data;
-	SiS_NoScaleData = (SiS_LCDDataStruct *) SiS310_NoScaleData;
-	SiS_LCD1280x960Data = (SiS_LCDDataStruct *) SiS310_LCD1280x960Data;
-	SiS_StPALData = (SiS_TVDataStruct *) SiS310_StPALData;
-	SiS_ExtPALData = (SiS_TVDataStruct *) SiS310_ExtPALData;
-	SiS_StNTSCData = (SiS_TVDataStruct *) SiS310_StNTSCData;
-	SiS_ExtNTSCData = (SiS_TVDataStruct *) SiS310_ExtNTSCData;
-	SiS_St1HiTVData = (SiS_TVDataStruct *) SiS310_St1HiTVData;
-	SiS_St2HiTVData = (SiS_TVDataStruct *) SiS310_St2HiTVData;
-	SiS_ExtHiTVData = (SiS_TVDataStruct *) SiS310_ExtHiTVData;
-	SiS_NTSCTiming = SiS310_NTSCTiming;
-	SiS_PALTiming = SiS310_PALTiming;
-	SiS_HiTVSt1Timing = SiS310_HiTVSt1Timing;
-	SiS_HiTVSt2Timing = SiS310_HiTVSt2Timing;
-	SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
-	SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
-	SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
-	SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
-
-	SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *) SiS310_PanelDelayTbl;
-	SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS800x600Data_1;
-	SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *) SiS310_LVDS800x600Data_2;
-	SiS_LVDS1024x768Data_1 =
-	    (SiS_LVDSDataStruct *) SiS310_LVDS1024x768Data_1;
-	SiS_LVDS1024x768Data_2 =
-	    (SiS_LVDSDataStruct *) SiS310_LVDS1024x768Data_2;
-	SiS_LVDS1280x1024Data_1 =
-	    (SiS_LVDSDataStruct *) SiS310_LVDS1280x1024Data_1;
-	SiS_LVDS1280x1024Data_2 =
-	    (SiS_LVDSDataStruct *) SiS310_LVDS1280x1024Data_2;
-	SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS640x480Data_1;
-	SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *) SiS310_CHTVUNTSCData;
-	SiS_CHTVONTSCData = (SiS_LVDSDataStruct *) SiS310_CHTVONTSCData;
-	SiS_CHTVUPALData = (SiS_LVDSDataStruct *) SiS310_CHTVUPALData;
-	SiS_CHTVOPALData = (SiS_LVDSDataStruct *) SiS310_CHTVOPALData;
-	SiS_PanelType00_1 = (SiS_LVDSDesStruct *) SiS310_PanelType00_1;
-	SiS_PanelType01_1 = (SiS_LVDSDesStruct *) SiS310_PanelType01_1;
-	SiS_PanelType02_1 = (SiS_LVDSDesStruct *) SiS310_PanelType02_1;
-	SiS_PanelType03_1 = (SiS_LVDSDesStruct *) SiS310_PanelType03_1;
-	SiS_PanelType04_1 = (SiS_LVDSDesStruct *) SiS310_PanelType04_1;
-	SiS_PanelType05_1 = (SiS_LVDSDesStruct *) SiS310_PanelType05_1;
-	SiS_PanelType06_1 = (SiS_LVDSDesStruct *) SiS310_PanelType06_1;
-	SiS_PanelType07_1 = (SiS_LVDSDesStruct *) SiS310_PanelType07_1;
-	SiS_PanelType08_1 = (SiS_LVDSDesStruct *) SiS310_PanelType08_1;
-	SiS_PanelType09_1 = (SiS_LVDSDesStruct *) SiS310_PanelType09_1;
-	SiS_PanelType0a_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0a_1;
-	SiS_PanelType0b_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0b_1;
-	SiS_PanelType0c_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0c_1;
-	SiS_PanelType0d_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0d_1;
-	SiS_PanelType0e_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0e_1;
-	SiS_PanelType0f_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0f_1;
-	SiS_PanelType00_2 = (SiS_LVDSDesStruct *) SiS310_PanelType00_2;
-	SiS_PanelType01_2 = (SiS_LVDSDesStruct *) SiS310_PanelType01_2;
-	SiS_PanelType02_2 = (SiS_LVDSDesStruct *) SiS310_PanelType02_2;
-	SiS_PanelType03_2 = (SiS_LVDSDesStruct *) SiS310_PanelType03_2;
-	SiS_PanelType04_2 = (SiS_LVDSDesStruct *) SiS310_PanelType04_2;
-	SiS_PanelType05_2 = (SiS_LVDSDesStruct *) SiS310_PanelType05_2;
-	SiS_PanelType06_2 = (SiS_LVDSDesStruct *) SiS310_PanelType06_2;
-	SiS_PanelType07_2 = (SiS_LVDSDesStruct *) SiS310_PanelType07_2;
-	SiS_PanelType08_2 = (SiS_LVDSDesStruct *) SiS310_PanelType08_2;
-	SiS_PanelType09_2 = (SiS_LVDSDesStruct *) SiS310_PanelType09_2;
-	SiS_PanelType0a_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0a_2;
-	SiS_PanelType0b_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0b_2;
-	SiS_PanelType0c_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0c_2;
-	SiS_PanelType0d_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0d_2;
-	SiS_PanelType0e_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0e_2;
-	SiS_PanelType0f_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0f_2;
-	/*301b */
-	LVDS1024x768Des_1 = (SiS_LVDSDesStruct *) SiS310_PanelType1076_1;
-	LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *) SiS310_PanelType1210_1;
-	LVDS1280x960Des_1 = (SiS_LVDSDesStruct *) SiS310_PanelType1296_1;
-	LVDS1024x768Des_2 = (SiS_LVDSDesStruct *) SiS310_PanelType1076_2;
-	LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *) SiS310_PanelType1210_2;
-	LVDS1280x960Des_2 = (SiS_LVDSDesStruct *) SiS310_PanelType1296_2;
-	/*end 301b */
-
-	SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *) SiS310_CHTVUNTSCDesData;
-	SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *) SiS310_CHTVONTSCDesData;
-	SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *) SiS310_CHTVUPALDesData;
-	SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *) SiS310_CHTVOPALDesData;
-	SiS_LVDSCRT1800x600_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_1;
-	SiS_LVDSCRT11024x768_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_1;
-	SiS_LVDSCRT11280x1024_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_1;
-	SiS_LVDSCRT1800x600_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_1_H;
-	SiS_LVDSCRT11024x768_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_1_H;
-	SiS_LVDSCRT11280x1024_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_1_H;
-	SiS_LVDSCRT1800x600_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_2;
-	SiS_LVDSCRT11024x768_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_2;
-	SiS_LVDSCRT11280x1024_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_2;
-	SiS_LVDSCRT1800x600_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_2_H;
-	SiS_LVDSCRT11024x768_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_2_H;
-	SiS_LVDSCRT11280x1024_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_2_H;
-	SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1UNTSC;
-	SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1ONTSC;
-	SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1UPAL;
-	SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1OPAL;
-	SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_UNTSC;
-	SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_ONTSC;
-	SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_UPAL;
-	SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_OPAL;
-	/*add for LCDA */
-	SiS_LCDACRT1800x600_1 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_1;
-	SiS_LCDACRT11024x768_1 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_1;
-	SiS_LCDACRT11280x1024_1 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_1;
-	SiS_LCDACRT1800x600_1_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_1_H;
-	SiS_LCDACRT11024x768_1_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_1_H;
-	SiS_LCDACRT11280x1024_1_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_1_H;
-	SiS_LCDACRT1800x600_2 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_2;
-	SiS_LCDACRT11024x768_2 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_2;
-	SiS_LCDACRT11280x1024_2 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_2;
-	SiS_LCDACRT1800x600_2_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_2_H;
-	SiS_LCDACRT11024x768_2_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_2_H;
-	SiS_LCDACRT11280x1024_2_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_2_H;
-	/*end for 301b */
-
-	SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
-	SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
-	SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL;
-	SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL;
-	/* 310 customization related */
+void DelaySeconds(int seconds);
+void DebugCode(UCHAR code);
 
-}
+#ifdef LINUX_XF86
+/* TW: Mode table for X driver */
+UShort  ModeIndex_320x480[]      = {0x5A, 0x5B, 0x00, 0x00};  /* DSTN/FSTN */
+UShort  ModeIndex_512x384[]      = {0x52, 0x58, 0x00, 0x5c};
+UShort  ModeIndex_640x480[]      = {0x2E, 0x44, 0x00, 0x62};
+UShort  ModeIndex_720x480[]      = {0x31, 0x33, 0x00, 0x35};
+UShort  ModeIndex_720x576[]      = {0x32, 0x34, 0x00, 0x36};
+UShort  ModeIndex_800x480[]      = {0x70, 0x7a, 0x00, 0x76};  /* 310/325 series only */
+UShort  ModeIndex_800x600[]      = {0x30, 0x47, 0x00, 0x63};
+UShort  ModeIndex_1024x768[]     = {0x38, 0x4A, 0x00, 0x64};
+UShort  ModeIndex_1024x576[]     = {0x71, 0x74, 0x00, 0x77};  /* 310/325 series only */
+UShort  ModeIndex_1024x600[]     = {0x20, 0x21, 0x00, 0x22};  /* 300 series only */
+UShort  ModeIndex_1280x1024[]    = {0x3A, 0x4D, 0x00, 0x65};
+UShort  ModeIndex_300_1280x960[] = {0x6e, 0x6f, 0x00, 0x7b};
+UShort  ModeIndex_310_1280x960[] = {0x7C, 0x7D, 0x00, 0x7E};
+UShort  ModeIndex_1152x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 300 series only */
+UShort  ModeIndex_1280x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 310/325 series only */
+UShort  ModeIndex_1280x720[]     = {0x79, 0x75, 0x00, 0x78};  /* 310/325 series only */
+UShort  ModeIndex_1400x1050[]    = {0x26, 0x27, 0x00, 0x28};  /* 310/325 series only */
+UShort  ModeIndex_1600x1200[]    = {0x3C, 0x3D, 0x00, 0x66};
+UShort  ModeIndex_1920x1440[]    = {0x68, 0x69, 0x00, 0x6B};
+UShort  ModeIndex_2048x1536[]    = {0x6c, 0x6d, 0x00, 0x6e};  /* 310/325 series only */
 #endif
 
-BOOLEAN
-SiSInit (PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	ULONG ROMAddr = (ULONG) HwDeviceExtension->pjVirtualRomBase;
-	ULONG FBAddr = (ULONG) HwDeviceExtension->pjVideoMemoryAddress;
-	USHORT BaseAddr = (USHORT) HwDeviceExtension->ulIOAddress;
-	UCHAR i, temp = 0;
-	UCHAR SR11, temp1;
-	ULONG base;
-	UCHAR SR12 = 0, SR13 = 0, SR14 = 0, SR16 = 0, SR17 = 0, SR18 = 0, SR19 =
-	    0, SR1A = 0;
-#ifdef CONFIG_FB_SIS_315
-	/* ULONG   j, k;   */
-	UCHAR CR39 = 0, CR3A = 0, CR3B = 0, CR3C = 0, CR3D = 0, CR3E = 0, CR3F =
-	    0;
-	UCHAR CR79 = 0, CR7A = 0, CR7B = 0, CR7C = 0;
-	PSIS_DSReg pSR;
-	ULONG Temp;
-#endif
-	UCHAR VBIOSVersion[5];
-
-/* if(ROMAddr==0)   return (FALSE);*/
-	if (FBAddr == 0)
-		return (FALSE);
-	if (BaseAddr == 0)
-		return (FALSE);
-
-	SiS_SetReg3 ((USHORT) (BaseAddr + 0x12), 0x67);	/* 3c2 <- 67 ,ynlai */
-#ifdef CONFIG_FB_SIS_315
-	/*if(HwDeviceExtension->jChipType > SIS_315H) */
-	if (HwDeviceExtension->jChipType > SIS_315PRO) {
-		if (!HwDeviceExtension->bIntegratedMMEnabled)
-			return (FALSE);	/* alan  */
-	}
+void
+DelaySeconds(int seconds)
+{
+  int i;
+#ifdef WIN2000
+  int j;
 #endif
 
-	SiS_MemoryCopy (VBIOSVersion, HwDeviceExtension->szVBIOSVer, 4);
-
-	VBIOSVersion[4] = 0x0;
-	/* 09/07/99 modify by domao */
+  for (i=0;i<seconds;i++) {
+#ifdef TC
+    delay(1000);
+#endif
 
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO) ||
-	    (HwDeviceExtension->jChipType == SIS_550) ||	/* 05/02/01 ynlai for 550 */
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740))	/* 09/03/01 chiawen for 650 */
-		InitTo310Pointer ();
-#endif
-
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730) ||
-	    (HwDeviceExtension->jChipType == SIS_300))
-		InitTo300Pointer ();
-#endif
-
-	SiS_P3c4 = BaseAddr + 0x14;
-	SiS_P3d4 = BaseAddr + 0x24;
-	SiS_P3c0 = BaseAddr + 0x10;
-	SiS_P3ce = BaseAddr + 0x1e;
-	SiS_P3c2 = BaseAddr + 0x12;
-	SiS_P3ca = BaseAddr + 0x1a;
-	SiS_P3c6 = BaseAddr + 0x16;
-	SiS_P3c7 = BaseAddr + 0x17;
-	SiS_P3c8 = BaseAddr + 0x18;
-	SiS_P3c9 = BaseAddr + 0x19;
-	SiS_P3da = BaseAddr + 0x2A;
-	SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
-	SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
-	SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
-	SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
-	SiS_Set_LVDS_TRUMPION (HwDeviceExtension);	/*2/29/00 by Mars Wen for LVDS and Trumpion  */
+#ifdef WIN2000
+    for (j=0;j<20000;j++)
+      VideoPortStallExecution(50);
+#endif
 
-	SiS_SetReg1 (SiS_P3c4, 0x05, 0x86);	/* 1.Openkey  */
+#ifdef WINCE_HEADER
+#endif
 
 #ifdef LINUX_KERNEL
-#ifdef CONFIG_FB_SIS_300	/* add to set SR14 */
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		base = 0x80000060;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 >> (16 + 8 + 4);
-		temp1 = temp1 & (0x07);
-		temp1 = temp1 + 1;
-		temp1 = 1 << temp1;
-		SR14 = temp1 - 1;
-		base = 0x80000064;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 & (0x00000020);
-		if (temp1)
-			SR14 = (0x10000000) | SR14;
-		else
-			SR14 = (0x01000000) | SR14;
-	}
 #endif
+  }
+}
 
-#ifdef CONFIG_FB_SIS_315	/* add to set SR14 */
-	if ((HwDeviceExtension->jChipType == SIS_550)) {
-		base = 0x80000060;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 >> (16 + 8 + 4);
-		temp1 = temp1 & (0x07);
-		temp1 = temp1 + 1;
-		temp1 = 1 << temp1;
-		SR14 = temp1 - 1;
-		base = 0x80000064;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 & (0x00000020);
-		if (temp1)
-			SR14 = (0x10000000) | SR14;
-		else
-			SR14 = (0x01000000) | SR14;
-	}
-
-	if ((HwDeviceExtension->jChipType == SIS_640)
-	    || (HwDeviceExtension->jChipType == SIS_740)) {
-		base = 0x80000064;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp >> 4;
-		temp1 = temp1 & (0x07);
-		if (temp1 > 2) {
-			temp = temp1;
-			switch (temp) {
-			case 3:
-				temp1 = 0x07;
-				break;
-			case 4:
-				temp1 = 0x0F;
-				break;
-			case 5:
-				temp1 = 0x1F;
-				break;
-			case 6:
-				temp1 = 0x05;
-				break;
-			case 7:
-				temp1 = 0x17;
-				break;
-			case 8:
-				break;
-			case 9:
-				break;
-			}
-		}
-		SR14 = temp1;
-		base = 0x8000007C;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 & (0x00000020);
-		if (temp1)
-			SR14 = (0x10000000) | SR14;
-	}
-#endif
+void
+DebugCode(UCHAR code)
+{
+  OutPortByte ( 0x80, code);
+  /*OutPortByte ( 0x300, code);*/
+  DelaySeconds(0x3);
+}
+
+#ifdef SIS300
+void
+InitTo300Pointer(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   SiS_SModeIDTable = (SiS_StStruct *) SiS300_SModeIDTable;
+   SiS_VBModeIDTable = (SiS_VBModeStruct *) SiS300_VBModeIDTable;
+   SiS_StandTable = (SiS_StandTableStruct *) SiS300_StandTable;
+   SiS_EModeIDTable = (SiS_ExtStruct *) SiS300_EModeIDTable;
+   SiS_RefIndex = (SiS_Ext2Struct *) SiS300_RefIndex;
+   SiS_CRT1Table = (SiS_CRT1TableStruct *) SiS300_CRT1Table;
+   SiS_MCLKData_0 = (SiS_MCLKDataStruct *) SiS300_MCLKData;
+   SiS_ECLKData = (SiS_ECLKDataStruct *) SiS300_ECLKData;
+   SiS_VCLKData = (SiS_VCLKDataStruct *) SiS300_VCLKData;
+   SiS_VBVCLKData = (SiS_VBVCLKDataStruct *) SiS300_VCLKData;
+   SiS_ScreenOffset = SiS300_ScreenOffset;
+   SiS_StResInfo = (SiS_StResInfoStruct *) SiS300_StResInfo;
+   SiS_ModeResInfo = (SiS_ModeResInfoStruct *) SiS300_ModeResInfo;
+
+   pSiS_OutputSelect = &SiS300_OutputSelect;
+   pSiS_SoftSetting = &SiS300_SoftSetting;
+   pSiS_SR07 = &SiS300_SR07;
+   SiS_SR15 = SiS300_SR15;
+   SiS_CR40 = SiS300_CR40;
+   SiS_CR49 = SiS300_CR49;
+   pSiS_SR1F = &SiS300_SR1F;
+   pSiS_SR21 = &SiS300_SR21;
+   pSiS_SR22 = &SiS300_SR22;
+   pSiS_SR23 = &SiS300_SR23;
+   pSiS_SR24 = &SiS300_SR24;
+   SiS_SR25 = SiS300_SR25;
+   pSiS_SR31 = &SiS300_SR31;
+   pSiS_SR32 = &SiS300_SR32;
+   pSiS_SR33 = &SiS300_SR33;
+   pSiS_CRT2Data_1_2 = &SiS300_CRT2Data_1_2;
+   pSiS_CRT2Data_4_D = &SiS300_CRT2Data_4_D;
+   pSiS_CRT2Data_4_E = &SiS300_CRT2Data_4_E;
+   pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
+   pSiS_RGBSenseData = &SiS300_RGBSenseData;
+   pSiS_VideoSenseData = &SiS300_VideoSenseData;
+   pSiS_YCSenseData = &SiS300_YCSenseData;
+   pSiS_RGBSenseData2 = &SiS300_RGBSenseData2;
+   pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
+   pSiS_YCSenseData2 = &SiS300_YCSenseData2;
+
+   SiS_NTSCPhase  = SiS300_NTSCPhase;
+   SiS_PALPhase   = SiS300_PALPhase;
+   SiS_NTSCPhase2 = SiS300_NTSCPhase2;
+   SiS_PALPhase2  = SiS300_PALPhase2;
+   SiS_PALMPhase  = SiS300_PALMPhase;
+   SiS_PALNPhase  = SiS300_PALNPhase;
+   SiS_PALMPhase2 = SiS300_PALMPhase2;
+   SiS_PALNPhase2 = SiS300_PALNPhase2;
+
+   SiS_StLCD1024x768Data = (SiS_LCDDataStruct *) SiS300_StLCD1024x768Data;
+   SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *) SiS300_ExtLCD1024x768Data;
+   SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *) SiS300_St2LCD1024x768Data;
+   SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *) SiS300_StLCD1280x1024Data;
+   SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *) SiS300_ExtLCD1280x1024Data;
+   SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *) SiS300_St2LCD1280x1024Data;
+   SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *) SiS300_NoScaleData1024x768;
+   SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *) SiS300_NoScaleData1280x1024;
+   SiS_LCD1280x960Data = (SiS_LCDDataStruct *) SiS300_LCD1280x960Data;
+   SiS_StPALData = (SiS_TVDataStruct *) SiS300_StPALData;
+   SiS_ExtPALData = (SiS_TVDataStruct *) SiS300_ExtPALData;
+   SiS_StNTSCData = (SiS_TVDataStruct *) SiS300_StNTSCData;
+   SiS_ExtNTSCData = (SiS_TVDataStruct *) SiS300_ExtNTSCData;
+   SiS_St1HiTVData = (SiS_TVDataStruct *) SiS300_St1HiTVData;
+   SiS_St2HiTVData = (SiS_TVDataStruct *) SiS300_St2HiTVData;
+   SiS_ExtHiTVData = (SiS_TVDataStruct *) SiS300_ExtHiTVData;
+   SiS_NTSCTiming = SiS300_NTSCTiming;
+   SiS_PALTiming = SiS300_PALTiming;
+   SiS_HiTVSt1Timing = SiS300_HiTVSt1Timing;
+   SiS_HiTVSt2Timing = SiS300_HiTVSt2Timing;
+   SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
+   SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
+   SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
+   SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
+
+   SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *) SiS300_PanelDelayTbl;
+   SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *) SiS300_PanelDelayTblLVDS;
+
+   SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *) SiS300_LVDS800x600Data_1;
+   SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *) SiS300_LVDS800x600Data_2;
+   SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *) SiS300_LVDS1024x768Data_1;
+   SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *) SiS300_LVDS1024x768Data_2;
+   SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_1;
+   SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_2;
+   SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_1;
+   SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_2;
+   SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *) SiS300_LVDS640x480Data_1;
+   SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *) SiS300_LVDS1024x600Data_1;
+   SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *) SiS300_LVDS1024x600Data_2;
+   SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *) SiS300_LVDS1152x768Data_1;
+   SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *) SiS300_LVDS1152x768Data_2;
+   SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *) SiS300_CHTVUNTSCData;
+   SiS_CHTVONTSCData = (SiS_LVDSDataStruct *) SiS300_CHTVONTSCData;
+   SiS_CHTVUPALData  = (SiS_LVDSDataStruct *) SiS300_CHTVUPALData;
+   SiS_CHTVOPALData  = (SiS_LVDSDataStruct *) SiS300_CHTVOPALData;
+   SiS_PanelType00_1 = (SiS_LVDSDesStruct *) SiS300_PanelType00_1;
+   SiS_PanelType01_1 = (SiS_LVDSDesStruct *) SiS300_PanelType01_1;
+   SiS_PanelType02_1 = (SiS_LVDSDesStruct *) SiS300_PanelType02_1;
+   SiS_PanelType03_1 = (SiS_LVDSDesStruct *) SiS300_PanelType03_1;
+   SiS_PanelType04_1 = (SiS_LVDSDesStruct *) SiS300_PanelType04_1;
+   SiS_PanelType05_1 = (SiS_LVDSDesStruct *) SiS300_PanelType05_1;
+   SiS_PanelType06_1 = (SiS_LVDSDesStruct *) SiS300_PanelType06_1;
+   SiS_PanelType07_1 = (SiS_LVDSDesStruct *) SiS300_PanelType07_1;
+   SiS_PanelType08_1 = (SiS_LVDSDesStruct *) SiS300_PanelType08_1;
+   SiS_PanelType09_1 = (SiS_LVDSDesStruct *) SiS300_PanelType09_1;
+   SiS_PanelType0a_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0a_1;
+   SiS_PanelType0b_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0b_1;
+   SiS_PanelType0c_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0c_1;
+   SiS_PanelType0d_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0d_1;
+   SiS_PanelType0e_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0e_1;
+   SiS_PanelType0f_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0f_1;
+   SiS_PanelType00_2 = (SiS_LVDSDesStruct *) SiS300_PanelType00_2;
+   SiS_PanelType01_2 = (SiS_LVDSDesStruct *) SiS300_PanelType01_2;
+   SiS_PanelType02_2 = (SiS_LVDSDesStruct *) SiS300_PanelType02_2;
+   SiS_PanelType03_2 = (SiS_LVDSDesStruct *) SiS300_PanelType03_2;
+   SiS_PanelType04_2 = (SiS_LVDSDesStruct *) SiS300_PanelType04_2;
+   SiS_PanelType05_2 = (SiS_LVDSDesStruct *) SiS300_PanelType05_2;
+   SiS_PanelType06_2 = (SiS_LVDSDesStruct *) SiS300_PanelType06_2;
+   SiS_PanelType07_2 = (SiS_LVDSDesStruct *) SiS300_PanelType07_2;
+   SiS_PanelType08_2 = (SiS_LVDSDesStruct *) SiS300_PanelType08_2;
+   SiS_PanelType09_2 = (SiS_LVDSDesStruct *) SiS300_PanelType09_2;
+   SiS_PanelType0a_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0a_2;
+   SiS_PanelType0b_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0b_2;
+   SiS_PanelType0c_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0c_2;
+   SiS_PanelType0d_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0d_2;
+   SiS_PanelType0e_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0e_2;
+   SiS_PanelType0f_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0f_2;
+   SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *) SiS300_CHTVUNTSCDesData;
+   SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *) SiS300_CHTVONTSCDesData;
+   SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *) SiS300_CHTVUPALDesData;
+   SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *) SiS300_CHTVOPALDesData;
+   SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_1;
+   SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_1;
+   SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_1;
+   SiS_LVDSCRT11024x600_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x600_1;
+   SiS_LVDSCRT11152x768_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11152x768_1;
+   SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_1_H;
+   SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_1_H;
+   SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_1_H;
+   SiS_LVDSCRT11024x600_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x600_1_H;
+   SiS_LVDSCRT11152x768_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11152x768_1_H;
+   SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_2;
+   SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_2;
+   SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_2;
+   SiS_LVDSCRT11024x600_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x600_2;
+   SiS_LVDSCRT11152x768_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11152x768_2;
+   SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_2_H;
+   SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_2_H;
+   SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_2_H;
+   SiS_LVDSCRT11024x600_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x600_2_H;
+   SiS_LVDSCRT11152x768_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11152x768_2_H;
+   SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1UNTSC;
+   SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1ONTSC;
+   SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1UPAL;
+   SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1OPAL;
+   SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_UNTSC;
+   SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_ONTSC;
+   SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_UPAL;
+   SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_OPAL;
+   SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
+   SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
+   SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL;
+   SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL;
+
+   Panel320x480 = Panel300_320x480;
+   Panel640x480 = Panel300_640x480;
+   Panel800x600 = Panel300_800x600;
+   Panel1024x768 = Panel300_1024x768;
+   Panel1280x1024 = Panel300_1280x1024;
+   Panel1280x960 = Panel300_1280x960;
+   Panel1024x600 = Panel300_1024x600;
+   Panel1152x768 = Panel300_1152x768;
+   Panel1600x1200 = 16;  /*Panel300_1600x1200;  OLD */
+   Panel1400x1050 = 16;  /* TW: Something illegal */
+   Panel1152x864 = 16;   /* TW: Something illegal */
+   Panel1280x768 = 16;   /* TW: Something illegal */
+   Panel1024x600 = 16;   /* TW: Something illegal */
+   PanelMax = Panel300_320x480;        /* TW: highest value */
+   PanelMinLVDS = Panel300_800x600;    /* TW: Lowest value LVDS */
+   PanelMin301 = Panel310_1024x768;    /* TW: lowest value 301 */
+
+}
+#endif
+
+#ifdef SIS315H
+void
+InitTo310Pointer(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   SiS_SModeIDTable = (SiS_StStruct *) SiS310_SModeIDTable;
+   SiS_StandTable   = (SiS_StandTableStruct *) SiS310_StandTable;
+   SiS_EModeIDTable = (SiS_ExtStruct *) SiS310_EModeIDTable;
+   SiS_RefIndex     = (SiS_Ext2Struct *) SiS310_RefIndex;
+   SiS_CRT1Table    = (SiS_CRT1TableStruct *) SiS310_CRT1Table;
+
+   /* TW: MCLK is different */
+   if(HwDeviceExtension->jChipType > SIS_315PRO) {
+      SiS_MCLKData_0 = (SiS_MCLKDataStruct *) SiS310_MCLKData_0_650;  /* 550, 650 */
+   } else {
+      SiS_MCLKData_0 = (SiS_MCLKDataStruct *) SiS310_MCLKData_0_315;  /* 315 */
+   }
+   SiS_MCLKData_1    = (SiS_MCLKDataStruct *) SiS310_MCLKData_1;
+   SiS_ECLKData      = (SiS_ECLKDataStruct *) SiS310_ECLKData;
+   SiS_VCLKData      = (SiS_VCLKDataStruct *) SiS310_VCLKData;
+   SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *) SiS310_VBVCLKData;
+
+   SiS_ScreenOffset = SiS310_ScreenOffset;
+   SiS_StResInfo = (SiS_StResInfoStruct *) SiS310_StResInfo;
+   SiS_ModeResInfo = (SiS_ModeResInfoStruct *) SiS310_ModeResInfo;
+
+   pSiS_OutputSelect = &SiS310_OutputSelect;
+   pSiS_SoftSetting = &SiS310_SoftSetting;
+   pSiS_SR07 = &SiS310_SR07;
+   SiS_SR15 = SiS310_SR15;
+   SiS_CR40 = SiS310_CR40;
+   SiS_CR49 = SiS310_CR49;
+   pSiS_SR1F = &SiS310_SR1F;
+   pSiS_SR21 = &SiS310_SR21;
+   pSiS_SR22 = &SiS310_SR22;
+   pSiS_SR23 = &SiS310_SR23;
+   pSiS_SR24 = &SiS310_SR24;
+   SiS_SR25 = SiS310_SR25;
+   pSiS_SR31 = &SiS310_SR31;
+   pSiS_SR32 = &SiS310_SR32;
+   pSiS_SR33 = &SiS310_SR33;
+   pSiS_CRT2Data_1_2 = &SiS310_CRT2Data_1_2;
+   pSiS_CRT2Data_4_D = &SiS310_CRT2Data_4_D;
+   pSiS_CRT2Data_4_E = &SiS310_CRT2Data_4_E;
+   pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
+   pSiS_RGBSenseData = &SiS310_RGBSenseData;
+   pSiS_VideoSenseData = &SiS310_VideoSenseData;
+   pSiS_YCSenseData = &SiS310_YCSenseData;
+   pSiS_RGBSenseData2 = &SiS310_RGBSenseData2;
+   pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
+   pSiS_YCSenseData2 = &SiS310_YCSenseData2;
+   SiS_NTSCPhase = SiS310_NTSCPhase;
+   SiS_PALPhase = SiS310_PALPhase;
+   SiS_NTSCPhase2 = SiS310_NTSCPhase2;
+   SiS_PALPhase2 = SiS310_PALPhase2;
+   SiS_PALMPhase = SiS310_PALMPhase;
+   SiS_PALNPhase = SiS310_PALNPhase;
+   SiS_PALMPhase2 = SiS310_PALMPhase2;
+   SiS_PALNPhase2 = SiS310_PALNPhase2;
+
+   SiS_StLCD1024x768Data = (SiS_LCDDataStruct *) SiS310_StLCD1024x768Data;
+   SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *) SiS310_ExtLCD1024x768Data;
+   SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *) SiS310_St2LCD1024x768Data;
+   SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *) SiS310_StLCD1280x1024Data;
+   SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *) SiS310_ExtLCD1280x1024Data;
+   SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *) SiS310_St2LCD1280x1024Data;
+   SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *) SiS310_NoScaleData1024x768;
+   SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *) SiS310_NoScaleData1280x1024;
+   SiS_LCD1280x960Data = (SiS_LCDDataStruct *) SiS310_LCD1280x960Data;
+   SiS_StPALData = (SiS_TVDataStruct *) SiS310_StPALData;
+   SiS_ExtPALData = (SiS_TVDataStruct *) SiS310_ExtPALData;
+   SiS_StNTSCData = (SiS_TVDataStruct *) SiS310_StNTSCData;
+   SiS_ExtNTSCData = (SiS_TVDataStruct *) SiS310_ExtNTSCData;
+   SiS_St1HiTVData = (SiS_TVDataStruct *) SiS310_St1HiTVData;
+   SiS_St2HiTVData = (SiS_TVDataStruct *) SiS310_St2HiTVData;
+   SiS_ExtHiTVData = (SiS_TVDataStruct *) SiS310_ExtHiTVData;
+   SiS_NTSCTiming = SiS310_NTSCTiming;
+   SiS_PALTiming = SiS310_PALTiming;
+   SiS_HiTVSt1Timing = SiS310_HiTVSt1Timing;
+   SiS_HiTVSt2Timing = SiS310_HiTVSt2Timing;
+   SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
+   SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
+   SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
+   SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
+
+   SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *) SiS310_PanelDelayTbl;
+   SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *) SiS310_PanelDelayTblLVDS;
+
+   SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *) SiS310_LVDS800x600Data_1;
+   SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *) SiS310_LVDS800x600Data_2;
+   SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *) SiS310_LVDS1024x768Data_1;
+   SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *) SiS310_LVDS1024x768Data_2;
+   SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS1280x1024Data_1;
+   SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *) SiS310_LVDS1280x1024Data_2;
+   SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *) SiS310_LVDS1280x960Data_1;
+   SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *) SiS310_LVDS1280x960Data_2;
+   SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS1400x1050Data_1;
+   SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *) SiS310_LVDS1400x1050Data_2;
+   SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *) SiS310_LVDS1024x600Data_1;
+   SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *) SiS310_LVDS1024x600Data_2;
+   SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *) SiS310_LVDS1152x768Data_1;
+   SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *) SiS310_LVDS1152x768Data_2;
+   SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *) SiS310_LVDSXXXxXXXData_1;
+   SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *) SiS310_LVDS320x480Data_1;
+   SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *) SiS310_LVDS640x480Data_1;
+   SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *) SiS310_CHTVUNTSCData;
+   SiS_CHTVONTSCData = (SiS_LVDSDataStruct *) SiS310_CHTVONTSCData;
+   SiS_CHTVUPALData  = (SiS_LVDSDataStruct *) SiS310_CHTVUPALData;
+   SiS_CHTVOPALData  = (SiS_LVDSDataStruct *) SiS310_CHTVOPALData;
+   SiS_PanelType00_1 = (SiS_LVDSDesStruct *) SiS310_PanelType00_1;
+   SiS_PanelType01_1 = (SiS_LVDSDesStruct *) SiS310_PanelType01_1;
+   SiS_PanelType02_1 = (SiS_LVDSDesStruct *) SiS310_PanelType02_1;
+   SiS_PanelType03_1 = (SiS_LVDSDesStruct *) SiS310_PanelType03_1;
+   SiS_PanelType04_1 = (SiS_LVDSDesStruct *) SiS310_PanelType04_1;
+   SiS_PanelType05_1 = (SiS_LVDSDesStruct *) SiS310_PanelType05_1;
+   SiS_PanelType06_1 = (SiS_LVDSDesStruct *) SiS310_PanelType06_1;
+   SiS_PanelType07_1 = (SiS_LVDSDesStruct *) SiS310_PanelType07_1;
+   SiS_PanelType08_1 = (SiS_LVDSDesStruct *) SiS310_PanelType08_1;
+   SiS_PanelType09_1 = (SiS_LVDSDesStruct *) SiS310_PanelType09_1;
+   SiS_PanelType0a_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0a_1;
+   SiS_PanelType0b_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0b_1;
+   SiS_PanelType0c_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0c_1;
+   SiS_PanelType0d_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0d_1;
+   SiS_PanelType0e_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0e_1;
+   SiS_PanelType0f_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0f_1;
+   SiS_PanelType00_2 = (SiS_LVDSDesStruct *) SiS310_PanelType00_2;
+   SiS_PanelType01_2 = (SiS_LVDSDesStruct *) SiS310_PanelType01_2;
+   SiS_PanelType02_2 = (SiS_LVDSDesStruct *) SiS310_PanelType02_2;
+   SiS_PanelType03_2 = (SiS_LVDSDesStruct *) SiS310_PanelType03_2;
+   SiS_PanelType04_2 = (SiS_LVDSDesStruct *) SiS310_PanelType04_2;
+   SiS_PanelType05_2 = (SiS_LVDSDesStruct *) SiS310_PanelType05_2;
+   SiS_PanelType06_2 = (SiS_LVDSDesStruct *) SiS310_PanelType06_2;
+   SiS_PanelType07_2 = (SiS_LVDSDesStruct *) SiS310_PanelType07_2;
+   SiS_PanelType08_2 = (SiS_LVDSDesStruct *) SiS310_PanelType08_2;
+   SiS_PanelType09_2 = (SiS_LVDSDesStruct *) SiS310_PanelType09_2;
+   SiS_PanelType0a_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0a_2;
+   SiS_PanelType0b_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0b_2;
+   SiS_PanelType0c_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0c_2;
+   SiS_PanelType0d_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0d_2;
+   SiS_PanelType0e_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0e_2;
+   SiS_PanelType0f_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0f_2;
+
+   LVDS1024x768Des_1 = (SiS_LVDSDesStruct *) SiS310_PanelType1076_1;
+   LVDS1280x1024Des_1= (SiS_LVDSDesStruct *) SiS310_PanelType1210_1;
+   LVDS1280x960Des_1 = (SiS_LVDSDesStruct *) SiS310_PanelType1296_1 ;
+   LVDS1024x768Des_2 = (SiS_LVDSDesStruct *) SiS310_PanelType1076_2;
+   LVDS1280x1024Des_2= (SiS_LVDSDesStruct *) SiS310_PanelType1210_2;
+   LVDS1280x960Des_2 = (SiS_LVDSDesStruct *) SiS310_PanelType1296_2;
+
+   /* TW: New from 650/301LV BIOS */
+   SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1024x768_1;
+   SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1280x1024_1;
+   SiS_CRT2Part2_1024x768_2  = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1024x768_2;
+   SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1280x1024_2;
+   SiS_CRT2Part2_1024x768_3  = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1024x768_3;
+   SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1280x1024_3;
+
+   SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *) SiS310_CHTVUNTSCDesData;
+   SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *) SiS310_CHTVONTSCDesData;
+   SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *) SiS310_CHTVUPALDesData;
+   SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *) SiS310_CHTVOPALDesData;
+
+   SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_1;
+   SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_1;
+   SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_1;
+   SiS_LVDSCRT11400x1050_1   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11400x1050_1;
+   SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x600_1;
+   SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11152x768_1;
+   SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_1_H;
+   SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_1_H;
+   SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_1_H;
+   SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11400x1050_1_H;
+   SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x600_1_H;
+   SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11152x768_1_H;
+   SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_2;
+   SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_2;
+   SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_2;
+   SiS_LVDSCRT11400x1050_2   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11400x1050_2;
+   SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x600_2;
+   SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11152x768_2;
+   SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_2_H;
+   SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_2_H;
+   SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_2_H;
+   SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11400x1050_2_H;
+   SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x600_2_H;
+   SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11152x768_2_H;
+   SiS_LVDSCRT1XXXxXXX_1     = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1XXXxXXX_1;
+   SiS_LVDSCRT1320x480_1     = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1320x480_1;
+   SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1UNTSC;
+   SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1ONTSC;
+   SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1UPAL;
+   SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1OPAL;
+   SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_UNTSC;
+   SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_ONTSC;
+   SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_UPAL;
+   SiS_CHTVReg_OPAL  = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_OPAL;
+   SiS_LCDACRT1800x600_1     = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_1;
+   SiS_LCDACRT11024x768_1    = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_1;
+   SiS_LCDACRT11280x1024_1   = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_1;
+   SiS_LCDACRT1800x600_1_H   = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_1_H;
+   SiS_LCDACRT11024x768_1_H  = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_1_H;
+   SiS_LCDACRT11280x1024_1_H = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_1_H;
+   SiS_LCDACRT1800x600_2     = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_2;
+   SiS_LCDACRT11024x768_2    = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_2;
+   SiS_LCDACRT11280x1024_2   = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_2;
+   SiS_LCDACRT1800x600_2_H   = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_2_H;
+   SiS_LCDACRT11024x768_2_H  = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_2_H;
+   SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_2_H;
+   SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
+   SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
+   SiS_CHTVVCLKUPAL  = SiS310_CHTVVCLKUPAL;
+   SiS_CHTVVCLKOPAL  = SiS310_CHTVVCLKOPAL;
+
+   Panel320x480 = Panel310_320x480;
+   Panel640x480 = Panel310_640x480;
+   Panel800x600 = Panel310_800x600;
+   Panel1024x768 = Panel310_1024x768;
+   Panel1280x1024 = Panel310_1280x1024;
+   Panel1280x960 = Panel310_1280x960;
+   Panel1600x1200 = Panel310_1600x1200;
+   Panel1400x1050 = Panel310_1400x1050;
+   Panel1152x768 = Panel310_1152x768;
+   Panel1152x864 = Panel310_1152x864;
+   Panel1280x768 = Panel310_1280x768;
+   Panel1024x600 = Panel310_1024x600;
+   PanelMax = Panel310_320x480;       /* TW: highest value */
+   PanelMinLVDS = Panel310_800x600;   /* TW: lowest value LVDS */
+   PanelMin301 = Panel310_1024x768;   /* TW: lowest value 301 */
 
+}
 #endif
 
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		SR12 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x12);
-		SR13 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x13);
-		SR14 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x14);
-		SR16 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x16);
-		SR17 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x17);
-		SR18 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x18);
-		SR19 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x19);
-		SR1A = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x1A);
-	} else {
-		SR13 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x13);
-		SR14 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x14);
-	}
-#endif
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_550)) {
-		CR39 = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x39);
-		CR3A = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3A);
-		CR3B = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3B);
-		CR3C = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3C);
-		CR3D = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3D);
-		CR3E = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3E);
-		CR3F = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3F);
-		CR79 = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x79);
-		CR7A = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x7A);
-		CR7B = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x7B);
-		CR7C = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x7C);
-	} else if ((HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-		   (HwDeviceExtension->jChipType == SIS_740)) {
-		SR12 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x12);
-		SR13 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x13);
-		SR14 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x14);
-		SR16 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x16);
-		SR17 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x17);
-		SR18 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x18);
-		SR19 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x19);
-		SR1A = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x1A);
-	}
-#endif
-/* ResetExtReg begin */
-	for (i = 0x06; i < 0x20; i++)
-		SiS_SetReg1 (SiS_P3c4, i, 0);	/* 2.Reset Extended register */
-	for (i = 0x21; i <= 0x27; i++)
-		SiS_SetReg1 (SiS_P3c4, i, 0);	/*   Reset Extended register */
-	for (i = 0x31; i <= 0x3D; i++)
-		SiS_SetReg1 (SiS_P3c4, i, 0);
-
-#ifdef CONFIG_FB_SIS_300H
-	for (i = 0x38; i <= 0x3F; i++)
-		SiS_SetReg1 (SiS_P3d4, i, 0);
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-	for (i = 0x37; i <= 0x3F; i++)
-		SiS_SetReg1 (SiS_P3d4, i, 0);
-	for (i = 0x79; i <= 0x7C; i++)
-		SiS_SetReg1 (SiS_P3d4, i, 0);
+#ifndef LINUX_XF86
+/* -------------- SiSInit -----------------*/
+BOOLEAN
+SiSInit(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
+   ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
+   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+   UCHAR   i,temp=0;
+   UCHAR   SR11;
+#ifdef LINUX_KERNEL
+   UCHAR   temp1;
+   ULONG   base;
 #endif
-/* ResetExtReg end */
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		SiS_SetReg1 (SiS_P3c4, 0x12, SR12);
-		SiS_SetReg1 (SiS_P3c4, 0x13, SR13);
-		SiS_SetReg1 (SiS_P3c4, 0x14, SR14);
-		SiS_SetReg1 (SiS_P3c4, 0x16, SR16);
-		SiS_SetReg1 (SiS_P3c4, 0x17, SR17);
-		SiS_SetReg1 (SiS_P3c4, 0x18, SR18);
-		SiS_SetReg1 (SiS_P3c4, 0x19, SR19);
-		SiS_SetReg1 (SiS_P3c4, 0x1A, SR1A);
-	}
+   UCHAR   SR13=0,SR14=0,SR16=0,SR17=0,SR19=0,SR1A=0;
+#ifdef SIS300
+   UCHAR   SR18=0,SR12=0;
 #endif
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_550)) {
-		SiS_SetReg1 (SiS_P3d4, 0x39, CR39);
-		SiS_SetReg1 (SiS_P3d4, 0x3A, CR3A);
-		SiS_SetReg1 (SiS_P3d4, 0x3B, CR3B);
-		SiS_SetReg1 (SiS_P3d4, 0x3C, CR3C);
-		SiS_SetReg1 (SiS_P3d4, 0x3D, CR3D);
-		SiS_SetReg1 (SiS_P3d4, 0x3E, CR3E);
-		SiS_SetReg1 (SiS_P3d4, 0x3F, CR3F);
-		SiS_SetReg1 (SiS_P3d4, 0x79, CR79);
-		SiS_SetReg1 (SiS_P3d4, 0x7A, CR7A);
-		SiS_SetReg1 (SiS_P3d4, 0x7B, CR7B);
-		SiS_SetReg1 (SiS_P3d4, 0x7C, CR7C);
-	} else if ((HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-		   (HwDeviceExtension->jChipType == SIS_740)) {
-		SiS_SetReg1 (SiS_P3c4, 0x12, SR12);
-		SiS_SetReg1 (SiS_P3c4, 0x13, SR13);
-		SiS_SetReg1 (SiS_P3c4, 0x14, SR14);
-		SiS_SetReg1 (SiS_P3c4, 0x16, SR16);
-		SiS_SetReg1 (SiS_P3c4, 0x17, SR17);
-		SiS_SetReg1 (SiS_P3c4, 0x18, SR18);
-		SiS_SetReg1 (SiS_P3c4, 0x19, SR19);
-		SiS_SetReg1 (SiS_P3c4, 0x1A, SR1A);
-	}
+#ifdef SIS315H
+   UCHAR   CR37=0,CR38=0,CR79=0,CR7A=0,CR7B=0,CR7C=0;
+   UCHAR   SR1B=0,SR15=0;
+   PSIS_DSReg  pSR;
+   ULONG   Temp;
 #endif
+   UCHAR   VBIOSVersion[5];
+
+   if(FBAddr==0)    return (FALSE);
+   if(BaseAddr==0)  return (FALSE);
 
-/* detect ExtChip Type */
-	SiS_Set_LVDS_TRUMPION (HwDeviceExtension);	/*2/29/00 by Mars Wen for LVDS and Trumpion  */
+   SiS_SetReg3((USHORT)(BaseAddr+0x12),  0x67);  /* 3c2 <- 67 ,ynlai */
 
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		temp = (UCHAR) SR1A;
-	} else
+#ifdef SIS315H
+   /*if(HwDeviceExtension->jChipType > SIS_315H)*/
+   if(HwDeviceExtension->jChipType > SIS_315PRO) {
+     if(!HwDeviceExtension->bIntegratedMMEnabled)
+     	return (FALSE);  /* alan  */
+   }
 #endif
-	{
-		if ((*pSiS_SoftSetting & SoftDRAMType) == 0) {
-			temp = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x3A);
-		}
-	}
 
-	SiS_RAMType = temp & 0x03;
-	SiS_SetMemoryClock (ROMAddr);
+   SiS_MemoryCopy(VBIOSVersion,HwDeviceExtension->szVBIOSVer,4);
+   VBIOSVersion[4]= 0x0;
+   /* 09/07/99 modify by domao */
 
-/* SetDefExt1Regs  begin */
-	SiS_SetReg1 (SiS_P3c4, 0x07, *pSiS_SR07);
-	if ((HwDeviceExtension->jChipType != SIS_540) &&
-	    (HwDeviceExtension->jChipType != SIS_630) &&
-	    (HwDeviceExtension->jChipType != SIS_730)) {
-		for (i = 0x15; i < 0x1C; i++) {
-			SiS_SetReg1 (SiS_P3c4, i,
-				     SiS_SR15[i - 0x15][SiS_RAMType]);
-		}
-	}
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO)) {
-		for (i = 0x40; i <= 0x44; i++) {
-			SiS_SetReg1 (SiS_P3d4, i,
-				     SiS_CR40[i - 0x40][SiS_RAMType]);
-		}
-		SiS_SetReg1 (SiS_P3d4, 0x48, 0x23);
-		SiS_SetReg1 (SiS_P3d4, 0x49, SiS_CR49[0]);
-		/* /SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[0]);  */
-	}
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_315H)||
+      (HwDeviceExtension->jChipType == SIS_315PRO)||
+      (HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650))
+     InitTo310Pointer(HwDeviceExtension);
 #endif
 
-	SiS_SetReg1 (SiS_P3c4, 0x1F, *pSiS_SR1F);
-	/*SiS_SetReg1(SiS_P3c4,0x20,0x20); */
-	SiS_SetReg1 (SiS_P3c4, 0x20, 0xA0);	/* alan, 2001/6/26 Frame buffer can read/write */
-	SiS_SetReg1 (SiS_P3c4, 0x23, *pSiS_SR23);
-	SiS_SetReg1 (SiS_P3c4, 0x24, *pSiS_SR24);
-	SiS_SetReg1 (SiS_P3c4, 0x25, SiS_SR25[0]);
-#ifdef CONFIG_FB_SIS_300
-	if (HwDeviceExtension->jChipType == SIS_300) {
-		SiS_SetReg1 (SiS_P3c4, 0x21, 0x84);
-		SiS_SetReg1 (SiS_P3c4, 0x22, 0x00);
-	}
+#ifdef SIS300
+   if ((HwDeviceExtension->jChipType == SIS_540)||
+       (HwDeviceExtension->jChipType == SIS_630)||
+       (HwDeviceExtension->jChipType == SIS_730)||
+       (HwDeviceExtension->jChipType == SIS_300))
+     InitTo300Pointer(HwDeviceExtension);
 #endif
-	SR11 = 0x0F;
-	SiS_SetReg1 (SiS_P3c4, 0x11, SR11);
 
-	SiS_UnLockCRT2 (HwDeviceExtension, BaseAddr);
-	SiS_SetReg1 (SiS_Part1Port, 0x00, 0x00);
-	SiS_SetReg1 (SiS_Part1Port, 0x02, *pSiS_CRT2Data_1_2);
-#ifdef CONFIG_FB_SIS_315	/* 05/02/01 ynlai  for sis550 */
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO) ||
-	    (HwDeviceExtension->jChipType == SIS_550) ||
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740))
-		/* 09/03/01 chiawen for 650 */
-		SiS_SetReg1 (SiS_Part1Port, 0x2E, 0x08);	/* use VB */
-#endif
-
-	temp = *pSiS_SR32;
-	if (SiS_BridgeIsOn (BaseAddr)) {
-		temp = temp & 0xEF;
-	}
-	SiS_SetReg1 (SiS_P3c4, 0x32, temp);
+   /* TW: Set SiS Register globals */
+   SiSRegInit(BaseAddr);
 
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO)) {
-		HwDeviceExtension->pQueryVGAConfigSpace (HwDeviceExtension,
-							 0x50, 0, &Temp);	/* Get */
-
-		Temp >>= 20;
-		Temp &= 0xF;
-		if (Temp != 1) {
-			SiS_SetReg1 (SiS_P3c4, 0x25, SiS_SR25[1]);
-			SiS_SetReg1 (SiS_P3d4, 0x49, SiS_CR49[1]);
-		}
-
-		SiS_SetReg1 (SiS_P3c4, 0x27, 0x1F);
-
-		SiS_SetReg1 (SiS_P3c4, 0x31, *pSiS_SR31);
-		SiS_SetReg1 (SiS_P3c4, 0x32, *pSiS_SR32);
-		SiS_SetReg1 (SiS_P3c4, 0x33, *pSiS_SR33);
-	}
+   /* TW: Determine LVDS/CH70xx/TRUMPION */
+   SiS_Set_LVDS_TRUMPION(HwDeviceExtension);
+
+   SiS_SetReg1(SiS_P3c4,0x05,0x86);                     /* 1.Openkey - unlock registers */
+
+#ifdef LINUX_KERNEL
+
+#ifdef SIS300                                         	/* Set SR14*/
+   if((HwDeviceExtension->jChipType==SIS_540)||
+      (HwDeviceExtension->jChipType==SIS_630)||
+      (HwDeviceExtension->jChipType==SIS_730)) {
+     base=0x80000060;
+     OutPortLong(base,0xcf8);
+     temp1=InPortLong(0xcfc);
+     temp1 >>= (16+8+4);
+     temp1 &= 0x07;
+     temp1++;
+     temp1 = 1 << temp1;
+     SR14 = temp1 - 1;
+     base=0x80000064;
+     OutPortLong(base,0xcf8);
+     temp1 = InPortLong(0xcfc);
+     temp1 &= 0x00000020;
+     if(temp1) 	SR14 |= 0x80;
+     else      	SR14 |= 0x40;
+   }
+#endif
+
+#ifdef SIS315H                                         /* Set SR14*/
+   if(HwDeviceExtension->jChipType==SIS_550) {
+     base=0x80000060;
+     OutPortLong(base,0xcf8);
+     temp1 = InPortLong(0xcfc);
+     temp1 >>= (16+8+4);
+     temp1 &= 0x07;
+     temp1++;
+     temp1 = 1 << temp1;
+     SR14 = temp1 - 1;
+     base=0x80000064;
+     OutPortLong(base,0xcf8);
+     temp1 = InPortLong(0xcfc);
+     temp1 &= 0x00000020;
+     if(temp1)  SR14 |= 0x80;
+     else       SR14 |= 0x40;
+   }
+
+   if((HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650)) {
+     base=0x80000064;
+     OutPortLong(base,0xcf8);
+     temp1=InPortLong(0xcfc);
+     temp1 >>= 4;
+     temp1 &= 0x07;
+     if(temp1 > 2) {
+       temp = temp1;
+       switch(temp) {
+        case 3: temp1=0x07;  break;
+        case 4: temp1=0x0F;  break;
+        case 5: temp1=0x1F;  break;
+        case 6: temp1=0x05;  break;
+        case 7: temp1=0x17;  break;
+        case 8: break;
+        case 9: break;
+       }
+     }
+     SR14 = temp1;
+     base=0x8000007C;
+     OutPortLong(base,0xcf8);
+     temp1 = InPortLong(0xcfc);
+     temp1 &= 0x00000020;
+     if(temp1)  SR14 |= 0x80;
+   }
+#endif
+
+#endif  /* Linux kernel */
+
+#ifdef SIS300
+   if((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730)) {
+     SR12 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x12);
+     SR13 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13);
+     SR14 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x14);
+     SR16 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x16);
+     SR17 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x17);
+     SR18 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x18);
+     SR19 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x19);
+     SR1A = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
+   } else if(HwDeviceExtension->jChipType == SIS_300){
+     SR13 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13);
+     SR14 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x14);
+   }
+#endif
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650)) {
+     SR19 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x19);
+     SR19 = (SR19)||0x01;  /* TW: ??? || ??? */
+     if(SR19==0x00) {
+     	SR13 = 0x22;
+     	SR14 = 0x00;
+    	SR15 = 0x01;
+     	SR16 = 0x00;
+     	SR17 = 0x00;
+     	SR1A = 0x00;
+     	SR1B = 0x00;
+     	CR37 = 0x00;
+     	CR38 = 0x00;
+     	CR79 = 0x00;
+     	CR7A = 0x00;
+     	CR7B = 0x00;
+     	CR7C = 0x00;
+     } else {
+     	SR13 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13);
+     	SR14 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x14);
+     	SR15 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x15);
+     	SR16 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x16);
+     	SR17 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x17);
+     	SR1A = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
+     	SR1B = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1B);
+     	CR37 = (UCHAR)SiS_GetReg1(SiS_P3d4,0x37);  /* TW: Was 0x02 - why? */
+     	CR38 = (UCHAR)SiS_GetReg1(SiS_P3d4,0x38);
+     	CR79 = (UCHAR)SiS_GetReg1(SiS_P3d4,0x79);
+     	CR7A = (UCHAR)SiS_GetReg1(SiS_P3d4,0x7A);
+     	CR7B = (UCHAR)SiS_GetReg1(SiS_P3d4,0x7B);
+     	CR7C = (UCHAR)SiS_GetReg1(SiS_P3d4,0x7C);
+     }
+   }
+#endif
+
+/* ResetExtReg begin: Reset extended registers */
+
+   for(i=0x06;i< 0x20;i++) SiS_SetReg1(SiS_P3c4,i,0);   /* 2.Reset Extended registers */
+   for(i=0x21;i<=0x27;i++) SiS_SetReg1(SiS_P3c4,i,0);
+   for(i=0x31;i<=0x3D;i++) SiS_SetReg1(SiS_P3c4,i,0);
+
+#ifdef SIS300
+   if((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730)||
+      (HwDeviceExtension->jChipType == SIS_300)) {
+     	for(i=0x38;i<=0x3F;i++) SiS_SetReg1(SiS_P3d4,i,0);
+   }
+#endif
+
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_315H)||
+      (HwDeviceExtension->jChipType == SIS_315PRO)||
+      (HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650)) {
+   	for(i=0x12;i<=0x1B;i++) SiS_SetReg1(SiS_P3c4,i,0);
+   	for(i=0x79;i<=0x7C;i++) SiS_SetReg1(SiS_P3d4,i,0);
+   }
 #endif
 
-	if (SiS_BridgeIsOn (BaseAddr) == 1) {
-		if (SiS_IF_DEF_LVDS == 0) {
-			SiS_SetReg1 (SiS_Part2Port, 0x00, 0x1C);
-			SiS_SetReg1 (SiS_Part4Port, 0x0D, *pSiS_CRT2Data_4_D);
-			SiS_SetReg1 (SiS_Part4Port, 0x0E, *pSiS_CRT2Data_4_E);
-			SiS_SetReg1 (SiS_Part4Port, 0x10, *pSiS_CRT2Data_4_10);
-			SiS_SetReg1 (SiS_Part4Port, 0x0F, 0x3F);
-		}
-		SiS_LockCRT2 (HwDeviceExtension, BaseAddr);
-	}
-	SiS_SetReg1 (SiS_P3d4, 0x83, 0x00);
+/* ResetExtReg end */
+
+#ifdef SIS300
+   if((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730)) {
+     SiS_SetReg1(SiS_P3c4,0x12,SR12);
+     SiS_SetReg1(SiS_P3c4,0x13,SR13);
+     SiS_SetReg1(SiS_P3c4,0x14,SR14);
+     SiS_SetReg1(SiS_P3c4,0x16,SR16);
+     SiS_SetReg1(SiS_P3c4,0x17,SR17);
+     SiS_SetReg1(SiS_P3c4,0x18,SR18);
+     SiS_SetReg1(SiS_P3c4,0x19,SR19);
+     SiS_SetReg1(SiS_P3c4,0x1A,SR1A);
+   }
+#endif
+
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650)) {
+     SiS_SetReg1(SiS_P3c4,0x13,SR13);
+     SiS_SetReg1(SiS_P3c4,0x14,SR14);
+     SiS_SetReg1(SiS_P3c4,0x15,SR15);
+     SiS_SetReg1(SiS_P3c4,0x16,SR16);
+     SiS_SetReg1(SiS_P3c4,0x17,SR17);
+     SiS_SetReg1(SiS_P3c4,0x19,SR19);
+     SiS_SetReg1(SiS_P3c4,0x1A,SR1A);
+     SiS_SetReg1(SiS_P3c4,0x1B,SR1B);
+     SiS_SetReg1(SiS_P3d4,0x37,CR37);
+     SiS_SetReg1(SiS_P3d4,0x38,CR38);
+     SiS_SetReg1(SiS_P3d4,0x79,CR79);
+     SiS_SetReg1(SiS_P3d4,0x7A,CR7A);
+     SiS_SetReg1(SiS_P3d4,0x7B,CR7B);
+     SiS_SetReg1(SiS_P3d4,0x7C,CR7C);
+   }
+#endif
+
+#ifdef SIS300
+   if((HwDeviceExtension->jChipType==SIS_540)||
+      (HwDeviceExtension->jChipType==SIS_630)||
+      (HwDeviceExtension->jChipType==SIS_730)) {
+     	temp = (UCHAR)SR1A & 0x03;
+   } else if(HwDeviceExtension->jChipType==SIS_300) {
+        /* TW: Nothing? */
+   }
+#endif
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_315H )||
+      (HwDeviceExtension->jChipType == SIS_315PRO)) {
+      	if((*pSiS_SoftSetting & SoftDRAMType) == 0){
+          	temp = (UCHAR)SiS_GetReg1(SiS_P3c4,0x3A) & 0x03;
+        }
+   }
+   if((HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650)) {
+        if((*pSiS_SoftSetting & SoftDRAMType) == 0){
+          	temp = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13) & 0x07;
+        }
+   }
+#endif
+
+   SiS_RAMType = temp;
+   SiS_SetMemoryClock(ROMAddr,HwDeviceExtension);
+
+/* SetDefExt1Regs begin: Set default register contents */
+
+   SiS_SetReg1(SiS_P3c4,0x07,*pSiS_SR07); 		/* DAC speed */
+
+   if((HwDeviceExtension->jChipType != SIS_540) &&
+      (HwDeviceExtension->jChipType != SIS_630) &&
+      (HwDeviceExtension->jChipType != SIS_730)){
+     	for(i=0x15;i<0x1C;i++) {
+       		SiS_SetReg1(SiS_P3c4,i,SiS_SR15[i-0x15][SiS_RAMType]);
+     	}
+   }
+
+#ifdef SIS315H
+   if ((HwDeviceExtension->jChipType == SIS_315H )||
+       (HwDeviceExtension->jChipType == SIS_315PRO)) {
+     	for(i=0x40;i<=0x44;i++) {
+       		SiS_SetReg1(SiS_P3d4,i,SiS_CR40[i-0x40][SiS_RAMType]);
+     	}
+     	SiS_SetReg1(SiS_P3d4,0x48,0x23);
+     	SiS_SetReg1(SiS_P3d4,0x49,SiS_CR49[0]);
+    /*  SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[0]);  */
+   }
+#endif
+
+   SiS_SetReg1(SiS_P3c4,0x1F,*pSiS_SR1F); 	/* DAC pedestal */
+   SiS_SetReg1(SiS_P3c4,0x20,0xA0);
+   SiS_SetReg1(SiS_P3c4,0x23,*pSiS_SR23);
+   SiS_SetReg1(SiS_P3c4,0x24,*pSiS_SR24);
+   SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[0]);
+
+#ifdef SIS300
+   if(HwDeviceExtension->jChipType==SIS_300) {
+     	SiS_SetReg1(SiS_P3c4,0x21,0x84);
+     	SiS_SetReg1(SiS_P3c4,0x22,0x00);
+   }
+#endif
+
+   SR11=0x0F;
+   SiS_SetReg1(SiS_P3c4,0x11,SR11);		/* Power Management & DDC port */
+
+   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+   SiS_SetReg1(SiS_Part1Port,0x00,0x00);
+   SiS_SetReg1(SiS_Part1Port,0x02,*pSiS_CRT2Data_1_2);
+
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_315H) ||
+      (HwDeviceExtension->jChipType == SIS_315PRO) ||
+      (HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650))
+     	SiS_SetReg1(SiS_Part1Port,0x2E,0x08);    /* use VB */
+#endif
+
+   temp=*pSiS_SR32;
+   if(SiS_BridgeIsOn(BaseAddr)) {
+     	temp &= 0xEF;
+   }
+   SiS_SetReg1(SiS_P3c4,0x32,temp);
+
+#ifdef SIS315H
+   if ((HwDeviceExtension->jChipType == SIS_315H) ||
+       (HwDeviceExtension->jChipType == SIS_315PRO)) {
+     HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension,0x50,0,&Temp);  /* Get */
+     Temp >>= 20;
+     Temp &= 0xF;
+     if (Temp!=1) {
+     	SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[1]);
+     	SiS_SetReg1(SiS_P3d4,0x49,SiS_CR49[1]);
+     }
+
+     SiS_SetReg1(SiS_P3c4,0x27,0x1F);
+
+     SiS_SetReg1(SiS_P3c4,0x31,*pSiS_SR31);
+     SiS_SetReg1(SiS_P3c4,0x32,*pSiS_SR32);
+     SiS_SetReg1(SiS_P3c4,0x33,*pSiS_SR33);
+   }
+#endif
+
+   if (SiS_BridgeIsOn(BaseAddr) == 0) {
+     	if(SiS_IF_DEF_LVDS==0) {
+       		SiS_SetReg1(SiS_Part2Port,0x00,0x1C);
+       		SiS_SetReg1(SiS_Part4Port,0x0D,*pSiS_CRT2Data_4_D);
+       		SiS_SetReg1(SiS_Part4Port,0x0E,*pSiS_CRT2Data_4_E);
+       		SiS_SetReg1(SiS_Part4Port,0x10,*pSiS_CRT2Data_4_10);
+       		SiS_SetReg1(SiS_Part4Port,0x0F,0x3F);
+     	}
+     	SiS_LockCRT2(HwDeviceExtension, BaseAddr);
+   }
+   SiS_SetReg1(SiS_P3d4,0x83,0x00);
+
 /*   SetDefExt1Regs end */
 
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO)
-	    ) {			/* 05/02/01 ynlai */
-		/* For SiS 300,310 Chip  */
-		if (HwDeviceExtension->bSkipDramSizing == TRUE) {
-			SiS_SetDRAMModeRegister (ROMAddr);
-			pSR = HwDeviceExtension->pSR;
-			if (pSR != NULL) {
-				while (pSR->jIdx != 0xFF) {
-					SiS_SetReg1 (SiS_P3c4, pSR->jIdx,
-						     pSR->jVal);
-					pSR++;
-				}
-			}
-		} else
-			SiS_SetDRAMSize_310 (HwDeviceExtension);
-	}
-#endif
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_550)) {	/* 05/02/01 ynlai For SiS 550 */
-		/* SetDRAMConfig begin */
+#ifdef SIS315H
+   if ((HwDeviceExtension->jChipType==SIS_315H)||
+       (HwDeviceExtension->jChipType==SIS_315PRO)) {
+       	if (HwDeviceExtension->bSkipDramSizing==TRUE) {
+         	SiS_SetDRAMModeRegister(ROMAddr,HwDeviceExtension);
+         	pSR = HwDeviceExtension->pSR;
+         	if (pSR!=NULL) {
+           		while (pSR->jIdx!=0xFF) {
+             			SiS_SetReg1(SiS_P3c4,pSR->jIdx,pSR->jVal);
+             			pSR++;
+           		}
+         	}
+       } else SiS_SetDRAMSize_310(HwDeviceExtension);
+   }
+#endif
+
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType==SIS_550)){
+       /* SetDRAMConfig begin */
 /*     SiS_SetReg1(SiS_P3c4,0x12,SR12);
        SiS_SetReg1(SiS_P3c4,0x13,SR13);
        SiS_SetReg1(SiS_P3c4,0x14,SR14);
@@ -812,2973 +961,3514 @@
        SiS_SetReg1(SiS_P3c4,0x18,SR18);
        SiS_SetReg1(SiS_P3c4,0x19,SR19);
        SiS_SetReg1(SiS_P3c4,0x1A,SR1A);   */
-		/* SetDRAMConfig end */
-	}
+       /* SetDRAMConfig end */
+   }
 #endif
-#ifdef CONFIG_FB_SIS_300
-	if (HwDeviceExtension->jChipType == SIS_300) {	/* For SiS 300 Chip  */
-		if (HwDeviceExtension->bSkipDramSizing == TRUE) {
-/*       SiS_SetDRAMModeRegister(ROMAddr);
-         temp = (HwDeviceExtension->pSR)->jVal;
-         SiS_SetReg1(SiS_P3c4,0x13,temp);
-         temp = (HwDeviceExtension->pSR)->jVal;
-         SiS_SetReg1(SiS_P3c4,0x14,temp);   */
-		} else {
+
+#ifdef SIS300
+   if( HwDeviceExtension->jChipType==SIS_300) {
+       	if (HwDeviceExtension->bSkipDramSizing==TRUE) {
+/*       	SiS_SetDRAMModeRegister(ROMAddr,HwDeviceExtension);
+         	temp = (HwDeviceExtension->pSR)->jVal;
+         	SiS_SetReg1(SiS_P3c4,0x13,temp);
+         	temp = (HwDeviceExtension->pSR)->jVal;
+         	SiS_SetReg1(SiS_P3c4,0x14,temp);   */
+       } else {
 #ifdef TC
-			SiS_SetReg1 (SiS_P3c4, 0x13, SR13);
-			SiS_SetReg1 (SiS_P3c4, 0x14, SR14);
-			SiS_SetRegANDOR (SiS_P3c4, 0x15, 0xFF, 0x04);
+         	SiS_SetReg1(SiS_P3c4,0x13,SR13);
+         	SiS_SetReg1(SiS_P3c4,0x14,SR14);
+         	SiS_SetRegANDOR(SiS_P3c4,0x15,0xFF,0x04);
 #else
-			SiS_SetDRAMSize_300 (HwDeviceExtension);
-			SiS_SetDRAMSize_300 (HwDeviceExtension);
+         	SiS_SetDRAMSize_300(HwDeviceExtension);
+         	SiS_SetDRAMSize_300(HwDeviceExtension);
 #endif
-		}
-	}
-	if ((HwDeviceExtension->jChipType == SIS_540) ||	/* For SiS 630/540/730 Chip  */
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		/* SetDRAMConfig begin */
-/*     SiS_SetReg1(SiS_P3c4,0x12,SR12);
-       SiS_SetReg1(SiS_P3c4,0x13,SR13);
-       SiS_SetReg1(SiS_P3c4,0x14,SR14);
-       SiS_SetReg1(SiS_P3c4,0x16,SR16);
-       SiS_SetReg1(SiS_P3c4,0x17,SR17);
-       SiS_SetReg1(SiS_P3c4,0x18,SR18);
-       SiS_SetReg1(SiS_P3c4,0x19,SR19);
-       SiS_SetReg1(SiS_P3c4,0x1A,SR1A);    */
-		/* SetDRAMConfig end */
-	}
-/* SetDRAMSize end */
+       }
+   }
+   if((HwDeviceExtension->jChipType==SIS_540)||
+      (HwDeviceExtension->jChipType==SIS_630)||
+      (HwDeviceExtension->jChipType==SIS_730)){
+       	/* SetDRAMConfig begin */
+#if 0
+     	SiS_SetReg1(SiS_P3c4,0x12,SR12);
+       	SiS_SetReg1(SiS_P3c4,0x13,SR13);
+       	SiS_SetReg1(SiS_P3c4,0x14,SR14);
+       	SiS_SetReg1(SiS_P3c4,0x16,SR16);
+       	SiS_SetReg1(SiS_P3c4,0x17,SR17);
+       	SiS_SetReg1(SiS_P3c4,0x18,SR18);
+       	SiS_SetReg1(SiS_P3c4,0x19,SR19);
+       	SiS_SetReg1(SiS_P3c4,0x1A,SR1A);
 #endif
+       	/* SetDRAMConfig end */
+   }
+/* SetDRAMSize end */
+#endif /* SIS300 */
 
 /*   SetDefExt2Regs begin  */
-/* AGP=1;
+#if 0
+   AGP=1;
    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x3A);
    temp=temp&0x30;
    if(temp==0x30) AGP=0;
    if(AGP==0) *pSiS_SR21=*pSiS_SR21&0xEF;
    SiS_SetReg1(SiS_P3c4,0x21,*pSiS_SR21);
    if(AGP==1) *pSiS_SR22=*pSiS_SR22&0x20;
-   SiS_SetReg1(SiS_P3c4,0x22,*pSiS_SR22);  */
-
-	SiS_SetReg1 (SiS_P3c4, 0x21, *pSiS_SR21);
-	SiS_SetReg1 (SiS_P3c4, 0x22, *pSiS_SR22);
-/*   SetDefExt2Regs end  */
-
-/* SiS_SetReg3(SiS_P3c6,0xff);
-   SiS_ClearDAC(SiS_P3c8);        [ynlai] 05/22/01            */
-
-	SiS_DetectMonitor (HwDeviceExtension, BaseAddr);
-	SiS_GetSenseStatus (HwDeviceExtension, ROMAddr);	/* sense CRT2 */
-
-	return (TRUE);
-}
-
-void
-SiS_Set_LVDS_TRUMPION (PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT temp;
-
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		temp = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x1A);
-		temp = (temp & 0xE0) >> 4;
-		SiS_SetRegANDOR (SiS_P3d4, 0x37, 0xF1, temp);
-		temp = temp >> 1;
-		if ((temp == 0) || (temp == 1)) {	/* for 301 */
-			SiS_IF_DEF_LVDS = 0;
-			SiS_IF_DEF_CH7005 = 0;
-			SiS_IF_DEF_TRUMPION = 0;
-		}
-		if ((temp >= 2) && (temp <= 5)) {
-			SiS_IF_DEF_LVDS = 1;
-		}
-		if (temp == 3)
-			SiS_IF_DEF_TRUMPION = 1;
-		if ((temp == 4) || (temp == 5))
-			SiS_IF_DEF_CH7005 = 1;
-	} else {
-		SiS_IF_DEF_LVDS = 0;
-		SiS_IF_DEF_TRUMPION = 0;
-		SiS_IF_DEF_CH7005 = 0;
-	}
-#else
-	if ((HwDeviceExtension->jChipType == SIS_550) ||
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740))
-	 {			/* 09/03/01 chiawen for 650 */
-		SiS_IF_DEF_LVDS = 0;
-		SiS_IF_DEF_TRUMPION = 0;
-		SiS_IF_DEF_CH7005 = 0;
-	}
+   SiS_SetReg1(SiS_P3c4,0x22,*pSiS_SR22);
 #endif
-}
+   SiS_SetReg1(SiS_P3c4,0x21,*pSiS_SR21);
+   SiS_SetReg1(SiS_P3c4,0x22,*pSiS_SR22);
+/*   SetDefExt2Regs end  */
 
-/* ===============  for 300 dram sizing begin  =============== */
-#ifdef CONFIG_FB_SIS_300
-void
-SiS_SetDRAMSize_300 (PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	/*ULONG   ROMAddr  = (ULONG)HwDeviceExtension->pjVirtualRomBase; */
-	ULONG FBAddr = (ULONG) HwDeviceExtension->pjVideoMemoryAddress;
-	/*USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; */
-	USHORT SR13, SR14 = 0, buswidth, Done;
-	SHORT i, j, k;
-	USHORT data, TotalCapacity, PhysicalAdrOtherPage = 0;
-	ULONG Addr;
-	UCHAR temp;
-
-	int PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
-	int RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
-	/*int PageCapacity,PhysicalAdrHigh,PhysicalAdrHalfPage,PhysicalAdrAnotherPage; */
-	int PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage;
-
-	SiSSetMode (HwDeviceExtension, 0x2e);
-	data = SiS_GetReg1 (SiS_P3c4, 0x1);
-	data = data | 0x20;
-	SiS_SetReg1 (SiS_P3c4, 0x01, data);	/* Turn OFF Display  */
-
-	SiS_SetReg1 (SiS_P3c4, 0x13, 0x00);
-	SiS_SetReg1 (SiS_P3c4, 0x14, 0xBF);
-	buswidth = SiS_ChkBUSWidth_300 (FBAddr);
-
-	MB2Bank = 16;
-	Done = 0;
-	for (i = 6; i >= 0; i--) {
-		if (Done == 1)
-			break;
-		PseudoRankCapacity = 1 << i;
-		for (j = 4; j >= 1; j--) {
-			if (Done == 1)
-				break;
-			PseudoTotalCapacity = PseudoRankCapacity * j;
-			PseudoAdrPinCount = 15 - j;
-			if (PseudoTotalCapacity <= 64) {
-				for (k = 0; k <= 16; k++) {
-					if (Done == 1)
-						break;
-					RankCapacity =
-					    buswidth * SiS_DRAMType[k][3];
-					AdrPinCount =
-					    SiS_DRAMType[k][2] +
-					    SiS_DRAMType[k][0];
-					if (RankCapacity == PseudoRankCapacity)
-						if (AdrPinCount <=
-						    PseudoAdrPinCount) {
-							if (j == 3) {	/* Rank No */
-								BankNumHigh =
-								    RankCapacity
-								    * MB2Bank *
-								    3 - 1;
-								BankNumMid =
-								    RankCapacity
-								    * MB2Bank *
-								    1 - 1;
-							} else {
-								BankNumHigh =
-								    RankCapacity
-								    * MB2Bank *
-								    j - 1;
-								BankNumMid =
-								    RankCapacity
-								    * MB2Bank *
-								    j / 2 - 1;
-							}
-							PageCapacity =
-							    (1 <<
-							     SiS_DRAMType[k][1])
-							    * buswidth * 4;
-							PhysicalAdrHigh =
-							    BankNumHigh;
-							PhysicalAdrHalfPage =
-							    (PageCapacity / 2 +
-							     PhysicalAdrHigh) %
-							    PageCapacity;
-							PhysicalAdrOtherPage =
-							    PageCapacity *
-							    SiS_DRAMType[k][2] +
-							    PhysicalAdrHigh;
-							/* Write data */
-							/*Test */
-							temp =
-							    (UCHAR)
-							    SiS_GetReg1
-							    (SiS_P3c4, 0x15);
-							SiS_SetReg1 (SiS_P3c4,
-								     0x15,
-								     (USHORT)
-								     (temp &
-								      0xFB));
-
-							temp =
-							    (UCHAR)
-							    SiS_GetReg1
-							    (SiS_P3c4, 0x15);
-							SiS_SetReg1 (SiS_P3c4,
-								     0x15,
-								     (USHORT)
-								     (temp |
-								      0x04));
-							/*Test */
-							TotalCapacity =
-							    SiS_DRAMType[k][3] *
-							    buswidth;
-							SR13 =
-							    SiS_DRAMType[k][4];
-							if (buswidth == 4)
-								SR14 =
-								    (TotalCapacity
-								     -
-								     1) | 0x80;
-							if (buswidth == 2)
-								SR14 =
-								    (TotalCapacity
-								     -
-								     1) | 0x40;
-							if (buswidth == 1)
-								SR14 =
-								    (TotalCapacity
-								     -
-								     1) | 0x00;
-							SiS_SetReg1 (SiS_P3c4,
-								     0x13,
-								     SR13);
-							SiS_SetReg1 (SiS_P3c4,
-								     0x14,
-								     SR14);
-
-							Addr =
-							    FBAddr +
-							    (BankNumHigh) * 64 *
-							    1024 +
-							    PhysicalAdrHigh;
-							*((USHORT *) (Addr)) =
-							    (USHORT)
-							    PhysicalAdrHigh;
-							Addr =
-							    FBAddr +
-							    (BankNumMid) * 64 *
-							    1024 +
-							    PhysicalAdrHigh;
-							*((USHORT *) (Addr)) =
-							    (USHORT) BankNumMid;
-							Addr =
-							    FBAddr +
-							    (BankNumHigh) * 64 *
-							    1024 +
-							    PhysicalAdrHalfPage;
-							*((USHORT *) (Addr)) =
-							    (USHORT)
-							    PhysicalAdrHalfPage;
-							Addr =
-							    FBAddr +
-							    (BankNumHigh) * 64 *
-							    1024 +
-							    PhysicalAdrOtherPage;
-							*((USHORT *) (Addr)) =
-							    PhysicalAdrOtherPage;
-
-							/* Read data */
-							Addr =
-							    FBAddr +
-							    (BankNumHigh) * 64 *
-							    1024 +
-							    PhysicalAdrHigh;
-							data =
-							    *((USHORT *)
-							      (Addr));
-							if (data ==
-							    PhysicalAdrHigh)
-								    Done = 1;
-						}	/* if struct */
-				}	/* for loop (k) */
-			}	/* if struct */
-		}		/* for loop (j) */
-	}			/* for loop (i) */
+#if 0
+   SiS_SetReg3(SiS_P3c6,0xff);
+   SiS_ClearDAC(SiS_P3c8);        /* [ynlai] 05/22/01 */
+#endif
+
+#ifdef LINUXBIOS   /* TW: This is not needed for our purposes */
+   SiS_DetectMonitor(HwDeviceExtension,BaseAddr);
+   SiS_GetSenseStatus(HwDeviceExtension,ROMAddr);      /* sense CRT2 */
+#endif
+
+   return(TRUE);
+}
+
+void
+SiS_Set_LVDS_TRUMPION(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT temp=0;
+
+#ifdef SiS300
+  if ((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730)) {
+        /* TW: Read POWER_ON_TRAP and copy to CR37 */
+    	temp = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
+    	temp = (temp & 0xE0) >> 4;
+   	SiS_SetRegANDOR(SiS_P3d4,0x37,0xF1,temp);
+  }
+#endif
+#ifdef SIS315H
+  if ((HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650)) {
+#if 0 /* TW: This is not required */
+        /* TW: Read POWER_ON_TRAP and copy to CR37 */
+    	temp = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
+    	temp = (temp & 0xE0) >> 4;
+   	SiS_SetRegANDOR(SiS_P3d4,0x37,0xF1,temp);
+#endif
+  }
+#endif
+
+   /* Set globals SiS_IF_DEF... */
+   SiSSetLVDSetc(HwDeviceExtension, 0);
+}
+
+/* ===============  SiS 300 dram sizing begin  =============== */
+#ifdef SIS300
+void
+SiS_SetDRAMSize_300(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   ULONG   FBAddr = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
+   USHORT  SR13,SR14=0,buswidth,Done;
+   SHORT   i,j,k;
+   USHORT  data, TotalCapacity, PhysicalAdrOtherPage=0;
+   ULONG   Addr;
+   UCHAR   temp;
+   int     PseudoRankCapacity,PseudoTotalCapacity,PseudoAdrPinCount;
+   int     RankCapacity,AdrPinCount,BankNumHigh,BankNumMid,MB2Bank;
+   int     PageCapacity,PhysicalAdrHigh,PhysicalAdrHalfPage;
+
+   SiSSetMode(HwDeviceExtension,0x2e);
+
+   data=SiS_GetReg1(SiS_P3c4,0x01);
+   data=data|0x20;
+   SiS_SetReg1(SiS_P3c4,0x01,data);                    /* Turn OFF Display  */
+
+   SiS_SetReg1(SiS_P3c4,0x13,0x00);
+   SiS_SetReg1(SiS_P3c4,0x14,0xBF);
+   buswidth=SiS_ChkBUSWidth_300(FBAddr);
+
+   MB2Bank=16;
+   Done=0;
+   for(i=6;i>=0;i--) {
+      if(Done==1) break;
+      PseudoRankCapacity=1<<i;
+      for(j=4;j>=1;j--) {
+         if(Done==1) break;
+         PseudoTotalCapacity=PseudoRankCapacity*j;
+         PseudoAdrPinCount=15-j;
+         if(PseudoTotalCapacity <= 64) {
+            for(k=0;k<=16;k++) {
+               if(Done==1) break;
+               RankCapacity=buswidth*SiS_DRAMType[k][3];
+               AdrPinCount=SiS_DRAMType[k][2]+SiS_DRAMType[k][0];
+               if(RankCapacity==PseudoRankCapacity)
+                 if(AdrPinCount<=PseudoAdrPinCount) {
+                    if(j==3) {             /* Rank No */
+                       BankNumHigh=RankCapacity*MB2Bank*3-1;
+                       BankNumMid=RankCapacity*MB2Bank*1-1;
+                    }
+                    else {
+                       BankNumHigh=RankCapacity*MB2Bank*j-1;
+                       BankNumMid=RankCapacity*MB2Bank*j/2-1;
+                    }
+                    PageCapacity=(1<<SiS_DRAMType[k][1])*buswidth*4;
+                    PhysicalAdrHigh =BankNumHigh;
+                    PhysicalAdrHalfPage=(PageCapacity/2+PhysicalAdrHigh)%PageCapacity;
+                    PhysicalAdrOtherPage=PageCapacity*SiS_DRAMType[k][2]+PhysicalAdrHigh;
+                    /* Write data */
+                    /*Test */
+                    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x15);
+                    SiS_SetReg1(SiS_P3c4,0x15,(USHORT)(temp&0xFB));
+
+                    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x15);
+                    SiS_SetReg1(SiS_P3c4,0x15,(USHORT)(temp|0x04));
+                    /*Test */
+                    TotalCapacity=SiS_DRAMType[k][3]*buswidth;
+                    SR13=SiS_DRAMType[k][4];
+                    if(buswidth==4) SR14=(TotalCapacity-1)|0x80;
+                    if(buswidth==2) SR14=(TotalCapacity-1)|0x40;
+                    if(buswidth==1) SR14=(TotalCapacity-1)|0x00;
+                    SiS_SetReg1(SiS_P3c4,0x13,SR13);
+                    SiS_SetReg1(SiS_P3c4,0x14,SR14);
+
+                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrHigh;
+                    *((USHORT *)(Addr)) = (USHORT) PhysicalAdrHigh;
+                    Addr=FBAddr+(BankNumMid)*64*1024+PhysicalAdrHigh;
+                    *((USHORT *)(Addr)) = (USHORT) BankNumMid;
+                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrHalfPage;
+                    *((USHORT *)(Addr)) = (USHORT) PhysicalAdrHalfPage;
+                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrOtherPage;
+                    *((USHORT *)(Addr))=PhysicalAdrOtherPage;
+
+                    /* Read data */
+                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrHigh;
+                    data=*((USHORT *)(Addr));
+                    if(data==PhysicalAdrHigh) Done=1;
+                 }  /* if struct */
+            }  /* for loop (k) */
+         }  /* if struct */
+      }  /* for loop (j) */
+   }  /* for loop (i) */
 }
 
 USHORT
-SiS_ChkBUSWidth_300 (ULONG FBAddress)
+SiS_ChkBUSWidth_300(ULONG FBAddress)
 {
-	/*USHORT  data; */
-	PULONG pVideoMemory;
+   /*USHORT  data;*/
+   PULONG  pVideoMemory;
 
-	pVideoMemory = (PULONG) FBAddress;
+   pVideoMemory = (PULONG) FBAddress;
 
-	pVideoMemory[0] = 0x01234567L;
-	pVideoMemory[1] = 0x456789ABL;
-	pVideoMemory[2] = 0x89ABCDEFL;
-	pVideoMemory[3] = 0xCDEF0123L;
-	if (pVideoMemory[3] == 0xCDEF0123L) {	/*ChannelA128Bit */
-		return (4);
-	}
-	if (pVideoMemory[1] == 0x456789ABL) {	/*ChannelB64Bit */
-		return (2);
-	}
-	return (1);
+   pVideoMemory[0] = 0x01234567L;
+   pVideoMemory[1] = 0x456789ABL;
+   pVideoMemory[2] = 0x89ABCDEFL;
+   pVideoMemory[3] = 0xCDEF0123L;
+   if (pVideoMemory[3]==0xCDEF0123L) { /*ChannelA128Bit */
+     return(4);
+   }
+   if (pVideoMemory[1]==0x456789ABL) {  /*ChannelB64Bit */
+     return(2);
+   }
+   return(1);
 }
 #endif
+/* ===============  SiS 300 dram sizing end    =============== */
 
-/* ===============  for 300 dram sizing end    =============== */
-
-/* ============== alan ====================== */
-#ifdef CONFIG_FB_SIS_315
-UCHAR
-SiS_Get310DRAMType (ULONG ROMAddr)
-{
-	UCHAR data;
-
-	/* 
-	   index=SiS_GetReg1(SiS_P3c4,0x1A);
-	   index=index&07;
-	 */
-	if (*pSiS_SoftSetting & SoftDRAMType)
-		data = *pSiS_SoftSetting & 0x03;
-	else
-		data = SiS_GetReg1 (SiS_P3c4, 0x3a) & 0x03;
+/* ==============  SiS 310 dram sizing begin ================= */
+#ifdef SIS315H
 
-	return data;
-}
+/* TW: Moved Get310DRAMType further down */
 
 void
-SiS_Delay15us (ULONG ulMicrsoSec)
+SiS_Delay15us(ULONG ulMicrsoSec)
 {
 }
 
 void
-SiS_SDR_MRS (void)
+SiS_SDR_MRS(void)
 {
-	USHORT data;
+   USHORT  data;
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x16);
-	data = data & 0x3F;	/*/ SR16 D7=0,D6=0 */
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);	/*/ enable mode register set(MRS) low */
-	SiS_Delay15us (0x100);
-	data = data | 0x80;	/*/ SR16 D7=1,D6=0 */
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);	/*/ enable mode register set(MRS) high */
-	SiS_Delay15us (0x100);
+   data=SiS_GetReg1(SiS_P3c4,0x16);
+   data=data & 0x3F;          		/* SR16 D7=0,D6=0 */
+   SiS_SetReg1(SiS_P3c4,0x16,data);   	/* enable mode register set(MRS) low */
+   SiS_Delay15us(0x100);
+   data=data | 0x80;          		/* SR16 D7=1,D6=0 */
+   SiS_SetReg1(SiS_P3c4,0x16,data);   	/* enable mode register set(MRS) high */
+   SiS_Delay15us(0x100);
 }
 
 void
-SiS_DDR_MRS (void)
+SiS_DDR_MRS(void)
 {
-	USHORT data;
+   USHORT  data;
 
-	/* SR16 <- 1F,DF,2F,AF */
+   /* SR16 <- 1F,DF,2F,AF */
 
-	/* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
-	data = SiS_GetReg1 (SiS_P3c4, 0x16);
-	data &= 0x0F;
-	data |= 0x10;
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);
+   /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
+   data=SiS_GetReg1(SiS_P3c4,0x16);
+   data &= 0x0F;
+   data |= 0x10;
+   SiS_SetReg1(SiS_P3c4,0x16,data);
 
-	if (!(SiS_SR15[1][SiS_RAMType] & 0x10)) {
-		data &= 0x0F;
-	}
-	/* SR16 D7=1,D6=1 */
-	data |= 0xC0;
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);
-
-	/* SR16 D7=1,D6=0,D5=1,D4=0 */
-	data &= 0x0F;
-	data |= 0x20;
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);
-	if (!(SiS_SR15[1][SiS_RAMType] & 0x10)) {
-		data &= 0x0F;
-	}
-	/* SR16 D7=1 */
-	data |= 0x80;
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);
+   if (!(SiS_SR15[1][SiS_RAMType] & 0x10))
+     data &= 0x0F;
+
+   /* SR16 D7=1,D6=1 */
+   data |= 0xC0;
+   SiS_SetReg1(SiS_P3c4,0x16,data);
+   
+   /* SR16 D7=1,D6=0,D5=1,D4=0 */
+   data &= 0x0F;
+   data |= 0x20;
+   SiS_SetReg1(SiS_P3c4,0x16,data);
+   if (!(SiS_SR15[1][SiS_RAMType] & 0x10))
+     data &= 0x0F;
+
+   /* SR16 D7=1 */
+   data |= 0x80;
+   SiS_SetReg1(SiS_P3c4,0x16,data);
 }
 
 void
-SiS_SetDRAMModeRegister (ULONG ROMAddr)
+SiS_SetDRAMModeRegister(UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-
-	if (SiS_Get310DRAMType (ROMAddr) < 2) {
-		SiS_SDR_MRS ();
-	} else {
-		/* SR16 <- 0F,CF,0F,8F */
-		SiS_DDR_MRS ();
-	}
+    if (SiS_Get310DRAMType(ROMAddr,HwDeviceExtension) < 2)
+        SiS_SDR_MRS();
+    else
+        /* SR16 <- 0F,CF,0F,8F */
+        SiS_DDR_MRS();
 }
 
 void
-SiS_DisableRefresh (void)
+SiS_DisableRefresh(void)
 {
-	USHORT data;
-
-	data = SiS_GetReg1 (SiS_P3c4, 0x17);
-	data &= 0xF8;
-	SiS_SetReg1 (SiS_P3c4, 0x17, data);
+   USHORT  data;
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x19);
-	data |= 0x03;
-	SiS_SetReg1 (SiS_P3c4, 0x19, data);
+   data=SiS_GetReg1(SiS_P3c4,0x17);
+   data &= 0xF8;
+   SiS_SetReg1(SiS_P3c4,0x17,data);
 
+   data=SiS_GetReg1(SiS_P3c4,0x19);
+   data |= 0x03;
+   SiS_SetReg1(SiS_P3c4,0x19,data);
 }
 
 void
-SiS_EnableRefresh (ULONG ROMAddr)
+SiS_EnableRefresh(UCHAR *ROMAddr)
 {
-
-	SiS_SetReg1 (SiS_P3c4, 0x17, SiS_SR15[2][SiS_RAMType]);	/* SR17 */
-
-	SiS_SetReg1 (SiS_P3c4, 0x19, SiS_SR15[4][SiS_RAMType]);	/* SR19 */
-
+   SiS_SetReg1(SiS_P3c4,0x17,SiS_SR15[2][SiS_RAMType]);  /* SR17 */
+   SiS_SetReg1(SiS_P3c4,0x19,SiS_SR15[4][SiS_RAMType]);  /* SR19 */
 }
 
 void
-SiS_DisableChannelInterleaving (int index, USHORT SiS_DDRDRAM_TYPE[][5])
+SiS_DisableChannelInterleaving(int index,USHORT SiS_DDRDRAM_TYPE[][5])
 {
-	USHORT data;
-
-	data = SiS_GetReg1 (SiS_P3c4, 0x15);
-	data &= 0x1F;
-	switch (SiS_DDRDRAM_TYPE[index][3]) {
-	case 64:
-		data |= 0;
-		break;
-	case 32:
-		data |= 0x20;
-		break;
-	case 16:
-		data |= 0x40;
-		break;
-	case 4:
-		data |= 0x60;
-		break;
-	}
-	SiS_SetReg1 (SiS_P3c4, 0x15, data);
+   USHORT  data;
 
+   data=SiS_GetReg1(SiS_P3c4,0x15);
+   data &= 0x1F;
+   switch (SiS_DDRDRAM_TYPE[index][3])
+   {
+     case 64: data |= 0; 	break;
+     case 32: data |= 0x20;	break;
+     case 16: data |= 0x40;     break;
+     case 4:  data |= 0x60;     break;
+   }
+   SiS_SetReg1(SiS_P3c4,0x15,data);
 }
 
 void
-SiS_SetDRAMSizingType (int index, USHORT DRAMTYPE_TABLE[][5])
+SiS_SetDRAMSizingType(int index,USHORT DRAMTYPE_TABLE[][5])
 {
-	USHORT data;
-
-	data = DRAMTYPE_TABLE[index][4];
-	SiS_SetReg1 (SiS_P3c4, 0x13, data);
+   USHORT  data;
 
-	/* should delay 50 ns */
+   data = DRAMTYPE_TABLE[index][4];
+   SiS_SetReg1(SiS_P3c4,0x13,data);
 
+   /* should delay 50 ns */
 }
 
 void
-SiS_CheckBusWidth_310 (ULONG ROMAddress, ULONG FBAddress)
+SiS_CheckBusWidth_310(UCHAR *ROMAddress,ULONG FBAddress,
+                      PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT data;
-	PULONG volatile pVideoMemory;
+   USHORT  data;
+   PULONG volatile pVideoMemory;
 
-	pVideoMemory = (PULONG) FBAddress;
-	if (SiS_Get310DRAMType (ROMAddress) < 2) {
+   pVideoMemory = (PULONG) FBAddress;
+   if (SiS_Get310DRAMType(ROMAddress,HwDeviceExtension) < 2) {
 
-		SiS_SetReg1 (SiS_P3c4, 0x13, 0x00);
-		SiS_SetReg1 (SiS_P3c4, 0x14, 0x12);
-		/* should delay */
-		SiS_SDR_MRS ();
+     SiS_SetReg1(SiS_P3c4,0x13,0x00);
+     SiS_SetReg1(SiS_P3c4,0x14,0x12);
+     /* should delay */
+     SiS_SDR_MRS();
 
-		SiS_ChannelAB = 0;
-		SiS_DataBusWidth = 128;
-		pVideoMemory[0] = 0x01234567L;
-		pVideoMemory[1] = 0x456789ABL;
-		pVideoMemory[2] = 0x89ABCDEFL;
-		pVideoMemory[3] = 0xCDEF0123L;
-		pVideoMemory[4] = 0x55555555L;
-		pVideoMemory[5] = 0x55555555L;
-		pVideoMemory[6] = 0xFFFFFFFFL;
-		pVideoMemory[7] = 0xFFFFFFFFL;
-		if ((pVideoMemory[3] != 0xCDEF0123L)
-		    || (pVideoMemory[2] != 0x89ABCDEFL)) {
-			/*ChannelA64Bit */
-			SiS_DataBusWidth = 64;
-			SiS_ChannelAB = 0;
-			data = SiS_GetReg1 (SiS_P3c4, 0x14);
-			SiS_SetReg1 (SiS_P3c4, 0x14, (USHORT) (data & 0xFD));
-		}
+     SiS_ChannelAB = 0;
+     SiS_DataBusWidth = 128;
+     pVideoMemory[0] = 0x01234567L;
+     pVideoMemory[1] = 0x456789ABL;
+     pVideoMemory[2] = 0x89ABCDEFL;
+     pVideoMemory[3] = 0xCDEF0123L;
+     pVideoMemory[4] = 0x55555555L;
+     pVideoMemory[5] = 0x55555555L;
+     pVideoMemory[6] = 0xFFFFFFFFL;
+     pVideoMemory[7] = 0xFFFFFFFFL;
+     if ((pVideoMemory[3]!=0xCDEF0123L) || (pVideoMemory[2] != 0x89ABCDEFL)) {
+       /*ChannelA64Bit */
+       SiS_DataBusWidth = 64;
+       SiS_ChannelAB = 0;
+       data=SiS_GetReg1(SiS_P3c4,0x14);
+       SiS_SetReg1(SiS_P3c4,  0x14, (USHORT) (data & 0xFD));
+     }
 
-		if ((pVideoMemory[1] != 0x456789ABL)
-		    || (pVideoMemory[0] != 0x01234567L)) {
-			/*ChannelB64Bit */
-			SiS_DataBusWidth = 64;
-			SiS_ChannelAB = 1;
-			data = SiS_GetReg1 (SiS_P3c4, 0x14);
-			SiS_SetReg1 (SiS_P3c4, 0x14,
-				     (USHORT) ((data & 0xFD) | 0x01));
-		}
-		return;
+     if ((pVideoMemory[1]!=0x456789ABL) || (pVideoMemory[0] != 0x01234567L)) {
+       /*ChannelB64Bit */
+       SiS_DataBusWidth = 64;
+       SiS_ChannelAB = 1;
+       data=SiS_GetReg1(SiS_P3c4,0x14);
+       SiS_SetReg1(SiS_P3c4,0x14,(USHORT)((data&0xFD)|0x01));
+     }
+     return;
 
-	} else {
-		/* DDR Dual channel */
-		SiS_SetReg1 (SiS_P3c4, 0x13, 0x00);
-		SiS_SetReg1 (SiS_P3c4, 0x14, 0x02);	/* Channel A, 64bit */
-		/* should delay */
-		SiS_DDR_MRS ();
-
-		SiS_ChannelAB = 0;
-		SiS_DataBusWidth = 64;
-		pVideoMemory[0] = 0x01234567L;
-		pVideoMemory[1] = 0x456789ABL;
-		pVideoMemory[2] = 0x89ABCDEFL;
-		pVideoMemory[3] = 0xCDEF0123L;
-		pVideoMemory[4] = 0x55555555L;
-		pVideoMemory[5] = 0x55555555L;
-		pVideoMemory[6] = 0xAAAAAAAAL;
-		pVideoMemory[7] = 0xAAAAAAAAL;
-
-		if (pVideoMemory[1] == 0x456789ABL) {
-			if (pVideoMemory[0] == 0x01234567L) {
-				/* Channel A 64bit */
-				return;
-			}
-		} else {
-			if (pVideoMemory[0] == 0x01234567L) {
-				/* Channel A 32bit */
-				SiS_DataBusWidth = 32;
-				SiS_SetReg1 (SiS_P3c4, 0x14, 0x00);
-				return;
-			}
+   } else {
+     /* DDR Dual channel */
+     SiS_SetReg1(SiS_P3c4,0x13,0x00);
+     SiS_SetReg1(SiS_P3c4,0x14,0x02); /* Channel A, 64bit */
+     /* should delay */
+     SiS_DDR_MRS();
 
-		}
+     SiS_ChannelAB = 0;
+     SiS_DataBusWidth = 64;
+     pVideoMemory[0] = 0x01234567L;
+     pVideoMemory[1] = 0x456789ABL;
+     pVideoMemory[2] = 0x89ABCDEFL;
+     pVideoMemory[3] = 0xCDEF0123L;
+     pVideoMemory[4] = 0x55555555L;
+     pVideoMemory[5] = 0x55555555L;
+     pVideoMemory[6] = 0xAAAAAAAAL;
+     pVideoMemory[7] = 0xAAAAAAAAL;
 
-		SiS_SetReg1 (SiS_P3c4, 0x14, 0x03);	/* Channel B, 64bit */
-		SiS_DDR_MRS ();
-
-		SiS_ChannelAB = 1;
-		SiS_DataBusWidth = 64;
-		pVideoMemory[0] = 0x01234567L;
-		pVideoMemory[1] = 0x456789ABL;
-		pVideoMemory[2] = 0x89ABCDEFL;
-		pVideoMemory[3] = 0xCDEF0123L;
-		pVideoMemory[4] = 0x55555555L;
-		pVideoMemory[5] = 0x55555555L;
-		pVideoMemory[6] = 0xAAAAAAAAL;
-		pVideoMemory[7] = 0xAAAAAAAAL;
-		if (pVideoMemory[1] == 0x456789ABL) {
-			/* Channel B 64 */
-			if (pVideoMemory[0] == 0x01234567L) {
-				/* Channel B 64bit */
-				return;
-			} else {
-				/* error */
-			}
-		} else {
-			if (pVideoMemory[0] == 0x01234567L) {
-				/* Channel B 32 */
-				SiS_DataBusWidth = 32;
-				SiS_SetReg1 (SiS_P3c4, 0x14, 0x01);
-			} else {
-				/* error */
-			}
-		}
-	}
+     if (pVideoMemory[1] == 0x456789ABL) {
+       if (pVideoMemory[0] == 0x01234567L) {
+         /* Channel A 64bit */
+         return;
+       }
+     } else {
+       if (pVideoMemory[0] == 0x01234567L) {
+         /* Channel A 32bit */
+         SiS_DataBusWidth = 32;
+         SiS_SetReg1(SiS_P3c4,0x14,0x00);
+         return;
+       }
+     }
+
+     SiS_SetReg1(SiS_P3c4,0x14,0x03); /* Channel B, 64bit */
+     SiS_DDR_MRS();
+
+     SiS_ChannelAB = 1;
+     SiS_DataBusWidth = 64;
+     pVideoMemory[0] = 0x01234567L;
+     pVideoMemory[1] = 0x456789ABL;
+     pVideoMemory[2] = 0x89ABCDEFL;
+     pVideoMemory[3] = 0xCDEF0123L;
+     pVideoMemory[4] = 0x55555555L;
+     pVideoMemory[5] = 0x55555555L;
+     pVideoMemory[6] = 0xAAAAAAAAL;
+     pVideoMemory[7] = 0xAAAAAAAAL;
+     if (pVideoMemory[1] == 0x456789ABL) {
+       /* Channel B 64 */
+       if (pVideoMemory[0] == 0x01234567L) {
+         /* Channel B 64bit */
+         return;
+       } else {
+         /* error */
+       }
+     } else {
+       if (pVideoMemory[0] == 0x01234567L) {
+         /* Channel B 32 */
+         SiS_DataBusWidth = 32;
+         SiS_SetReg1(SiS_P3c4,0x14,0x01);
+       } else {
+         /* error */
+       }
+     }
+   }
 }
 
 int
-SiS_SetRank (int index, UCHAR RankNo, UCHAR SiS_ChannelAB,
-	     USHORT DRAMTYPE_TABLE[][5])
+SiS_SetRank(int index,UCHAR RankNo,UCHAR SiS_ChannelAB,USHORT DRAMTYPE_TABLE[][5])
 {
-	USHORT data;
-	int RankSize;
+  USHORT  data;
+  int RankSize;
 
-	if ((RankNo == 2) && (DRAMTYPE_TABLE[index][0] == 2))
-		return 0;
-
-	RankSize = DRAMTYPE_TABLE[index][3] / 2 * SiS_DataBusWidth / 32;
-
-	if (RankNo * RankSize <= 128) {
-		data = 0;
-		while ((RankSize >>= 1) > 0) {
-			data += 0x10;
-		}
-		data |= (RankNo - 1) << 2;
-		data |= (SiS_DataBusWidth / 64) & 2;
-		data |= SiS_ChannelAB;
-		SiS_SetReg1 (SiS_P3c4, 0x14, data);
-		/* should delay */
-		SiS_SDR_MRS ();
-		return 1;
-	} else
-		return 0;
+  if ((RankNo==2)&&(DRAMTYPE_TABLE[index][0]==2))
+         return 0;
 
+  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_DataBusWidth/32;
+
+  if (RankNo*RankSize<=128) {
+    data = 0;
+    while ((RankSize>>=1)>0) {
+      data+=0x10;
+    }
+    data |= (RankNo-1)<<2;
+    data |= (SiS_DataBusWidth/64)&2;
+    data |= SiS_ChannelAB;
+    SiS_SetReg1(SiS_P3c4,0x14,data);
+    /* should delay */
+    SiS_SDR_MRS();
+    return 1;
+  } else
+    return 0;
 }
 
 int
-SiS_SetDDRChannel (int index, UCHAR ChannelNo, UCHAR SiS_ChannelAB,
-		   USHORT DRAMTYPE_TABLE[][5])
+SiS_SetDDRChannel(int index,UCHAR ChannelNo,UCHAR SiS_ChannelAB,
+                  USHORT DRAMTYPE_TABLE[][5])
 {
-	USHORT data;
-	int RankSize;
-
-	RankSize = DRAMTYPE_TABLE[index][3] / 2 * SiS_DataBusWidth / 32;
-	/* RankSize = DRAMTYPE_TABLE[index][3]; */
-	if (ChannelNo * RankSize <= 128) {
-		data = 0;
-		while ((RankSize >>= 1) > 0) {
-			data += 0x10;
-		}
-		if (ChannelNo == 2)
-			data |= 0x0C;
-
-		data |= (SiS_DataBusWidth / 32) & 2;
-		data |= SiS_ChannelAB;
-		SiS_SetReg1 (SiS_P3c4, 0x14, data);
-		/* should delay */
-		SiS_DDR_MRS ();
-		return 1;
-	} else
-		return 0;
+  USHORT  data;
+  int RankSize;
 
+  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_DataBusWidth/32;
+  /* RankSize = DRAMTYPE_TABLE[index][3]; */
+  if (ChannelNo*RankSize<=128) {
+    data = 0;
+    while ((RankSize>>=1)>0) {
+      data+=0x10;
+    }
+    if (ChannelNo==2)
+      data |= 0x0C;
+
+    data |= (SiS_DataBusWidth/32)&2;
+    data |= SiS_ChannelAB;
+    SiS_SetReg1(SiS_P3c4,0x14,data);
+    /* should delay */
+    SiS_DDR_MRS();
+    return 1;
+  } else
+    return 0;
 }
 
 int
-SiS_CheckColumn (int index, USHORT DRAMTYPE_TABLE[][5], ULONG FBAddress)
+SiS_CheckColumn(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
-	int i;
-	ULONG Increment, Position;
+  int i;
+  ULONG Increment,Position;
 
-	/*Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_DataBusWidth / 64 + 1); */
-	Increment = 1 << (10 + SiS_DataBusWidth / 64);
+  /*Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_DataBusWidth / 64 + 1); */
+  Increment = 1<<(10 + SiS_DataBusWidth / 64);
 
-	for (i = 0, Position = 0; i < 2; i++) {
-		*((PULONG) (FBAddress + Position)) = Position;
-		Position += Increment;
-	}
+  for (i=0,Position=0;i<2;i++) {
+         *((PULONG)(FBAddress+Position))=Position;
+         Position += Increment;
+  }
 
-	for (i = 0, Position = 0; i < 2; i++) {
+  for (i=0,Position=0;i<2;i++) {
 /*    if (FBAddress[Position]!=Position) */
-		if ((*(PULONG) (FBAddress + Position)) != Position)
-			return 0;
-		Position += Increment;
-	}
-	return 1;
+         if ( (*(PULONG) (FBAddress + Position)) !=Position)
+                return 0;
+         Position += Increment;
+  }
+  return 1;
 }
 
 int
-SiS_CheckBanks (int index, USHORT DRAMTYPE_TABLE[][5], ULONG FBAddress)
+SiS_CheckBanks(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
-	int i;
-	ULONG Increment, Position;
-	Increment = 1 << (DRAMTYPE_TABLE[index][2] + SiS_DataBusWidth / 64 + 2);
+  int i;
+  ULONG Increment,Position;
+  Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_DataBusWidth / 64 + 2);
 
-	for (i = 0, Position = 0; i < 4; i++) {
+  for (i=0,Position=0;i<4;i++) {
 /*    FBAddress[Position]=Position; */
-		*((PULONG) (FBAddress + Position)) = Position;
-		Position += Increment;
-	}
+    *((PULONG)(FBAddress+Position))=Position;
+    Position += Increment;
+  }
 
-	for (i = 0, Position = 0; i < 4; i++) {
+  for (i=0,Position=0;i<4;i++) {
 /*    if (FBAddress[Position]!=Position) */
-		if ((*(PULONG) (FBAddress + Position)) != Position)
-			return 0;
-		Position += Increment;
-	}
-	return 1;
+    if ( (*(PULONG) (FBAddress + Position)) !=Position)
+      return 0;
+    Position += Increment;
+  }
+  return 1;
 }
 
 int
-SiS_CheckRank (int RankNo, int index, USHORT DRAMTYPE_TABLE[][5],
-	       ULONG FBAddress)
+SiS_CheckRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
-	int i;
-	ULONG Increment, Position;
-	Increment = 1 << (DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
-			  DRAMTYPE_TABLE[index][0] + SiS_DataBusWidth / 64 +
-			  RankNo);
+  int i;
+  ULONG Increment,Position;
+  Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
+                  DRAMTYPE_TABLE[index][0] + SiS_DataBusWidth / 64 + RankNo);
 
-	for (i = 0, Position = 0; i < 2; i++) {
+  for (i=0,Position=0;i<2;i++) {
 /*    FBAddress[Position]=Position; */
-		*((PULONG) (FBAddress + Position)) = Position;
-		/* *((PULONG)(FBAddress))=Position; */
-		Position += Increment;
-	}
+    *((PULONG)(FBAddress+Position))=Position;
+    /* *((PULONG)(FBAddress))=Position; */
+    Position += Increment;
+  }
 
-	for (i = 0, Position = 0; i < 2; i++) {
+  for (i=0,Position=0;i<2;i++) {
 /*    if (FBAddress[Position]!=Position) */
-		if ((*(PULONG) (FBAddress + Position)) != Position)
-			/*if ( (*(PULONG) (FBAddress )) !=Position) */
-			return 0;
-		Position += Increment;
-	}
-	return 1;
-
+         if ( (*(PULONG) (FBAddress + Position)) !=Position)
+    /*if ( (*(PULONG) (FBAddress )) !=Position) */
+      return 0;
+    Position += Increment;
+  }
+  return 1;
 }
 
 int
-SiS_CheckDDRRank (int RankNo, int index, USHORT DRAMTYPE_TABLE[][5],
-		  ULONG FBAddress)
+SiS_CheckDDRRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
-	ULONG Increment, Position;
-	USHORT data;
-
-	Increment = 1 << (DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
-			  DRAMTYPE_TABLE[index][0] + SiS_DataBusWidth / 64 +
-			  RankNo);
-
-	Increment += Increment / 2;
-
-	Position = 0;
-	*((PULONG) (FBAddress + Position + 0)) = 0x01234567;
-	*((PULONG) (FBAddress + Position + 1)) = 0x456789AB;
-	*((PULONG) (FBAddress + Position + 2)) = 0x55555555;
-	*((PULONG) (FBAddress + Position + 3)) = 0x55555555;
-	*((PULONG) (FBAddress + Position + 4)) = 0xAAAAAAAA;
-	*((PULONG) (FBAddress + Position + 5)) = 0xAAAAAAAA;
-
-	if ((*(PULONG) (FBAddress + 1)) == 0x456789AB)
-		return 1;
-
-	if ((*(PULONG) (FBAddress + 0)) == 0x01234567)
-		return 0;
-
-	data = SiS_GetReg1 (SiS_P3c4, 0x14);
-	data &= 0xF3;
-	data |= 0x08;
-	SiS_SetReg1 (SiS_P3c4, 0x14, data);
-	data = SiS_GetReg1 (SiS_P3c4, 0x15);
-	data += 0x20;
-	SiS_SetReg1 (SiS_P3c4, 0x15, data);
-
-	return 1;
+  ULONG Increment,Position;
+  USHORT  data;
+  
+  Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
+                  DRAMTYPE_TABLE[index][0] + SiS_DataBusWidth / 64 + RankNo);
+
+  Increment += Increment/2;
+  
+  Position =0;
+  *((PULONG)(FBAddress+Position+0))=0x01234567;
+  *((PULONG)(FBAddress+Position+1))=0x456789AB;
+  *((PULONG)(FBAddress+Position+2))=0x55555555;
+  *((PULONG)(FBAddress+Position+3))=0x55555555;
+  *((PULONG)(FBAddress+Position+4))=0xAAAAAAAA;
+  *((PULONG)(FBAddress+Position+5))=0xAAAAAAAA;
+
+  if ( (*(PULONG) (FBAddress + 1))==0x456789AB)
+    return 1;
+
+  if ( (*(PULONG) (FBAddress + 0))==0x01234567)
+    return 0;
+
+  data=SiS_GetReg1(SiS_P3c4,0x14);
+  data &= 0xF3;
+  data |= 0x08;
+  SiS_SetReg1(SiS_P3c4,0x14,data);
+  data=SiS_GetReg1(SiS_P3c4,0x15);
+  data += 0x20;
+  SiS_SetReg1(SiS_P3c4,0x15,data);
 
+  return 1;
 }
 
 int
-SiS_CheckRanks (int RankNo, int index, USHORT DRAMTYPE_TABLE[][5],
-		ULONG FBAddress)
+SiS_CheckRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
-	int r;
+  int r;
 
-	for (r = RankNo; r >= 1; r--) {
-		if (!SiS_CheckRank (r, index, DRAMTYPE_TABLE, FBAddress))
-			return 0;
-	}
-	if (!SiS_CheckBanks (index, DRAMTYPE_TABLE, FBAddress))
-		return 0;
+  for (r=RankNo;r>=1;r--) {
+    if (!SiS_CheckRank(r,index,DRAMTYPE_TABLE,FBAddress))
+      return 0;
+  }
+  if (!SiS_CheckBanks(index,DRAMTYPE_TABLE,FBAddress))
+    return 0;
 
-	if (!SiS_CheckColumn (index, DRAMTYPE_TABLE, FBAddress))
-		return 0;
-	return 1;
+  if (!SiS_CheckColumn(index,DRAMTYPE_TABLE,FBAddress))
+    return 0;
 
+  return 1;
 }
 
 int
-SiS_CheckDDRRanks (int RankNo, int index, USHORT DRAMTYPE_TABLE[][5],
-		   ULONG FBAddress)
+SiS_CheckDDRRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
-	int r;
+  int r;
 
-	for (r = RankNo; r >= 1; r--) {
-		if (!SiS_CheckDDRRank (r, index, DRAMTYPE_TABLE, FBAddress))
-			return 0;
-	}
-	if (!SiS_CheckBanks (index, DRAMTYPE_TABLE, FBAddress))
-		return 0;
+  for (r=RankNo;r>=1;r--) {
+    if (!SiS_CheckDDRRank(r,index,DRAMTYPE_TABLE,FBAddress))
+      return 0;
+  }
+  if (!SiS_CheckBanks(index,DRAMTYPE_TABLE,FBAddress))
+    return 0;
 
-	if (!SiS_CheckColumn (index, DRAMTYPE_TABLE, FBAddress))
-		return 0;
-	return 1;
+  if (!SiS_CheckColumn(index,DRAMTYPE_TABLE,FBAddress))
+    return 0;
 
+  return 1;
 }
 
 int
-SiS_SDRSizing (ULONG FBAddress)
+SiS_SDRSizing(ULONG FBAddress)
 {
-	int i;
-	UCHAR j;
+  int    i;
+  UCHAR  j;
 
-	for (i = 0; i < 13; i++) {
-		SiS_SetDRAMSizingType (i, SiS_SDRDRAM_TYPE);
-		for (j = 2; j > 0; j--) {
-
-			if (!SiS_SetRank
-			    (i, (UCHAR) j, SiS_ChannelAB,
-			     SiS_SDRDRAM_TYPE)) continue;
-			else {
-				if (SiS_CheckRanks
-				    (j, i, SiS_SDRDRAM_TYPE,
-				     FBAddress)) return 1;
-			}
-		}
-	}
-	return 0;
+  for (i=0;i<13;i++) {
+    SiS_SetDRAMSizingType(i, SiS_SDRDRAM_TYPE);
+    for (j=2;j>0;j--) {
+      if (!SiS_SetRank(i,(UCHAR) j, SiS_ChannelAB,SiS_SDRDRAM_TYPE))
+        continue;
+      else {
+        if (SiS_CheckRanks(j,i,SiS_SDRDRAM_TYPE, FBAddress))
+          return 1;
+      }
+    }
+  }
+  return 0;
 }
 
 int
-SiS_DDRSizing (ULONG FBAddress)
+SiS_DDRSizing(ULONG FBAddress)
 {
 
-	int i;
-	UCHAR j;
+  int    i;
+  UCHAR  j;
 
-	for (i = 0; i < 4; i++) {
-		SiS_SetDRAMSizingType (i, SiS_DDRDRAM_TYPE);
-		SiS_DisableChannelInterleaving (i, SiS_DDRDRAM_TYPE);
-		for (j = 2; j > 0; j--) {
-			SiS_SetDDRChannel (i, j, SiS_ChannelAB,
-					   SiS_DDRDRAM_TYPE);
-			if (!SiS_SetRank
-			    (i, (UCHAR) j, SiS_ChannelAB,
-			     SiS_DDRDRAM_TYPE)) continue;
-			else {
-				if (SiS_CheckDDRRanks
-				    (j, i, SiS_DDRDRAM_TYPE,
-				     FBAddress)) return 1;
-			}
-		}
-	}
-	return 0;
+  for (i=0;i<4;i++){
+    SiS_SetDRAMSizingType(i,SiS_DDRDRAM_TYPE);
+    SiS_DisableChannelInterleaving(i,SiS_DDRDRAM_TYPE);
+    for (j=2;j>0;j--) {
+      SiS_SetDDRChannel(i, j, SiS_ChannelAB, SiS_DDRDRAM_TYPE);
+      if (!SiS_SetRank(i,(UCHAR) j, SiS_ChannelAB,SiS_DDRDRAM_TYPE))
+        continue;
+      else {
+        if (SiS_CheckDDRRanks(j,i,SiS_DDRDRAM_TYPE, FBAddress))
+          return 1;
+      }
+    }
+  }
+  return 0;
 }
 
 /*
-
  check if read cache pointer is correct
-
 */
 void
-SiS_VerifyMclk (ULONG FBAddr)
+SiS_VerifyMclk(ULONG FBAddr)
 {
-	PUCHAR pVideoMemory = (PUCHAR) FBAddr;
-	UCHAR i, j;
-	USHORT Temp, SR21;
-
-	pVideoMemory[0] = 0xaa;	/* alan */
-	pVideoMemory[16] = 0x55;	/* note: PCI read cache is off */
-
-	if ((pVideoMemory[0] != 0xaa) || (pVideoMemory[16] != 0x55)) {
-		for (i = 0, j = 16; i < 2; i++, j += 16) {
-			SR21 = SiS_GetReg1 (SiS_P3c4, 0x21);
-			Temp = SR21 & 0xFB;	/* disable PCI post write buffer empty gating */
-			SiS_SetReg1 (SiS_P3c4, 0x21, Temp);
-
-			Temp = SiS_GetReg1 (SiS_P3c4, 0x3C);
-			Temp = Temp | 0x01;	/*MCLK reset */
-			SiS_SetReg1 (SiS_P3c4, 0x3C, Temp);
-			Temp = SiS_GetReg1 (SiS_P3c4, 0x3C);
-			Temp = Temp & 0xFE;	/* MCLK normal operation */
-			SiS_SetReg1 (SiS_P3c4, 0x3C, Temp);
-			SiS_SetReg1 (SiS_P3c4, 0x21, SR21);
-
-			pVideoMemory[16 + j] = j;
-			if (pVideoMemory[16 + j] == j) {
-				pVideoMemory[j] = j;
-				break;
-			}
-		}
-	}
-
+   PUCHAR  pVideoMemory = (PUCHAR) FBAddr;
+   UCHAR i,j;
+   USHORT Temp,SR21;
+
+   pVideoMemory[0]=0xaa;  /* alan */
+   pVideoMemory[16]=0x55; /* note: PCI read cache is off */
+
+   if ((pVideoMemory[0]!=0xaa)||(pVideoMemory[16]!=0x55)) {
+     for (i=0,j=16;i<2;i++,j+=16)  {
+       SR21 = SiS_GetReg1(SiS_P3c4, 0x21);
+       Temp = SR21 & 0xFB;     /* disable PCI post write buffer empty gating */
+       SiS_SetReg1(SiS_P3c4, 0x21, Temp);
+
+       Temp = SiS_GetReg1(SiS_P3c4, 0x3C);
+       Temp = Temp | 0x01;                 /*MCLK reset */
+       SiS_SetReg1(SiS_P3c4, 0x3C, Temp);
+       Temp = SiS_GetReg1(SiS_P3c4, 0x3C);
+       Temp = Temp & 0xFE;                 /* MCLK normal operation */
+       SiS_SetReg1(SiS_P3c4, 0x3C, Temp);
+       SiS_SetReg1(SiS_P3c4, 0x21, SR21);
+
+       pVideoMemory[16+j] = j;
+       if (pVideoMemory[16+j]==j)  {
+         pVideoMemory[j] = j;
+         break;
+       }
+     }
+   }
 }
 
+/* TW: Is this a 315E? */
 int
-Is315E (void)
+Is315E(void)
 {
-	USHORT data;
+   USHORT  data;
 
-	data = SiS_GetReg1 (SiS_P3d4, 0x5F);
-	if (data & 0x10)
-		return 1;
-	else
-		return 0;
+   data=SiS_GetReg1(SiS_P3d4,0x5F);
+   if (data&0x10) return 1;
+   else return 0;
 }
 
+/* TW: For 315 only */
 void
-SiS_SetDRAMSize_310 (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetDRAMSize_310(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	ULONG ROMAddr = (ULONG) HwDeviceExtension->pjVirtualRomBase;
-	ULONG FBAddr = (ULONG) HwDeviceExtension->pjVideoMemoryAddress;
-	/*USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; */
-	USHORT data;
+   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
+   ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
+   USHORT  data;
 
-#ifdef SIS301
-	/*SiS_SetReg1(SiS_P3d4,0x30,0x40);   */
+#ifdef SIS301	/* TW: SIS301 ??? */
+   /*SiS_SetReg1(SiS_P3d4,0x30,0x40);   */
 #endif
-#ifdef SIS302
-	SiS_SetReg1 (SiS_P3d4, 0x30, 0x4D);	/* alan,should change value */
-	SiS_SetReg1 (SiS_P3d4, 0x31, 0xc0);	/* alan,should change value */
-	SiS_SetReg1 (SiS_P3d4, 0x34, 0x3F);	/* alan,should change value */
+#ifdef SIS302   /* TW: SIS302 ??? */
+   SiS_SetReg1(SiS_P3d4,0x30,0x4D);  /* alan,should change value */
+   SiS_SetReg1(SiS_P3d4,0x31,0xc0);  /* alan,should change value */
+   SiS_SetReg1(SiS_P3d4,0x34,0x3F);  /* alan,should change value */
 #endif
 
-	SiSSetMode (HwDeviceExtension, 0x2e);
+   SiSSetMode(HwDeviceExtension,0x2e);
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x21);
-	SiS_SetReg1 (SiS_P3c4, 0x21, (USHORT) (data & 0xDF));	/* disable read cache */
+   data=SiS_GetReg1(SiS_P3c4,0x21);
+   SiS_SetReg1(SiS_P3c4,0x21,(USHORT) (data&0xDF));   /* disable read cache */
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x1);
-	data = data | 0x20;
-	SiS_SetReg1 (SiS_P3c4, 0x01, data);	/* Turn OFF Display */
+   data=SiS_GetReg1(SiS_P3c4,0x1);
+   data=data|0x20;
+   SiS_SetReg1(SiS_P3c4,0x01,data);                   /* Turn OFF Display */
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x16);
-	SiS_SetReg1 (SiS_P3c4, 0x16, (USHORT) (data | 0x0F));	/* assume lowest speed DRAM */
+   data=SiS_GetReg1(SiS_P3c4,0x16);
+   SiS_SetReg1(SiS_P3c4,0x16,(USHORT) (data|0x0F));   /* assume lowest speed DRAM */
 
-	SiS_SetDRAMModeRegister (ROMAddr);
-	SiS_DisableRefresh ();
-	SiS_CheckBusWidth_310 (ROMAddr, FBAddr);
+   SiS_SetDRAMModeRegister(ROMAddr,HwDeviceExtension);
+   SiS_DisableRefresh();
+   SiS_CheckBusWidth_310(ROMAddr,FBAddr,HwDeviceExtension);
 
-	SiS_VerifyMclk (FBAddr);	/* alan 2000/7/3 */
+   SiS_VerifyMclk(FBAddr); /* alan 2000/7/3 */
 
-	if (SiS_Get310DRAMType (ROMAddr) < 2) {
-		SiS_SDRSizing (FBAddr);
-	} else {
-		SiS_DDRSizing (FBAddr);
-	}
+   if (SiS_Get310DRAMType(ROMAddr, HwDeviceExtension)<2)
+     SiS_SDRSizing(FBAddr);
+   else
+     SiS_DDRSizing(FBAddr);
 
-	if (Is315E ()) {
-		data = SiS_GetReg1 (SiS_P3c4, 0x14);
-		if ((data & 0x0C) == 0x0C) {	/* dual channel */
-			if ((data & 0xF0) > 0x40)
-				data = (data & 0x0F) | 0x40;
-		} else {	/* single channel */
+   if (Is315E()) {
+     data=SiS_GetReg1(SiS_P3c4,0x14);
+     if ((data&0x0C)==0x0C) { 	/* dual channel */
+     	if ((data&0xF0)>0x40)
+     	  data = (data & 0x0F) | 0x40;
+     } else { 			/* single channel */
+     	if ((data&0xF0)>0x50)
+     	  data = (data & 0x0F) | 0x50;
+     }
+   }
 
-			if ((data & 0xF0) > 0x50)
-				data = (data & 0x0F) | 0x50;
-		}
-
-	}
-
-	SiS_SetReg1 (SiS_P3c4, 0x16, SiS_SR15[1][SiS_RAMType]);	/* restore SR16 */
-
-	SiS_EnableRefresh (ROMAddr);
-	data = SiS_GetReg1 (SiS_P3c4, 0x21);
-	SiS_SetReg1 (SiS_P3c4, 0x21, (USHORT) (data | 0x20));	/* enable read cache */
+   SiS_SetReg1(SiS_P3c4,0x16,SiS_SR15[1][SiS_RAMType]);  /* restore SR16 */
 
+   SiS_EnableRefresh(ROMAddr);
+   data=SiS_GetReg1(SiS_P3c4,0x21);
+   SiS_SetReg1(SiS_P3c4,0x21,(USHORT) (data|0x20));      /* enable read cache */
 }
 #endif
 
 void
-SiS_SetMemoryClock (ULONG ROMAddr)
+SiS_SetMemoryClock(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	SiS_SetReg1 (SiS_P3c4, 0x28, SiS_MCLKData[SiS_RAMType].SR28);
-	SiS_SetReg1 (SiS_P3c4, 0x29, SiS_MCLKData[SiS_RAMType].SR29);
-	SiS_SetReg1 (SiS_P3c4, 0x2A, SiS_MCLKData[SiS_RAMType].SR2A);
-	SiS_SetReg1 (SiS_P3c4, 0x2E, SiS_ECLKData[SiS_RAMType].SR2E);
-	SiS_SetReg1 (SiS_P3c4, 0x2F, SiS_ECLKData[SiS_RAMType].SR2F);
-	SiS_SetReg1 (SiS_P3c4, 0x30, SiS_ECLKData[SiS_RAMType].SR30);
+   SiS_SetReg1(SiS_P3c4,0x28,SiS_MCLKData_0[SiS_RAMType].SR28);
+   SiS_SetReg1(SiS_P3c4,0x29,SiS_MCLKData_0[SiS_RAMType].SR29);
+   SiS_SetReg1(SiS_P3c4,0x2A,SiS_MCLKData_0[SiS_RAMType].SR2A);
+   SiS_SetReg1(SiS_P3c4,0x2E,SiS_ECLKData[SiS_RAMType].SR2E);
+   SiS_SetReg1(SiS_P3c4,0x2F,SiS_ECLKData[SiS_RAMType].SR2F);
+   SiS_SetReg1(SiS_P3c4,0x30,SiS_ECLKData[SiS_RAMType].SR30);
 
-#ifdef CONFIG_FB_SIS_315
-	if (Is315E ()) {
-		SiS_SetReg1 (SiS_P3c4, 0x28, 0x3B);	/* 143 */
-		SiS_SetReg1 (SiS_P3c4, 0x29, 0x22);
-		SiS_SetReg1 (SiS_P3c4, 0x2E, 0x3B);	/* 143 */
-		SiS_SetReg1 (SiS_P3c4, 0x2F, 0x22);
-	}
+#ifdef SIS315H
+   if (Is315E()) {
+     SiS_SetReg1(SiS_P3c4,0x28,0x3B); /* 143 */
+     SiS_SetReg1(SiS_P3c4,0x29,0x22);
+     SiS_SetReg1(SiS_P3c4,0x2E,0x3B); /* 143 */
+     SiS_SetReg1(SiS_P3c4,0x2F,0x22);
+   }
 #endif
+}
+
+#endif /* ifndef LINUX_XF86 */
+
+#ifdef SIS315H
+UCHAR
+SiS_Get310DRAMType(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   UCHAR   data;
 
+   if (*pSiS_SoftSetting & SoftDRAMType) {
+     data = *pSiS_SoftSetting & 0x03;
+   } else {
+     if(HwDeviceExtension->jChipType > SIS_315PRO) {
+        data = SiS_GetReg1(SiS_P3c4,0x13) & 0x07;
+     } else {	/* TW: 315 */
+        data = SiS_GetReg1(SiS_P3c4,0x3a) & 0x03;
+     }
+   }
+
+   return data;
+}
+#endif
+
+/* SiSInit END */
+
+/* ----------------------------------------- */
+
+void SiSRegInit(USHORT BaseAddr)
+{
+   SiS_P3c4=BaseAddr+0x14;
+   SiS_P3d4=BaseAddr+0x24;
+   SiS_P3c0=BaseAddr+0x10;
+   SiS_P3ce=BaseAddr+0x1e;
+   SiS_P3c2=BaseAddr+0x12;
+   SiS_P3ca=BaseAddr+0x1a;
+   SiS_P3c6=BaseAddr+0x16;
+   SiS_P3c7=BaseAddr+0x17;
+   SiS_P3c8=BaseAddr+0x18;
+   SiS_P3c9=BaseAddr+0x19;
+   SiS_P3da=BaseAddr+0x2A;
+   SiS_Part1Port=BaseAddr+SIS_CRT2_PORT_04;   /* Digital video interface registers (LCD) */
+   SiS_Part2Port=BaseAddr+SIS_CRT2_PORT_10;   /* 301 TV Encoder registers */
+   SiS_Part3Port=BaseAddr+SIS_CRT2_PORT_12;   /* 301 Macrovision registers */
+   SiS_Part4Port=BaseAddr+SIS_CRT2_PORT_14;   /* 301 VGA2 registers */
+   SiS_Part5Port=BaseAddr+SIS_CRT2_PORT_14+2; /* 301 palette address port registers */
+   SiS_DDC_Port=BaseAddr+0x14;  /* 0x3c4; */  /* DDC Port ( = P3C4) */
+}
+
+void
+SiSInitPCIetc(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+#ifdef LINUX_XF86
+   if ((HwDeviceExtension->jChipType == SIS_540)||
+       (HwDeviceExtension->jChipType == SIS_630)||
+       (HwDeviceExtension->jChipType == SIS_730)||
+       (HwDeviceExtension->jChipType == SIS_300)) {
+       /* TW: Set - PCI LINEAR ADDRESSING ENABLE (0x80)
+		  - PCI IO ENABLE  (0x20)
+		  - MMIO ENABLE (0x1)
+  	*/
+       SiS_SetReg1(SiS_P3c4,0x20,0xa1);
+       /* TW: Enable 2D (0x42) & 3D accelerator (0x18) */
+       SiS_SetRegANDOR(SiS_P3c4,0x1E,0xFF,0x5A);
+   }
+   if((HwDeviceExtension->jChipType == SIS_315H)||
+      (HwDeviceExtension->jChipType == SIS_315PRO)||
+      (HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650)) {
+      /* TW: This seems to be done the same way on these chipsets */
+      SiS_SetReg1(SiS_P3c4,0x20,0xa1);
+      SiS_SetRegANDOR(SiS_P3c4,0x1E,0xFF,0x5A);
+   }
+#endif
+}
+
+void
+SiSSetLVDSetc(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+{
+   ULONG   temp;
+
+   SiS_IF_DEF_LVDS = 0;
+   SiS_IF_DEF_TRUMPION = 0;
+   SiS_IF_DEF_CH70xx = 0;
+   SiS_IF_DEF_HiVision = 0;
+   SiS_IF_DEF_DSTN = 0;
+   SiS_IF_DEF_FSTN = 0;
+
+   SiS_ChrontelInit = 0;
+
+   if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
+   	SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
+   	SiS_IF_DEF_FSTN = 1;   /* for fstn */
+   }
+
+#ifdef SIS300
+   if((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730))
+    {
+      	temp=SiS_GetReg1(SiS_P3d4,0x37);
+      	temp = (temp & 0x0E) >> 1;
+      	if((temp >= 2) && (temp <= 5)) SiS_IF_DEF_LVDS = 1;
+      	if(temp == 3)   SiS_IF_DEF_TRUMPION = 1;
+      	if((temp == 4) || (temp == 5)) {
+		/* TW: Save power status (and error check) */
+		SiS_Backup70xx = SiS_GetCH700x(0x0e);
+		if (SiS_Backup70xx != 0xFFFF)
+			SiS_IF_DEF_CH70xx = 1;
+        }
+   }
+#endif
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650))
+    {
+        /* TW: CR37 is different on 310 series */
+        if (SiS_IF_DEF_FSTN)                       /* fstn: set CR37=0x04 */
+             SiS_SetReg1(SiS_P3d4,0x37,0x04);      /* (fake LVDS bridge) */
+
+	temp=SiS_GetReg1(SiS_P3d4,0x37);
+      	temp = (temp & 0x0E) >> 1;
+      	if((temp >= 2) && (temp <= 3)) SiS_IF_DEF_LVDS = 1;
+      	if(temp == 3)  {
+#if 0  /* Don't know how to do this on Chrontel 7019 */
+		/* TW: Save power status (and error check) */
+		SiS_Backup70xx = SiS_GetCH700x(0x0e);
+		if (SiS_Backup70xx != 0xFFFF)
+#endif
+			SiS_IF_DEF_CH70xx = 2;
+        }
+	SiS_IF_DEF_HiVision = 1;
+    }
+#endif
+}
+
+void
+SiSInitPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_315H)||
+      (HwDeviceExtension->jChipType == SIS_315PRO)||
+      (HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650))
+     InitTo310Pointer(HwDeviceExtension);
+#endif
+
+#ifdef SIS300
+   if ((HwDeviceExtension->jChipType == SIS_540)||
+       (HwDeviceExtension->jChipType == SIS_630)||
+       (HwDeviceExtension->jChipType == SIS_730)||
+       (HwDeviceExtension->jChipType == SIS_300))
+     InitTo300Pointer(HwDeviceExtension);
+#endif
 }
 
 /*
-=========================================
- ======== SiS SetMode Function  ==========
-=========================================
+ 	=========================================
+ 	======== SiS SetMode Function  ==========
+ 	=========================================
 */
+#ifdef LINUX_XF86
+/* TW: This is used for non-Dual-Head mode from X */
 BOOLEAN
-SiSSetMode (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo)
+SiSBIOSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+               DisplayModePtr mode)
 {
-	ULONG temp;
-	USHORT ModeIdIndex, KeepLockReg;
-	ULONG ROMAddr = (ULONG) HwDeviceExtension->pjVirtualRomBase;
-	/*ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress; */
-	USHORT BaseAddr = (USHORT) HwDeviceExtension->ulIOAddress;
-
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||	/* 05/02/01 ynlai for sis550 */
-	    (HwDeviceExtension->jChipType == SIS_315PRO) ||
-	    (HwDeviceExtension->jChipType == SIS_550) ||
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740))	/* 09/03/01 chiawen for 650 */
-		InitTo310Pointer ();
-#endif
-
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730) ||
-	    (HwDeviceExtension->jChipType == SIS_300))
-		InitTo300Pointer ();
-#endif
-
-	SiS_P3c4 = BaseAddr + 0x14;
-	SiS_P3d4 = BaseAddr + 0x24;
-	SiS_P3c0 = BaseAddr + 0x10;
-	SiS_P3ce = BaseAddr + 0x1e;
-	SiS_P3c2 = BaseAddr + 0x12;
-	SiS_P3ca = BaseAddr + 0x1a;
-	SiS_P3c6 = BaseAddr + 0x16;
-	SiS_P3c7 = BaseAddr + 0x17;
-	SiS_P3c8 = BaseAddr + 0x18;
-	SiS_P3c9 = BaseAddr + 0x19;
-	SiS_P3da = BaseAddr + 0x2A;
-	SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
-	SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
-	SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
-	SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
-
-	SiS_IF_DEF_LVDS = 0;
-	SiS_IF_DEF_CH7005 = 0;
-	SiS_IF_DEF_HiVision = 0;
-	SiS_IF_DEF_DSTN = 0;	/*for 550 dstn */
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730) ||
-	    (HwDeviceExtension->jChipType == SIS_550) ||
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740)) {	/* 09/03/01 chiawen for 650 */
-		temp = SiS_GetReg1 (SiS_P3d4, 0x37);
-		temp = (temp & 0x0E) >> 1;
-		if ((temp == 0) || (temp == 1)) {	/* for 301 */
-			SiS_IF_DEF_LVDS = 0;
-			SiS_IF_DEF_CH7005 = 0;
-			SiS_IF_DEF_TRUMPION = 0;
-		}
-		if ((temp >= 2) && (temp <= 5)) {
-			SiS_IF_DEF_LVDS = 1;
-		}
-		if (temp == 3)
-			SiS_IF_DEF_TRUMPION = 1;
-		if ((temp == 4) || (temp == 5))
-			SiS_IF_DEF_CH7005 = 1;
-	} else {
-		SiS_IF_DEF_LVDS = 0;
-		SiS_IF_DEF_TRUMPION = 0;
-		SiS_IF_DEF_CH7005 = 0;
-	}
+   UShort  ModeNo=0;
 
-	if (ModeNo & 0x80) {
-		ModeNo = ModeNo & 0x7F;
-		flag_clearbuffer = 0;
-	} else {
-		flag_clearbuffer = 1;
-	}
+   ModeNo = SiS_CalcModeIndex(pScrn, mode);
+   if (!ModeNo) return FALSE;
 
-	SiS_PresetScratchregister (SiS_P3d4, HwDeviceExtension);	/*add for CRT2  */
-	KeepLockReg = SiS_GetReg1 (SiS_P3c4, 0x05);
-	SiS_SetReg1 (SiS_P3c4, 0x05, 0x86);	/* 1.Openkey */
-	temp = SiS_SearchModeID (ROMAddr, ModeNo, &ModeIdIndex);	/* 2.Get ModeID Table  */
-	if (temp == 0)
-		return (0);
-	/*301b */
-	SiS_GetVBType (BaseAddr);
-	/*end 301b */
-	SiS_GetVBInfo301 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex, HwDeviceExtension);	/*add for CRT2 */
-	SiS_GetLCDResInfo301 (ROMAddr, SiS_P3d4, ModeNo, ModeIdIndex);	/*add for CRT2 */
-
-	temp = SiS_CheckMemorySize (ROMAddr, HwDeviceExtension, ModeNo, ModeIdIndex);	/*3.Check memory size */
-	if (temp == 0)
-		return (0);
-	if (SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {	/*301b */
-		SiS_SetCRT1Group (ROMAddr, HwDeviceExtension, ModeNo,
-				  ModeIdIndex);
-	} else {
-		if (!(SiS_VBInfo & SwitchToCRT2)) {
-			SiS_SetCRT1Group (ROMAddr, HwDeviceExtension, ModeNo,
-					  ModeIdIndex);
-		}
-	}
+   xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Setting mode 0x%x\n", ModeNo);
 
-	if (SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {	/*301b */
-		switch (HwDeviceExtension->ujVBChipID) {
-/*karl*/
-		case VB_CHIP_301:
-		case VB_CHIP_301B:
-			SiS_SetCRT2Group301 (BaseAddr, ROMAddr, ModeNo, HwDeviceExtension);	/*add for CRT2 */
-			break;
-		case VB_CHIP_302:
-			SiS_SetCRT2Group301 (BaseAddr, ROMAddr, ModeNo,
-					     HwDeviceExtension);
-			break;
-		case VB_CHIP_303:
-/*        SetCRT2Group302(BaseAddr,ROMAddr,ModeNo, HwDeviceExtension);                       add for CRT2   */
-			break;
-		case VB_CHIP_UNKNOWN:	/*add for lvds ch7005 */
-			temp = SiS_GetReg1 (SiS_P3d4, 0x37);
-			if (temp &
-			    (ExtChipLVDS | ExtChipTrumpion | ExtChipCH7005)) {
-				SiS_SetCRT2Group301 (BaseAddr, ROMAddr, ModeNo,
-						     HwDeviceExtension);
-			}
-			break;
-		}
-	}
-	if (KeepLockReg == 0xA1)
-		SiS_SetReg1 (SiS_P3c4, 0x05, 0x86);	/* 05/02/01 ynlai */
-	else
-		SiS_SetReg1 (SiS_P3c4, 0x05, 0x00);
-	return TRUE;
+   return(SiSSetMode(HwDeviceExtension, pScrn, ModeNo));
 }
 
-void
-SiS_SetCRT1Group (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		  USHORT ModeNo, USHORT ModeIdIndex)
-{
-	USHORT StandTableIndex, RefreshRateTableIndex;
-	USHORT temp;
-
-	/*SiS_SetReg1(SiS_P3d4,0x34,ModeNo); */
-	SiS_CRT1Mode = ModeNo;
-	/* set CR34->CRT1 ModeNofor CRT2 FIFO */
-	StandTableIndex = SiS_GetModePtr (ROMAddr, ModeNo, ModeIdIndex);	/* 4.GetModePtr  */
-	SiS_SetSeqRegs (ROMAddr, StandTableIndex);	/* 5.SetSeqRegs  */
-	SiS_SetMiscRegs (ROMAddr, StandTableIndex);	/* 6.SetMiscRegs */
-	SiS_SetCRTCRegs (ROMAddr, HwDeviceExtension, StandTableIndex);	/* 7.SetCRTCRegs */
-	SiS_SetATTRegs (ROMAddr, StandTableIndex);	/* 8.SetATTRegs  */
-	SiS_SetGRCRegs (ROMAddr, StandTableIndex);	/* 9.SetGRCRegs  */
-	SiS_ClearExt1Regs ();	/* 10.Clear Ext1Regs */
-	temp = ~ProgrammingCRT2;	/*       11.GetRatePtr  */
-	SiS_SetFlag = SiS_SetFlag & temp;
-	SiS_SelectCRT2Rate = 0;
-	/*301b */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		if (SiS_VBInfo & SetCRT2ToLCDA) {
-			SiS_SetFlag = SiS_SetFlag | ProgrammingCRT2;
-			/*   SiS_SelectCRT2Rate=4; */
-		}
-	}
-	/*end 301b */
+#ifdef SISDUALHEAD
+/* TW: Set CRT1 mode (used for dual head) */
+BOOLEAN
+SiSBIOSSetModeCRT1(PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+               DisplayModePtr mode)
+{
+   ULONG   temp;
+   USHORT  ModeIdIndex;
+#ifndef LINUX_XF86
+   USHORT  KeepLockReg;
+#endif
+   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
+   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+   SISPtr  pSiS = SISPTR(pScrn);
+   SISEntPtr pSiSEnt = pSiS->entityPrivate;
 
-	RefreshRateTableIndex = SiS_GetRatePtrCRT2 (ROMAddr, ModeNo, ModeIdIndex);	/* 11.GetRatePtr */
+   UShort  ModeNo=0;
 
-	/*301b */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		if (!(SiS_VBInfo & SetCRT2ToLCDA)) {
-			SiS_SetFlag = SiS_SetFlag & (~ProgrammingCRT2);
-		}
-	}
-	/*end 301b */
+   ModeNo = SiS_CalcModeIndex(pScrn, mode);
+   if (!ModeNo) return FALSE;
 
-	if (RefreshRateTableIndex != 0xFFFF) {
-		SiS_SetSync (ROMAddr, RefreshRateTableIndex);	/* 12.SetSync */
-		SiS_SetCRT1CRTC (ROMAddr, ModeNo, ModeIdIndex, RefreshRateTableIndex);	/* 13.SetCRT1CRTC  */
-		SiS_SetCRT1Offset (ROMAddr, ModeNo, ModeIdIndex,
-				   RefreshRateTableIndex, HwDeviceExtension);	/* 14.SetCRT1Offset */
-		SiS_SetCRT1VCLK (ROMAddr, ModeNo, ModeIdIndex,
-				 HwDeviceExtension, RefreshRateTableIndex);	/* 15.SetCRT1VCLK  */
-	}
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_540)) {
-		SiS_SetCRT1FIFO2 (ROMAddr, ModeNo, HwDeviceExtension,
-				  RefreshRateTableIndex);
-	}
-#endif
-#ifdef CONFIG_FB_SIS_315
-	if (HwDeviceExtension->jChipType >= SIS_315H) {
-		SiS_SetCRT1FIFO (ROMAddr, ModeNo, HwDeviceExtension);
-	}
-#endif
-	SiS_SetCRT1ModeRegs (ROMAddr, HwDeviceExtension, ModeNo, ModeIdIndex,
-			     RefreshRateTableIndex);
-	SiS_SetVCLKState (ROMAddr, HwDeviceExtension, ModeNo,
-			  RefreshRateTableIndex);
-#ifdef CONFIG_FB_SIS_315
-	if (HwDeviceExtension->jChipType > SIS_315H)
-		SiS_SetInterlace (ROMAddr, ModeNo, RefreshRateTableIndex);
-#endif
-	SiS_LoadDAC (ROMAddr, ModeNo, ModeIdIndex);
-	if (flag_clearbuffer)
-		SiS_ClearBuffer (HwDeviceExtension, ModeNo);
-
-	if (!(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA))) {	/*301b */
-		SiS_LongWait ();
-		SiS_DisplayOn ();
-	}
-}
+   xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Setting mode 0x%x on CRT1\n", ModeNo);
 
-void
-SiS_GetVBType (USHORT BaseAddr)
-{
-	USHORT flag;
+   SiSInitPtr(HwDeviceExtension);
 
-	flag = SiS_GetReg1 (SiS_Part4Port, 0x00);
-	if (flag >= 2)
-		SiS_VBType = VB_SIS302B;
-	else {
-		flag = SiS_GetReg1 (SiS_Part4Port, 0x01);
-		if (flag >= 0xB0)
-			SiS_VBType = VB_SIS301B;
-		else
-			SiS_VBType = VB_SIS301;
-
-		flag = SiS_GetReg1 (SiS_Part4Port, 0x23);	/*301dlvds */
-		if (!(flag & 0x02))
-			SiS_VBType = SiS_VBType | VB_NoLCD;
-	}
+   SiSRegInit(BaseAddr);
+
+   SiSInitPCIetc(HwDeviceExtension);
+
+   SiSSetLVDSetc(HwDeviceExtension, ModeNo);
+
+   /* TW: We don't clear the buffer under X */
+   flag_clearbuffer=0;
+
+   SiS_SetReg1(SiS_P3c4,0x05,0x86);                             		/* 1.Openkey */
+
+   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+
+   temp = SiS_SearchModeID(ROMAddr,&ModeNo,&ModeIdIndex);        		/* 2.Get ModeID Table  */
+   if(temp==0)  return(0);
+
+   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+   SiS_GetVBType(BaseAddr,HwDeviceExtension);
+
+   /* TW: Get VB information (connectors, connected devices) */
+   SiS_GetVBInfo301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+   SiS_SetHiVision(BaseAddr,HwDeviceExtension);
+   SiS_GetLCDResInfo301(ROMAddr,SiS_P3d4,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+   /* TW: I am not sure the flag's name is correct */
+   if((SiS_IF_DEF_LVDS == 1) && (HwDeviceExtension->jChipType >= SIS_315H)) {
+      if(SiS_GetReg1(SiS_P3c4,0x17) & 0x08)  SiS_SetFlag |= CRT2IsVGA;
+   }
+
+   /* TW: Set mode on CRT1 */
+   SiS_SetCRT1Group(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+
+   pSiSEnt->CRT1ModeNo = ModeNo;
+   pSiSEnt->CRT1DMode = mode;
 
+   /* TW: SetPitch: Adapt to virtual size & position */
+   SiS_SetPitchCRT1(pScrn, BaseAddr);
+
+   /* We have to reset CRT2 if changing mode on CRT1 */
+   if (pSiSEnt->CRT2ModeNo != -1) {
+        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "(Re-)Setting mode 0x%x on CRT2\n",
+				pSiSEnt->CRT2ModeNo);
+	SiSBIOSSetModeCRT2(HwDeviceExtension, pSiSEnt->pScrn_1,
+				pSiSEnt->CRT2DMode);
+   }
+
+   if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 0)) {
+      SiS_SetRegAND(SiS_P3d4,0x63,0xbf);
+      temp = SiS_GetReg1(SiS_P3c4,0x15);
+      if(!(temp & 0x01)) {
+          if(!(temp & 0xa0)) {
+	     if(SiS_GetReg1(SiS_P3c4,0x16) & 0x01) {
+	        SiS_SetRegOR(SiS_P3d4,0x64,0x40);
+	     }
+	  } else {
+	     SiS_SetRegOR(SiS_P3d4,0x64,0x40);
+	  }
+      }
+   }
+
+   /* Backup/Set ModeNo in MMIO */
+   SiS_GetSetModeID(pScrn,ModeNo);
+
+   return TRUE;
 }
 
-/* win2000 MM adapter not support standard mode  */
+/* TW: Set CRT2 mode (used for dual head) */
 BOOLEAN
-SiS_SearchModeID (ULONG ROMAddr, USHORT ModeNo, USHORT * ModeIdIndex)
+SiSBIOSSetModeCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+               DisplayModePtr mode)
 {
-	PUCHAR VGA_INFO = "\0x11";
+   ULONG   temp;
+   USHORT  ModeIdIndex;
+#ifndef LINUX_XF86
+   USHORT  KeepLockReg;
+#endif
+   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
+   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+   UShort  ModeNo=0;
+   SISPtr  pSiS = SISPTR(pScrn);
+   SISEntPtr pSiSEnt = pSiS->entityPrivate;
+
+   ModeNo = SiS_CalcModeIndex(pScrn, mode);
+   if (!ModeNo) return FALSE;
+
+   SiSInitPtr(HwDeviceExtension);
+
+   SiSRegInit(BaseAddr);
+
+   SiSInitPCIetc(HwDeviceExtension);
+
+   SiSSetLVDSetc(HwDeviceExtension, ModeNo);
+
+   /* TW: We don't clear the buffer under X */
+   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) {
+   	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
+   	return TRUE;
+   }
+
+   xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Setting mode 0x%x on CRT2\n", ModeNo);
+
+   /* 1.Openkey */
+   SiS_SetReg1(SiS_P3c4,0x05,0x86);
+
+   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+
+   /* 2.Get ModeID */
+   temp = SiS_SearchModeID(ROMAddr,&ModeNo,&ModeIdIndex);
+   if(temp==0)  return(0);
+
+   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+   SiS_GetVBType(BaseAddr,HwDeviceExtension);
+
+   /* TW: Get VB information (connectors, connected devices) */
+   SiS_GetVBInfo301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+   SiS_SetHiVision(BaseAddr,HwDeviceExtension);
+   SiS_GetLCDResInfo301(ROMAddr,SiS_P3d4,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+   /* TW: I am not sure the flag's name is correct */
+   if((SiS_IF_DEF_LVDS == 1) && (HwDeviceExtension->jChipType >= SIS_315H)) {
+      if(SiS_GetReg1(SiS_P3c4,0x17) & 0x08)  SiS_SetFlag |= CRT2IsVGA;
+   }
+
+   /* Set mode on CRT2 */
+   switch (HwDeviceExtension->ujVBChipID) {
+     case VB_CHIP_301:
+     case VB_CHIP_301B:
+     case VB_CHIP_301LV:
+     case VB_CHIP_302:
+     case VB_CHIP_302B:
+     case VB_CHIP_302LV:
+        SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        break;
+     case VB_CHIP_303:
+        break;
+     case VB_CHIP_UNKNOWN:
+        if (SiS_IF_DEF_LVDS == 1 || SiS_IF_DEF_CH70xx == 1 || SiS_IF_DEF_TRUMPION != 0)
+             	SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        break;
+   }
+
+   if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 0)) {
+      SiS_SetRegAND(SiS_P3d4,0x63,0xbf);
+      temp = SiS_GetReg1(SiS_P3c4,0x15);
+      if(!(temp & 0x01)) {
+          if(!(temp & 0xa0)) {
+	     if(SiS_GetReg1(SiS_P3c4,0x16) & 0x01) {
+	        SiS_SetRegOR(SiS_P3d4,0x64,0x40);
+	     }
+	  } else {
+	     SiS_SetRegOR(SiS_P3d4,0x64,0x40);
+	  }
+      }
+   }
+
+   /* TW: SetPitch: Adapt to virtual size & position */
+   SiS_SetPitchCRT2(pScrn, BaseAddr);
+
+   /* Backup/Set ModeNo in MMIO - don't do this for CRT2 */
+   /* SiS_GetSetModeID(pScrn,ModeNo); */
 
-	if (ModeNo <= 5)
-		ModeNo |= 1;
-	if (ModeNo <= 0x13) {
-		/* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(SiS_SModeIDTable)/sizeof(SiS_StStruct);(*ModeIdIndex)++) */
-		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
-			if (SiS_SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo)
-				break;
-			if (SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
-				return FALSE;
-		}
-
-#ifdef TC
-		VGA_INFO = (PUCHAR) MK_FP (0, 0x489);
-#endif
-		if (ModeNo == 0x07) {
-			if ((*VGA_INFO & 0x10) != 0)
-				(*ModeIdIndex)++;	/* 400 lines */
-			/* else 350 lines */
-		}
-		if (ModeNo <= 3) {
-			if ((*VGA_INFO & 0x80) == 0) {
-				(*ModeIdIndex)++;
-				if ((*VGA_INFO & 0x10) != 0)
-					(*ModeIdIndex)++;;	/* 400 lines  */
-				/* else 350 lines  */
-			}
-			/* else 200 lines  */
-		}
-	} else {
-		/* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(SiS_EModeIDTable)/sizeof(SiS_ExtStruct);(*ModeIdIndex)++) */
-		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
-			if (SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
-				break;
-			if (SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
-				return FALSE;
-		}
-	}
-	return TRUE;
+   return TRUE;
 }
+#endif /* Dualhead */
+#endif /* Linux_XF86 */
 
-/*add for 300 oem util for search VBModeID*/
+#ifdef LINUX_XF86
+/* TW: We need pScrn for setting the pitch correctly */
+BOOLEAN
+SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,ScrnInfoPtr pScrn,USHORT ModeNo)
+#else
 BOOLEAN
-SiS_SearchVBModeID (ULONG ROMAddr, USHORT ModeNo)
+SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+#endif
 {
-	USHORT ModeIdIndex;
+   ULONG   temp;
+   USHORT  ModeIdIndex,KeepLockReg;
+   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
+   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
 
-	// PUCHAR VGA_INFO;
+   SiSInitPtr(HwDeviceExtension);
 
-	if (ModeNo <= 5)
-		ModeNo |= 1;
-	/* for (ModeIdIndex=0;ModeIdIndex<sizeof(SiS_SModeIDTable)/sizeof(SiS_StStruct);(*ModeIdIndex)++) */
-	for (ModeIdIndex = 0;; (ModeIdIndex)++) {
-		if (SiS_VBModeIDTable[ModeIdIndex].ModeID == ModeNo)
-			break;
-		if (SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)
-			return FALSE;
-	}
-#ifdef TC
-	VGA_INFO = (PUCHAR) MK_FP (0, 0x489);
-	if (ModeNo == 0x07) {
-		if ((*VGA_INFO & 0x10) != 0)
-			(ModeIdIndex)++;	/* 400 lines */
-		/* else 350 lines */
-	}
-	if (ModeNo <= 3) {
-		if ((*VGA_INFO & 0x80) == 0) {
-			(ModeIdIndex)++;
-			if ((*VGA_INFO & 0x10) != 0)
-				(ModeIdIndex)++;;	/* 400 lines  */
-			/* else 350 lines  */
-		}
-		/* else 200 lines  */
-	}
-#endif
-	return ((BOOLEAN) ModeIdIndex);
-}
+   SiSRegInit(BaseAddr);
 
-/*end*/
+   SiSInitPCIetc(HwDeviceExtension);
 
-/* win2000 MM adapter not support standard mode!  */
+   SiSSetLVDSetc(HwDeviceExtension, ModeNo);
 
-BOOLEAN
-SiS_CheckMemorySize (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		     USHORT ModeNo, USHORT ModeIdIndex)
-{
-	USHORT memorysize;
-	USHORT modeflag;
-	USHORT temp;
+#ifdef LINUX_XF86
+   /* TW: We don't clear the buffer in X */
+   ModeNo |= 0x8000;
+#endif
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
+   if(ModeNo & 0x8000) {
+     	ModeNo &= 0x007F;
+     	flag_clearbuffer=0;
+   } else {
+     	flag_clearbuffer=1;
+   }
 
-/*  ModeType=modeflag&ModeInfoFlag;                           Get mode type  */
+   /* 1.Openkey */
+   KeepLockReg = SiS_GetReg1(SiS_P3c4,0x05);
+   SiS_SetReg1(SiS_P3c4,0x05,0x86);
 
-	memorysize = modeflag & MemoryInfoFlag;
-	memorysize = memorysize > MemorySizeShift;
-	memorysize++;		/* Get memory size */
-
-	temp = SiS_GetReg1 (SiS_P3c4, 0x14);	/* Get DRAM Size    */
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO)) {
-		temp = 1 << ((temp & 0x0F0) >> 4);
-		if ((temp & 0x0c) == 0x08) {	/* DDR asymetric */
-			temp += temp / 2;
-		} else {
-			if ((temp & 0x0c) != 0) {
-				temp <<= 1;
-			}
-		}
-	} else {		/* 300, 540 , 630 */
-
-		temp = temp & 0x3F;
-		temp++;
-		/*  temp=1 << ((temp&0x0F0)>>4); */
-	}
+   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
 
-	if ((HwDeviceExtension->jChipType == SIS_550) ||	/* 05/02/01 ynlai for sis550 */
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740)) {	/* 09/03/01 chiawen for 650 */
-		return (TRUE);
-	}
+   /* 2.Get ModeID Table  */
+   temp = SiS_SearchModeID(ROMAddr,&ModeNo,&ModeIdIndex);
+   if(temp==0) return(0);
 
-	if (temp < memorysize)
-		return (FALSE);
-	else
-		return (TRUE);
-}
+   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+   SiS_GetVBType(BaseAddr,HwDeviceExtension);
 
-UCHAR
-SiS_GetModePtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
-{
-	UCHAR index;
+   /* TW: Get VB information (connectors, connected devices) */
+   SiS_GetVBInfo301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+   SiS_SetHiVision(BaseAddr,HwDeviceExtension);
+   SiS_GetLCDResInfo301(ROMAddr,SiS_P3d4,ModeNo,ModeIdIndex,HwDeviceExtension);
 
-	if (ModeNo <= 0x13) {
-		index = SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
-	} else {
-		if (SiS_ModeType <= 0x02)
-			index = 0x1B;	/* 02 -> ModeEGA  */
-		else
-			index = 0x0F;
-	}
+   /* TW: I am not sure the flag's name is correct */
+   if((SiS_IF_DEF_LVDS == 1) && (HwDeviceExtension->jChipType >= SIS_315H)) {
+      if(SiS_GetReg1(SiS_P3c4,0x17) & 0x08)  SiS_SetFlag |= CRT2IsVGA;
+   }
 
-	return index;		/* Get SiS_StandTable index  */
-}
+   /* 3.Check memory size */
+   temp = SiS_CheckMemorySize(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);
+   if(!temp) return(0);
 
-void
-SiS_SetSeqRegs (ULONG ROMAddr, USHORT StandTableIndex)
-{
-	UCHAR SRdata;
-	USHORT i;
+   /* TW: Set mode on CRT1 */
+   if(SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
+   	SiS_SetCRT1Group(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+   } else {
+     if(!(SiS_VBInfo & SwitchToCRT2)) {
+       	SiS_SetCRT1Group(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+     }
+   }
 
-	SiS_SetReg1 (SiS_P3c4, 0x00, 0x03);	/* Set SR0  */
-	SRdata = SiS_StandTable[StandTableIndex].SR[0];
-	/*301b */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		if (SiS_VBInfo & SetCRT2ToLCDA) {
-			SRdata = SRdata | 0x01;
-		}
-	}
+   /* TW: Set mode on CRT2 */
+   if(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {
+     switch (HwDeviceExtension->ujVBChipID) {
+     case VB_CHIP_301:
+     case VB_CHIP_301B:
+     case VB_CHIP_301LV:
+     case VB_CHIP_302:
+     case VB_CHIP_302B:
+     case VB_CHIP_302LV:
+        SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        break;
+     case VB_CHIP_303:
+        break;
+     case VB_CHIP_UNKNOWN:
+	if (SiS_IF_DEF_LVDS == 1 || SiS_IF_DEF_CH70xx != 0 || SiS_IF_DEF_TRUMPION != 0)
+             	SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        break;
+     }
+   }
 
-	/*end 301b */
+   /* TW: Inserted from 650/301LV BIOS */
+   if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 0)) {
+      SiS_SetRegAND(SiS_P3d4,0x63,0xbf);
+      temp = SiS_GetReg1(SiS_P3c4,0x15);
+      if(!(temp & 0x01)) {
+          if(!(temp & 0xa0)) {
+	     if(SiS_GetReg1(SiS_P3c4,0x16) & 0x01) {
+	        SiS_SetRegOR(SiS_P3d4,0x64,0x40);
+	     }
+	  } else {
+	     SiS_SetRegOR(SiS_P3d4,0x64,0x40);
+	  }
+      }
+   }
 
-	if (SiS_IF_DEF_LVDS == 1) {
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				if (SiS_VBInfo & SetInSlaveMode) {
-					SRdata = SRdata | 0x01;	/* 8 dot clock  */
-				}
-			}
-		}
-		if (SiS_VBInfo & SetCRT2ToLCD) {
-			if (SiS_VBInfo & SetInSlaveMode) {
-				SRdata = SRdata | 0x01;	/* 8 dot clock  */
-			}
-		}
-	}
+#ifdef LINUX_XF86
+   /* TW: SetPitch: Adapt to virtual size & position */
+   if(pScrn)
+      SiS_SetPitch(pScrn, BaseAddr);
 
-	SRdata = SRdata | 0x20;	/* screen off  */
-	SiS_SetReg1 (SiS_P3c4, 0x01, SRdata);	/* Set SR1 */
-	for (i = 02; i <= 04; i++) {
-		SRdata = SiS_StandTable[StandTableIndex].SR[i - 1];	/* Get SR2,3,4 from file */
-		SiS_SetReg1 (SiS_P3c4, i, SRdata);	/* Set SR2 3 4 */
-	}
+   /* Backup/Set ModeNo in MMIO */
+   SiS_GetSetModeID(pScrn,ModeNo);
+#endif
+
+#ifndef LINUX_XF86  /* TW: We never lock registers in XF86 */
+   if(KeepLockReg==0xA1) SiS_SetReg1(SiS_P3c4,0x05,0x86);
+   else SiS_SetReg1(SiS_P3c4,0x05,0x00);
+#endif
+
+   return TRUE;
 }
 
 void
-SiS_SetMiscRegs (ULONG ROMAddr, USHORT StandTableIndex)
+SetEnableDstn()		/* TW: Called from sis_main.c */
 {
-	UCHAR Miscdata;
-
-	Miscdata = SiS_StandTable[StandTableIndex].MISC;	/* Get Misc from file */
-	/*301b */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		if (SiS_VBInfo & SetCRT2ToLCDA) {
-			Miscdata = Miscdata | 0x0C;
-		}
-	}
-	/*end 301b */
-	SiS_SetReg3 (SiS_P3c2, Miscdata);	/* Set Misc(3c2) */
+   SiS_IF_DEF_DSTN=1;   /* for 550 dstn */
 }
 
 void
-SiS_SetCRTCRegs (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		 USHORT StandTableIndex)
+SiS_SetCRT1Group(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                 USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr)
 {
-	UCHAR CRTCdata;
-	USHORT i;
+  USHORT  StandTableIndex,RefreshRateTableIndex;
 
-	CRTCdata = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x11);
-	CRTCdata = CRTCdata & 0x7f;
-	SiS_SetReg1 (SiS_P3d4, 0x11, CRTCdata);	/* Unlock CRTC */
+  SiS_CRT1Mode = ModeNo;
+  StandTableIndex = SiS_GetModePtr(ROMAddr,ModeNo,ModeIdIndex);
+  if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
+    if(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
+      SiS_DisableBridge(HwDeviceExtension,BaseAddr);
+    }
+  }
 
-	for (i = 0; i <= 0x18; i++) {
-		CRTCdata = SiS_StandTable[StandTableIndex].CRTC[i];	/* Get CRTC from file */
-		SiS_SetReg1 (SiS_P3d4, i, CRTCdata);	/* Set CRTC(3d4) */
-	}
-	if ((HwDeviceExtension->jChipType == SIS_630) &&
-	    (HwDeviceExtension->jChipRevision == 0x30)) {	/* for 630S0 */
-		if (SiS_VBInfo & SetInSlaveMode) {
-			if (SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-				SiS_SetReg1 (SiS_P3d4, 0x18, 0xFE);
-			}
-		}
-	}
-}
+  SiS_SetSeqRegs(ROMAddr,StandTableIndex);
+  SiS_SetMiscRegs(ROMAddr,StandTableIndex);
+  SiS_SetCRTCRegs(ROMAddr,HwDeviceExtension,StandTableIndex);
+  SiS_SetATTRegs(ROMAddr,StandTableIndex,ModeNo,HwDeviceExtension);
+  SiS_SetGRCRegs(ROMAddr,StandTableIndex);
+  SiS_ClearExt1Regs(HwDeviceExtension);
+  SiS_ResetCRT1VCLK(ROMAddr,HwDeviceExtension);
+  SiS_SelectCRT2Rate=0;
+  SiS_SetFlag &= (~ProgrammingCRT2);
 
-void
-SiS_SetATTRegs (ULONG ROMAddr, USHORT StandTableIndex)
-{
-	UCHAR ARdata;
-	USHORT i;
+#ifdef LINUX_XF86
+  xf86DrvMsg(0, X_INFO, "(init: VBType = %x, LVDS=%d, VBInfo=%x)\n",
+                    SiS_VBType, SiS_IF_DEF_LVDS, SiS_VBInfo);
+#endif
 
-	for (i = 0; i <= 0x13; i++) {
-		ARdata = SiS_StandTable[StandTableIndex].ATTR[i];	/* Get AR for file  */
-		/*301b */
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-			if (SiS_VBInfo & SetCRT2ToLCDA) {
-				if (i == 0x13) {
-					ARdata = 0;
-				}
-			}
-		}
-		/*end 301b */
-		if (SiS_IF_DEF_LVDS == 1) {	/*for LVDS  */
-			if (SiS_IF_DEF_CH7005 == 1) {
-				if (SiS_VBInfo & SetCRT2ToTV) {
-					if (SiS_VBInfo & SetInSlaveMode) {
-						if (i == 0x13) {
-							ARdata = 0;
-						}
-					}
-				}
-			}
-			if (SiS_VBInfo & SetCRT2ToLCD) {
-				if (SiS_VBInfo & SetInSlaveMode) {
-					if (SiS_LCDInfo & LCDNonExpanding) {
-						if (i == 0x13) {
-							ARdata = 0;
-						}
-					}
-				}
-			}
-		}
-		SiS_GetReg2 (SiS_P3da);	/* reset 3da  */
-		SiS_SetReg3 (SiS_P3c0, i);	/* set index  */
-		SiS_SetReg3 (SiS_P3c0, ARdata);	/* set data   */
-	}
-	SiS_GetReg2 (SiS_P3da);	/* reset 3da  */
-	SiS_SetReg3 (SiS_P3c0, 0x14);	/* set index  */
-	SiS_SetReg3 (SiS_P3c0, 0x00);	/* set data   */
+  /* TW: Inserted this entire if-section from 650/LVDS and 650/301 BIOS */
+  if(SiS_VBInfo & SetSimuScanMode) {
+     if(SiS_VBInfo & SetInSlaveMode) {
+        SiS_SetFlag |= ProgrammingCRT2;
+     }
+  }
+  /* TW: Removed 301B301LV302B302LV check here */
+  if(SiS_VBInfo & SetCRT2ToLCDA) {
+	 SiS_SetFlag |= ProgrammingCRT2;
+  }
 
-	SiS_GetReg2 (SiS_P3da);	/* Enable Attribute  */
-	SiS_SetReg3 (SiS_P3c0, 0x20);
-}
+  RefreshRateTableIndex = SiS_GetRatePtrCRT2(ROMAddr,ModeNo,ModeIdIndex);
 
-void
-SiS_SetGRCRegs (ULONG ROMAddr, USHORT StandTableIndex)
-{
-	UCHAR GRdata;
-	USHORT i;
+  /* TW: Removed 301B301LV302B302LV check here */
+  if(!(SiS_VBInfo & SetCRT2ToLCDA)) {
+	 SiS_SetFlag &= (~ProgrammingCRT2);
+  }
 
-	for (i = 0; i <= 0x08; i++) {
-		GRdata = SiS_StandTable[StandTableIndex].GRC[i];	/* Get GR from file */
-		SiS_SetReg1 (SiS_P3ce, i, GRdata);	/* Set GR(3ce) */
-	}
+  if (RefreshRateTableIndex != 0xFFFF) {
+    SiS_SetSync(ROMAddr,RefreshRateTableIndex);
+    SiS_SetCRT1CRTC(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+    SiS_SetCRT1Offset(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+    SiS_SetCRT1VCLK(ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,RefreshRateTableIndex);
+  }
 
-	if (SiS_ModeType > ModeVGA) {
-		GRdata = (UCHAR) SiS_GetReg1 (SiS_P3ce, 0x05);
-		GRdata = GRdata & 0xBF;	/* 256 color disable */
-		SiS_SetReg1 (SiS_P3ce, 0x05, GRdata);
-	}
-}
+#ifdef SIS300
+  if((HwDeviceExtension->jChipType == SIS_630)||
+     (HwDeviceExtension->jChipType == SIS_730)||
+     (HwDeviceExtension->jChipType == SIS_540)) {
+     	SiS_SetCRT1FIFO_300(ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
+  }
+#endif
+#ifdef SIS315H
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     	SiS_SetCRT1FIFO_310(ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+  }
+#endif
 
-void
-SiS_ClearExt1Regs ()
-{
-	USHORT i;
+  SiS_SetCRT1ModeRegs(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,RefreshRateTableIndex);
 
-	for (i = 0x0A; i <= 0x0E; i++)
-		SiS_SetReg1 (SiS_P3c4, i, 0x00);	/* Clear SR0A-SR0E */
-}
+#if 0  /* TW: Not done in any BIOS */
+#ifdef SIS315H
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+    if (RefreshRateTableIndex != 0xFFFF) {
+      	SiS_SetInterlace(ROMAddr,ModeNo,RefreshRateTableIndex);
+    }
+#endif
+  }
+#endif
 
-void
-SiS_SetSync (ULONG ROMAddr, USHORT RefreshRateTableIndex)
-{
-	USHORT sync;
-	USHORT temp;
-
-	sync = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;	/* di+0x00 */
-
-	sync = sync & 0xC0;
-	temp = 0x2F;
-	temp = temp | sync;
-	SiS_SetReg3 (SiS_P3c2, temp);	/* Set Misc(3c2) */
-}
-
-void
-SiS_SetCRT1CRTC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex)
-{
-	UCHAR index;
-	UCHAR data;
-	USHORT temp, tempah, i, modeflag, j;
-	USHORT ResInfo, DisplayType;
-	SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
-	if ((SiS_VBType & VB_SIS302B) && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		/*add crt1ptr */
-		if (ModeNo <= 0x13) {
-			modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		} else {
-			modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		}
-		temp =
-		    SiS_GetLCDACRT1Ptr (ROMAddr, ModeNo, ModeIdIndex,
-					RefreshRateTableIndex, &ResInfo,
-					&DisplayType);
-
-		switch (DisplayType) {
-		case 0:
-			LCDACRT1Ptr = SiS_LCDACRT1800x600_1;
-			break;
-		case 1:
-			LCDACRT1Ptr = SiS_LCDACRT11024x768_1;
-			break;
-		case 2:
-			LCDACRT1Ptr = SiS_LCDACRT11280x1024_1;
-			break;
-		case 3:
-			LCDACRT1Ptr = SiS_LCDACRT1800x600_1_H;
-			break;
-		case 4:
-			LCDACRT1Ptr = SiS_LCDACRT11024x768_1_H;
-			break;
-		case 5:
-			LCDACRT1Ptr = SiS_LCDACRT11280x1024_1_H;
-			break;
-		case 6:
-			LCDACRT1Ptr = SiS_LCDACRT1800x600_2;
-			break;
-		case 7:
-			LCDACRT1Ptr = SiS_LCDACRT11024x768_2;
-			break;
-		case 8:
-			LCDACRT1Ptr = SiS_LCDACRT11280x1024_2;
-			break;
-		case 9:
-			LCDACRT1Ptr = SiS_LCDACRT1800x600_2_H;
-			break;
-		case 10:
-			LCDACRT1Ptr = SiS_LCDACRT11024x768_2_H;
-			break;
-		case 11:
-			LCDACRT1Ptr = SiS_LCDACRT11280x1024_2_H;
-			break;
-			/*case 12: LCDACRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
-			   case 13: LCDACRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
-			   case 14: LCDACRT1Ptr = SiS_CHTVCRT1UPAL;                break;
-			   case 15: LCDACRT1Ptr = SiS_CHTVCRT1OPAL;                break; */
-		}
-
-		tempah = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x11);	/*unlock cr0-7  */
-		tempah = tempah & 0x7F;
-		SiS_SetReg1 (SiS_P3d4, 0x11, tempah);
-		tempah = (LCDACRT1Ptr + ResInfo)->CR[0];
-		SiS_SetReg1 (SiS_P3d4, 0x0, tempah);
-		for (i = 0x01, j = 1; i <= 0x07; i++, j++) {
-			tempah = (LCDACRT1Ptr + ResInfo)->CR[j];
-			SiS_SetReg1 (SiS_P3d4, i, tempah);
-		}
-/* for(i=0x06,j=5;i<=0x07;i++,j++){
-   tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3d4,i,tempah);
-  }*/
-		for (i = 0x10, j = 8; i <= 0x12; i++, j++) {
-			tempah = (LCDACRT1Ptr + ResInfo)->CR[j];
-			SiS_SetReg1 (SiS_P3d4, i, tempah);
-		}
-		for (i = 0x15, j = 11; i <= 0x16; i++, j++) {
-			tempah = (LCDACRT1Ptr + ResInfo)->CR[j];
-			SiS_SetReg1 (SiS_P3d4, i, tempah);
-		}
-
-		for (i = 0x0A, j = 13; i <= 0x0C; i++, j++) {
-			tempah = (LCDACRT1Ptr + ResInfo)->CR[j];
-			SiS_SetReg1 (SiS_P3c4, i, tempah);
-		}
-
-		tempah = (LCDACRT1Ptr + ResInfo)->CR[16];
-		tempah = tempah & 0x0E0;
-		SiS_SetReg1 (SiS_P3c4, 0x0E, tempah);
-
-		tempah = (LCDACRT1Ptr + ResInfo)->CR[16];
-		tempah = tempah & 0x01;
-		tempah = tempah << 5;
-		if (modeflag & DoubleScanMode) {
-			tempah = tempah | 0x080;
-		}
-		SiS_SetRegANDOR (SiS_P3d4, 0x09, ~0x020, tempah);
-		if (SiS_ModeType > 0x03)
-			SiS_SetReg1 (SiS_P3d4, 0x14, 0x4F);
-/*end 301b*/
-	} else {
-		index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;	/* Get index */
-		index = index & 0x3F;
+  SiS_LoadDAC(ROMAddr,ModeNo,ModeIdIndex);
 
-		data = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x11);
-		data = data & 0x7F;
-		SiS_SetReg1 (SiS_P3d4, 0x11, data);	/* Unlock CRTC */
-
-		for (i = 0, j = 0; i <= 07; i++, j++) {
-			data = SiS_CRT1Table[index].CR[i];
-			SiS_SetReg1 (SiS_P3d4, j, data);
-		}
-		for (j = 0x10; i <= 10; i++, j++) {
-			data = SiS_CRT1Table[index].CR[i];
-			SiS_SetReg1 (SiS_P3d4, j, data);
-		}
-		for (j = 0x15; i <= 12; i++, j++) {
-			data = SiS_CRT1Table[index].CR[i];
-			SiS_SetReg1 (SiS_P3d4, j, data);
-		}
-		for (j = 0x0A; i <= 15; i++, j++) {
-			data = SiS_CRT1Table[index].CR[i];
-			SiS_SetReg1 (SiS_P3c4, j, data);
-		}
-
-		data = SiS_CRT1Table[index].CR[16];
-		data = data & 0xE0;
-		SiS_SetReg1 (SiS_P3c4, 0x0E, data);
-
-		data = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x09);
-		data = data & 0xDF;	/* clear CR9 D[5] */
-		i = SiS_CRT1Table[index].CR[16];
-		i = i & 0x01;
-		i = i << 5;
-		data = data | i;
-
-		if (ModeNo <= 0x13)
-			i = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-		else
-			i = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
-		i = i & DoubleScanMode;
-		if (i)
-			data = data | 0x80;
-		SiS_SetReg1 (SiS_P3d4, 0x09, data);
+  if(flag_clearbuffer) SiS_ClearBuffer(HwDeviceExtension,ModeNo);
 
-		if (SiS_ModeType > 0x03)
-			SiS_SetReg1 (SiS_P3d4, 0x14, 0x4F);
-	}
+  if(!(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA))) {
+    SiS_LongWait();
+    SiS_DisplayOn();
+  }
 }
+
+#ifdef LINUX_XF86
 void
-SiS_SetCRT1Offset (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex,
-		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT temp, ah, al;
-	USHORT temp2, i;
-	USHORT DisplayUnit;
-
-	/* Alan */
-	temp = SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
-	if (HwDeviceExtension->jChipType >= SIS_315H) {
-		temp = temp >> 8;	/* sis310 *//* index */
-	} else {
-		temp = temp >> 4;	/* sis300 *//* index */
-	}
-	temp = SiS_ScreenOffset[temp];
-	if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
-		temp = 0x6B;
-		temp2 = ModeNo - 0x7C;
-	} else {
-		temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-		temp2 = temp2 & InterlaceMode;
-		if (temp2)
-			temp = temp << 1;
-		temp2 = SiS_ModeType - ModeEGA;
-	}
-	switch (temp2) {
-	case 0:
-		temp2 = 1;
-		break;
-	case 1:
-		temp2 = 2;
-		break;
-	case 2:
-		temp2 = 4;
-		break;
-	case 3:
-		temp2 = 4;
-		break;
-	case 4:
-		temp2 = 6;
-		break;
-	case 5:
-		temp2 = 8;
-		break;
-	}
-	temp = temp * temp2;
-	DisplayUnit = temp;
+SiS_SetPitch(ScrnInfoPtr pScrn, UShort BaseAddr)
+{
+   SISPtr pSiS = SISPTR(pScrn);
 
-	temp2 = temp;
-	temp = temp >> 8;	/* ah */
-	temp = temp & 0x0F;
-	i = SiS_GetReg1 (SiS_P3c4, 0x0E);
-	i = i & 0xF0;
-	i = i | temp;
-	SiS_SetReg1 (SiS_P3c4, 0x0E, i);
-
-	temp = (UCHAR) temp2;
-	temp = temp & 0xFF;	/* al */
-	SiS_SetReg1 (SiS_P3d4, 0x13, temp);
-
-	temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	temp2 = temp2 & InterlaceMode;
-	if (temp2)
-		DisplayUnit >>= 1;
-
-	DisplayUnit = DisplayUnit << 5;
-	ah = (DisplayUnit & 0xff00) >> 8;
-	al = DisplayUnit & 0x00ff;
-	if (al == 0)
-		ah = ah + 1;
-	else
-		ah = ah + 2;
-	SiS_SetReg1 (SiS_P3c4, 0x10, ah);
+   /* 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_Part1Port,0x00) & 0xa0) == 0x20) ||
+           ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
+   	SiS_SetPitchCRT1(pScrn, BaseAddr);
+   }
+   if (pSiS->VBFlags & DISPTYPE_DISP2) {
+   	SiS_SetPitchCRT2(pScrn, BaseAddr);
+   }
 }
 
 void
-SiS_SetCRT1VCLK (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		 USHORT RefreshRateTableIndex)
-{
-	UCHAR index, data;
-	USHORT vclkindex;
-	if (SiS_IF_DEF_LVDS == 1) {
-		vclkindex =
-		    SiS_GetVCLK2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				     RefreshRateTableIndex, HwDeviceExtension);
-		data = SiS_GetReg1 (SiS_P3c4, 0x31) & 0xCF;
-		SiS_SetReg1 (SiS_P3c4, 0x31, data);
-
-		data = SiS_VCLKData[vclkindex].SR2B;
-		SiS_SetReg1 (SiS_P3c4, 0x2B, data);
-		data = SiS_VCLKData[vclkindex].SR2C;
-		SiS_SetReg1 (SiS_P3c4, 0x2C, data);
-
-		if (HwDeviceExtension->jChipType < SIS_315H)
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x80);
-		else
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x01);
-
-	}
-		else
-	    if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-		&& (SiS_VBInfo & SetCRT2ToLCDA) && (SiS_IF_DEF_LVDS == 0)) {
-		vclkindex =
-		    SiS_GetVCLK2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				     RefreshRateTableIndex, HwDeviceExtension);
-		data = SiS_GetReg1 (SiS_P3c4, 0x31) & 0xCF;
-		SiS_SetReg1 (SiS_P3c4, 0x31, data);
-
-		data = SiS_VBVCLKData[vclkindex].Part4_A;
-		SiS_SetReg1 (SiS_P3c4, 0x2B, data);
-		data = SiS_VBVCLKData[vclkindex].Part4_B;
-		SiS_SetReg1 (SiS_P3c4, 0x2C, data);
-
-		if (HwDeviceExtension->jChipType < SIS_315H)
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x80);	/* for300 series */
-		else
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x01);
+SiS_SetPitchCRT1(ScrnInfoPtr pScrn, UShort BaseAddr)
+{
+    SISPtr pSiS = SISPTR(pScrn);
+    ULong  HDisplay,temp;
 
-	} else {
-		index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-		/*if(HwDeviceExtension->jChipType < SIS_315H) { */
-		index = index & 0x3F;
-		/*} */
-		data = SiS_GetReg1 (SiS_P3c4, 0x31) & 0xCF;
-/*SiS_SetReg1(SiS_P3c4,0x31,0x00); *//* for300 */
-		SiS_SetReg1 (SiS_P3c4, 0x31, data);
-		SiS_SetReg1 (SiS_P3c4, 0x2B, SiS_VCLKData[index].SR2B);
-		SiS_SetReg1 (SiS_P3c4, 0x2C, SiS_VCLKData[index].SR2C);
-		if (HwDeviceExtension->jChipType < SIS_315H)
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x80);	/* for300 series */
-		else
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x01);	/* for310 series */
-	}
+    HDisplay = pSiS->scrnPitch / 8;
+    SiS_SetReg1(SiS_P3d4, 0x13, (HDisplay & 0xFF));
+    temp = (SiS_GetReg1(SiS_P3c4, 0x0E) & 0xF0) | (HDisplay>>8);
+    SiS_SetReg1(SiS_P3c4, 0x0E, temp);
 }
+
 void
-SiS_IsLowResolution (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_SetPitchCRT2(ScrnInfoPtr pScrn, UShort BaseAddr)
 {
-	USHORT data;
-	USHORT ModeFlag;
+    SISPtr pSiS = SISPTR(pScrn);
+    ULong  HDisplay,temp;
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x0F);
-	data = data & 0x7F;
-	SiS_SetReg1 (SiS_P3c4, 0x0F, data);
-
-	if (ModeNo > 0x13) {
-		ModeFlag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
-			data = SiS_GetReg1 (SiS_P3c4, 0x0F);
-			data = data | 0x80;
-			SiS_SetReg1 (SiS_P3c4, 0x0F, data);
-			data = SiS_GetReg1 (SiS_P3c4, 0x01);
-			data = data & 0xF7;
-			SiS_SetReg1 (SiS_P3c4, 0x01, data);
-		}
-	}
+    HDisplay = pSiS->scrnPitch / 8;
+
+    /* Unlock CRT2 */
+    if (pSiS->VGAEngine == SIS_315_VGA)
+        SiS_SetRegANDOR(SiS_Part1Port,0x2F, 0xFF, 0x01);
+    else
+        SiS_SetRegANDOR(SiS_Part1Port,0x24, 0xFF, 0x01);
+
+    SiS_SetReg1(SiS_Part1Port,0x07, (HDisplay & 0xFF));
+    temp = (SiS_GetReg1(SiS_Part1Port,0x09) & 0xF0) | ((HDisplay >> 8) & 0xFF);
+    SiS_SetReg1(SiS_Part1Port,0x09, temp);
 }
+#endif
 
+/* TW: Checked against 650/301 and 630/301B BIOS */
 void
-SiS_SetCRT1ModeRegs (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		     USHORT ModeNo, USHORT ModeIdIndex,
-		     USHORT RefreshRateTableIndex)
-{
-	USHORT data, data2, data3;
-	USHORT infoflag = 0, modeflag;
-	USHORT resindex, xres;
-
-	if (ModeNo > 0x13) {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	} else {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ModeFlag */
-	}
-	SiS_SetRegANDOR (SiS_P3c4, 0x1F, 0x3F, 0x00);
-	if (ModeNo > 0x13)
-		data = infoflag;
-	else
-		data = 0;
-	data2 = 0;
-	if (ModeNo > 0x13) {
-		if (SiS_ModeType > 0x02) {
-			data2 = data2 | 0x02;
-			data3 = SiS_ModeType - ModeVGA;
-			data3 = data3 << 2;
-			data2 = data2 | data3;
-		}
-	}
-	data = data & InterlaceMode;
-	if (data)
-		data2 = data2 | 0x20;
-	SiS_SetReg1 (SiS_P3c4, 0x06, data2);
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		resindex = SiS_GetResInfo (ROMAddr, ModeNo, ModeIdIndex);
-		if (ModeNo <= 0x13) {
-			xres = SiS_StResInfo[resindex].HTotal;
-		} else {
-			xres = SiS_ModeResInfo[resindex].HTotal;	/* xres->ax */
-		}
-		data = 0x0000;
-		if (infoflag & InterlaceMode) {
-			if (xres == 1024)
-				data = 0x0035;
-			if (xres == 1280)
-				data = 0x0048;
-		}
-		data2 = data & 0x00FF;
-		SiS_SetRegANDOR (SiS_P3d4, 0x19, 0xFF, data2);
-		data2 = (data & 0xFF00) >> 8;
-		SiS_SetRegANDOR (SiS_P3d4, 0x19, 0xFC, data2);
-	}
-	if (modeflag & HalfDCLK) {
-		SiS_SetRegANDOR (SiS_P3c4, 0x01, 0xFF, 0x01);
-	}
+SiS_GetVBType(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT flag;
 
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-	} else {
-		if (modeflag & LineCompareOff) {
-			SiS_SetRegANDOR (SiS_P3c4, 0x0F, 0xF7, 0x08);
-		} else {
-			SiS_SetRegANDOR (SiS_P3c4, 0x0F, 0xF7, 0x00);
-		}
-	}
+  SiS_VBType = 0;
+  
+  if(SiS_IF_DEF_LVDS == 1) return;
 
-	data = 0x60;
-	if (SiS_ModeType != ModeText) {
-		data = data ^ 0x60;
-		if (SiS_ModeType != ModeEGA) {
-			data = data ^ 0xA0;
-		}
-	}
-	SiS_SetRegANDOR (SiS_P3c4, 0x21, 0x1F, data);
+  flag = SiS_GetReg1(SiS_Part4Port,0x00);
+
+  /* TW: Illegal values not welcome... */
+  if(flag > 10) return;
+
+  if (flag >= 2) {
+  	flag=SiS_GetReg1(SiS_Part4Port,0x01);
+        if(flag >= 0xB0){
+            	SiS_VBType = VB_SIS302B;
+            	if(flag >= 0xD0)
+               		SiS_VBType = VB_SIS302LV;
+        }
+  } else if (flag == 1) {
+        flag=SiS_GetReg1(SiS_Part4Port,0x01);
+        if(flag >= 0xB0){
+            	SiS_VBType = VB_SIS301B;
+            	if(flag >= 0xD0)
+               		SiS_VBType = VB_SIS301LV;
+        } else
+            SiS_VBType = VB_SIS301;
+  }
+  /* TW: This is checked in 630 BIOS, but not used */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+    if(SiS_VBType & VB_SIS301BLV302BLV) {
+      flag = SiS_GetReg1(SiS_Part4Port,0x23);
+      if(!(flag & 0x02))
+       	SiS_VBType |= VB_NoLCD;
+    }
+  }
 }
 
-void
-SiS_SetVCLKState (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		  USHORT ModeNo, USHORT RefreshRateTableIndex)
+BOOLEAN
+SiS_SearchModeID(UCHAR *ROMAddr,USHORT *ModeNo,USHORT *ModeIdIndex)
 {
-	USHORT data, data2 = 0;
-	USHORT VCLK;
-	UCHAR index;
+   UCHAR VGAINFO = 0x11;  /* TW: Replaces ds:449 */
 
-	if (ModeNo <= 0x13)
-		VCLK = 0;
-	else {
-		index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-		/*if(HwDeviceExtension->jChipType < SIS_315H) { */
-		index = index & 0x3F;
-		/*} */
-		VCLK = SiS_VCLKData[index].CLOCK;
-	}
+   if(*ModeNo <= 0x13) {
 
-	if (HwDeviceExtension->jChipType < SIS_315H) {
-		data2 = 0x00;
-		if (VCLK > 150)
-			data2 = data2 | 0x80;
-		SiS_SetRegANDOR (SiS_P3c4, 0x07, 0x7B, data2);
-
-		data2 = 0x00;
-		if (VCLK >= 150)
-			data2 = data2 | 0x08;	/* VCLK > 150 */
-		SiS_SetRegANDOR (SiS_P3c4, 0x32, 0xF7, data2);
-	} else {		/* 310 series */
-
-		data = SiS_GetReg1 (SiS_P3c4, 0x32);
-		data = data & 0xf3;
-		if (VCLK >= 200)
-			data = data | 0x0c;	/* VCLK > 200 */
-		SiS_SetReg1 (SiS_P3c4, 0x32, data);
-		data = SiS_GetReg1 (SiS_P3c4, 0x1F);
-		data &= 0xE7;
-		if (VCLK < 200)
-			data |= 0x10;
-		SiS_SetReg1 (SiS_P3c4, 0x1F, data);
-	}
+      if((*ModeNo) <= 5) (*ModeNo) |= 1;
 
-	if ((VCLK >= 0) && (VCLK < 135))
-		data2 = 0x03;
-	if ((VCLK >= 135) && (VCLK < 160))
-		data2 = 0x02;
-	if ((VCLK >= 160) && (VCLK < 260))
-		data2 = 0x01;
-	if (VCLK > 260)
-		data2 = 0x00;
-	/* disable 24bit palette RAM gamma correction  */
-
-	if (HwDeviceExtension->jChipType == SIS_540) {
-		if ((VCLK == 203) || (VCLK < 234))
-			data2 = 0x02;
-	}
-	SiS_SetRegANDOR (SiS_P3c4, 0x07, 0xFC, data2);
+      for (*ModeIdIndex=0;;(*ModeIdIndex)++) {
+         if (SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break;
+         if (SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)   return FALSE;
+      }
+
+      if(*ModeNo == 0x07) {
+          if(VGAINFO & 0x10) (*ModeIdIndex)++;   /* 400 lines */
+          /* else 350 lines */
+      }
+      if(*ModeNo <= 3) {
+         if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
+         if(VGAINFO & 0x10)    (*ModeIdIndex)++; /* 400 lines  */
+         /* else 350 lines  */
+      }
+      /* else 200 lines  */
+
+   } else {
+
+      for (*ModeIdIndex=0;;(*ModeIdIndex)++) {
+         if (SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
+         if (SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)   return FALSE;
+      }
+
+   }
+   return TRUE;
 }
 
-void
-SiS_LoadDAC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+/* For SiS 300 oem util: Search VBModeID */
+BOOLEAN
+SiS_SearchVBModeID(UCHAR *ROMAddr, USHORT *ModeNo)
 {
-	USHORT data, data2;
-	USHORT time, i, j, k;
-	USHORT m, n, o;
-	USHORT si, di, bx, dl;
-	USHORT al, ah, dh;
-	USHORT *table = NULL;
+   USHORT ModeIdIndex;
+   UCHAR VGAINFO = 0x11;  /* TW: Replaces ds:449 */
 
-	if (ModeNo <= 0x13)
-		data = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	else
-		data = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+   if(*ModeNo <= 5) *ModeNo |= 1;
 
-	data = data & DACInfoFlag;
-	time = 64;
-	if (data == 0x00)
-		table = SiS_MDA_DAC;
-	if (data == 0x08)
-		table = SiS_CGA_DAC;
-	if (data == 0x10)
-		table = SiS_EGA_DAC;
-	if (data == 0x18) {
-		time = 256;
-		table = SiS_VGA_DAC;
-	}
-	if (time == 256)
-		j = 16;
-	else
-		j = time;
+   for(ModeIdIndex=0; ; ModeIdIndex++) {
+       if (SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
+       if (SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)   return FALSE;
+   }
 
-	SiS_SetReg3 (SiS_P3c6, 0xFF);
-	SiS_SetReg3 (SiS_P3c8, 0x00);
+   if(*ModeNo != 0x07) {
+        if(*ModeNo > 0x03) return ((BOOLEAN)ModeIdIndex);
+	if(VGAINFO & 0x80) return ((BOOLEAN)ModeIdIndex);
+	ModeIdIndex++;
+   }
+   if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
+	                               /* else 350 lines */
+   return ((BOOLEAN)ModeIdIndex);
+}
 
-	for (i = 0; i < j; i++) {
-		data = table[i];
-		for (k = 0; k < 3; k++) {
-			data2 = 0;
-			if (data & 0x01)
-				data2 = 0x2A;
-			if (data & 0x02)
-				data2 = data2 + 0x15;
-			SiS_SetReg3 (SiS_P3c9, data2);
-			data = data >> 2;
-		}
-	}
+/* TW: Checked against 630/301B and 315 BIOS */
+BOOLEAN
+SiS_CheckMemorySize(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                    USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT memorysize,modeflag,temp;
 
-	if (time == 256) {
-		for (i = 16; i < 32; i++) {
-			data = table[i];
-			for (k = 0; k < 3; k++)
-				SiS_SetReg3 (SiS_P3c9, data);
-		}
-		si = 32;
-		for (m = 0; m < 9; m++) {
-			di = si;
-			bx = si + 0x04;
-			dl = 0;
-			for (n = 0; n < 3; n++) {
-				for (o = 0; o < 5; o++) {
-					dh = table[si];
-					ah = table[di];
-					al = table[bx];
-					si++;
-					SiS_WriteDAC (dl, ah, al, dh);
-				}	/* for 5 */
-				si = si - 2;
-				for (o = 0; o < 3; o++) {
-					dh = table[bx];
-					ah = table[di];
-					al = table[si];
-					si--;
-					SiS_WriteDAC (dl, ah, al, dh);
-				}	/* for 3 */
-				dl++;
-			}	/* for 3 */
-			si = si + 5;
-		}		/* for 9 */
-	}
+  if((HwDeviceExtension->jChipType == SIS_550)||
+     (HwDeviceExtension->jChipType == SIS_640)||
+     (HwDeviceExtension->jChipType == SIS_740)||
+     (HwDeviceExtension->jChipType == SIS_650))
+    return(TRUE);
+
+  if (ModeNo<=0x13) {
+    modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+    modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+
+  memorysize = modeflag & MemoryInfoFlag;
+  memorysize >>= MemorySizeShift;
+  memorysize++;                                        		/* Get memory size */
+
+  temp = SiS_GetReg1(SiS_P3c4,0x14);                            /* Get DRAM Size    */
+
+  if((HwDeviceExtension->jChipType == SIS_315H)||
+     (HwDeviceExtension->jChipType == SIS_315PRO)) {		/* 315 */
+    temp = 1 << ((temp & 0x0F0) >> 4);
+    if ((temp & 0x0c) == 0x08) {   /* DDR asymetric */
+      temp += (temp/2);
+    } else {
+      if ((temp & 0x0c) != 0) temp <<= 1;
+    }
+  } else { 							/* 300, 540, 630, 730 */
+    temp &= 0x3F;
+    temp++;
+  }
+
+  if(temp < memorysize) return(FALSE);
+  else return(TRUE);
 }
 
-void
-SiS_WriteDAC (USHORT dl, USHORT ah, USHORT al, USHORT dh)
+UCHAR
+SiS_GetModePtr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-	USHORT temp;
-	USHORT bh, bl;
+   UCHAR index;
 
-	bh = ah;
-	bl = al;
-	if (dl != 0) {
-		temp = bh;
-		bh = dh;
-		dh = temp;
-		if (dl == 1) {
-			temp = bl;
-			bl = dh;
-			dh = temp;
-		} else {
-			temp = bl;
-			bl = bh;
-			bh = temp;
-		}
+   if(ModeNo<=0x13) {
+     	index = SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
+   } else {
+     	if(SiS_ModeType <= 0x02) index=0x1B;    /* 02 -> ModeEGA  */
+     	else index=0x0F;
+   }
+   return index;
+}
+
+/* TW: Checked against 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */
+void
+SiS_SetSeqRegs(UCHAR *ROMAddr,USHORT StandTableIndex)
+{
+   UCHAR SRdata;
+   USHORT i;
+
+   SiS_SetReg1(SiS_P3c4,0x00,0x03);           		/* Set SR0  */
+
+   SRdata=SiS_StandTable[StandTableIndex].SR[0];
+
+   if(SiS_VBType & VB_SIS301BLV302BLV) {
+      	if(SiS_VBInfo & SetCRT2ToLCDA) {
+        	SRdata |= 0x01;
+        }
+   }
+   if(SiS_IF_DEF_LVDS == 1) {
+     if(SiS_IF_DEF_CH70xx != 0) {
+       if(SiS_VBInfo & SetCRT2ToTV) {
+         if(SiS_VBInfo & SetInSlaveMode) {
+           SRdata |= 0x01;        			/* 8 dot clock  */
+         }
+       }
+     }
+     if(SiS_VBInfo & SetCRT2ToLCD) {
+       if(SiS_VBInfo & SetInSlaveMode) {
+         /* TW: wdr/300: if(SiS_LCDInfo & LCDNonExpanding) { */
+         SRdata |= 0x01;          			/* 8 dot clock  */
+       }
+     }
+   }
+
+   SRdata |= 0x20;                			/* screen off  */
+
+   SiS_SetReg1(SiS_P3c4,0x01,SRdata);
+
+   for(i=02;i<=04;i++) {
+       	SRdata=SiS_StandTable[StandTableIndex].SR[i-1];
+     	SiS_SetReg1(SiS_P3c4,i,SRdata);
+   }
+}
+
+/* Checked against 650/301LV and 65/LVDS 1.10.07 BIOS */
+void
+SiS_SetMiscRegs(UCHAR *ROMAddr,USHORT StandTableIndex)
+{
+   UCHAR Miscdata;
+
+   Miscdata = SiS_StandTable[StandTableIndex].MISC;
+
+   if(SiS_VBType & VB_SIS301BLV302BLV) {
+      if(SiS_VBInfo & SetCRT2ToLCDA) {
+        Miscdata |= 0x0C;
+      }
+    }
+
+   SiS_SetReg3(SiS_P3c2,Miscdata);
+}
+
+/* Checked against 650/LVDS (1.10.07) and 650/301LV BIOS (630 code still there!) */
+void
+SiS_SetCRTCRegs(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                USHORT StandTableIndex)
+{
+  UCHAR CRTCdata;
+  USHORT i;
+
+  SiS_SetRegAND(SiS_P3d4,0x11,0x7f);                       /* Unlock CRTC */
+
+  for(i=0;i<=0x18;i++) {
+     CRTCdata=SiS_StandTable[StandTableIndex].CRTC[i];
+     SiS_SetReg1(SiS_P3d4,i,CRTCdata);                     /* Set CRTC(3d4) */
+  }
+  if( ( (HwDeviceExtension->jChipType == SIS_630) ||
+        (HwDeviceExtension->jChipType == SIS_730) )  &&
+      (HwDeviceExtension->jChipRevision >= 0x30) ) {       /* for 630S0 */
+    if(SiS_VBInfo & SetInSlaveMode) {
+      if(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+        SiS_SetReg1(SiS_P3d4,0x18,0xFE);
+      }
+    }
+  }
+}
+
+/* TW: Checked against 650/LVDS (1.10.07), 650/301LV and 630/301B BIOS */
+void
+SiS_SetATTRegs(UCHAR *ROMAddr,USHORT StandTableIndex,USHORT ModeNo,
+               PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   UCHAR ARdata;
+   USHORT i;
+
+   for(i=0;i<=0x13;i++) {
+    ARdata = SiS_StandTable[StandTableIndex].ATTR[i];
+#if 0
+    if((i <= 0x0f) || (i == 0x11)) {
+        if(ds:489 & 0x08) {
+	   continue;
+        }
+    }
+#endif
+    if(i == 0x13) {
+      if(SiS_VBType & VB_SIS301BLV302BLV) {
+        if(SiS_VBInfo & SetCRT2ToLCDA)  ARdata=0;
+      }
+      if(SiS_IF_DEF_LVDS == 1) {
+        if(SiS_IF_DEF_CH70xx != 0) {
+          if(SiS_VBInfo & SetCRT2ToTV) {
+            if(SiS_VBInfo & SetInSlaveMode) ARdata=0;
+          }
+        }
+      }
+      if(SiS_VBInfo & SetCRT2ToLCD) {
+        if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 1)) {
+	  /* TW: From 650/LVDS 1.10.07, 1.10a */
+	  ARdata = 0;
+	} else {
+          if(SiS_VBInfo & SetInSlaveMode) {
+	     /* TW: wdr: if(SiS_LCDInfo & LCDNonExpanding) { */
+	     ARdata=0;
+          }
+	}
+      }
+    }
+    SiS_GetReg2(SiS_P3da);                              /* reset 3da  */
+    SiS_SetReg3(SiS_P3c0,i);                            /* set index  */
+    SiS_SetReg3(SiS_P3c0,ARdata);                       /* set data   */
+   }
+   SiS_GetReg2(SiS_P3da);                                /* reset 3da  */
+   SiS_SetReg3(SiS_P3c0,0x14);                           /* set index  */
+   SiS_SetReg3(SiS_P3c0,0x00);                           /* set data   */
+
+   SiS_GetReg2(SiS_P3da);                                /* Enable Attribute  */
+   SiS_SetReg3(SiS_P3c0,0x20);
+}
+
+/* TW: Checked against 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */
+void
+SiS_SetGRCRegs(UCHAR *ROMAddr,USHORT StandTableIndex)
+{
+   UCHAR GRdata;
+   USHORT i;
+
+   for(i=0;i<=0x08;i++) {
+     GRdata = SiS_StandTable[StandTableIndex].GRC[i]; 	  /* Get GR from file */
+     SiS_SetReg1(SiS_P3ce,i,GRdata);                      /* Set GR(3ce) */
+   }
+
+   if(SiS_ModeType > ModeVGA) {
+     SiS_SetRegAND(SiS_P3ce,0x05,0xBF);			  /* 256 color disable */
+   }
+}
+
+/* TW: Checked against 650/LVDS (1.10.07, 1.10a), 650/301LV and 630/301B BIOS */
+void
+SiS_ClearExt1Regs(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT i;
+
+  for(i=0x0A;i<=0x0E;i++) SiS_SetReg1(SiS_P3c4,i,0x00);      /* Clear SR0A-SR0E */
+
+  /* TW: New from 650/LVDS/301LV BIOSes: */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     SiS_SetRegAND(SiS_P3c4,0x37,0xFE);
+  }
+}
+
+/* TW: Checked against 650/LVDS (1.10.07) and 650/301LV BIOS */
+void
+SiS_SetSync(UCHAR *ROMAddr,USHORT RefreshRateTableIndex)
+{
+  USHORT sync;
+  USHORT temp;
+
+  sync = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
+
+  sync &= 0xC0;
+  temp = 0x2F | sync;
+  SiS_SetReg3(SiS_P3c2,temp);                                 /* Set Misc(3c2) */
+}
+
+/* TW: Checked against 650/LVDS (1.10.07) and 650/301LV BIOS */
+void
+SiS_SetCRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex,
+		PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  UCHAR  index;
+  USHORT temp,tempah,i,modeflag,j;
+  USHORT ResInfo,DisplayType;
+  SiS_LCDACRT1DataStruct *LCDACRT1Ptr=NULL;
+
+  SiS_SetRegAND(SiS_P3d4,0x11,0x7f);		/*unlock cr0-7  */
+
+  if(ModeNo<=0x13) {
+        modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+        modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+
+  if((SiS_VBType & (VB_SIS302B | VB_SIS302LV))
+                        && (SiS_VBInfo & SetCRT2ToLCDA)) {
+
+     /* 302B LCDA - TW: Not done in any BIOS version */
+
+     temp = SiS_GetLCDACRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,
+                       RefreshRateTableIndex,&ResInfo,&DisplayType);
+  
+     switch(DisplayType) {
+      case 0 : LCDACRT1Ptr = SiS_LCDACRT1800x600_1;           break;
+      case 1 : LCDACRT1Ptr = SiS_LCDACRT11024x768_1;          break;
+      case 2 : LCDACRT1Ptr = SiS_LCDACRT11280x1024_1;         break;
+      case 3 : LCDACRT1Ptr = SiS_LCDACRT1800x600_1_H;         break;
+      case 4 : LCDACRT1Ptr = SiS_LCDACRT11024x768_1_H;        break;
+      case 5 : LCDACRT1Ptr = SiS_LCDACRT11280x1024_1_H;       break;
+      case 6 : LCDACRT1Ptr = SiS_LCDACRT1800x600_2;           break;
+      case 7 : LCDACRT1Ptr = SiS_LCDACRT11024x768_2;          break;
+      case 8 : LCDACRT1Ptr = SiS_LCDACRT11280x1024_2;         break;
+      case 9 : LCDACRT1Ptr = SiS_LCDACRT1800x600_2_H;         break;
+      case 10: LCDACRT1Ptr = SiS_LCDACRT11024x768_2_H;        break;
+      case 11: LCDACRT1Ptr = SiS_LCDACRT11280x1024_2_H;       break;
+     }
+
+     tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
+     SiS_SetReg1(SiS_P3d4,0x00,tempah);
+     for(i=0x01,j=1;i<=0x07;i++,j++){
+       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+       SiS_SetReg1(SiS_P3d4,i,tempah);
+     }
+     for(i=0x10,j=8;i<=0x12;i++,j++){
+       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+       SiS_SetReg1(SiS_P3d4,i,tempah);
+     }
+     for(i=0x15,j=11;i<=0x16;i++,j++){
+       tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
+       SiS_SetReg1(SiS_P3d4,i,tempah);
+     }
+     for(i=0x0A,j=13;i<=0x0C;i++,j++){
+       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+       SiS_SetReg1(SiS_P3c4,i,tempah);
+     }
+  
+     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
+     tempah &= 0x0E0;
+     SiS_SetReg1(SiS_P3c4,0x0E,tempah);
+
+     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
+     tempah &= 0x01;
+     tempah <<= 5;
+     if(modeflag & DoubleScanMode)  tempah |= 0x080;
+
+     SiS_SetRegANDOR(SiS_P3d4,0x09,~0x020,tempah);
+     if(SiS_ModeType > 0x03) SiS_SetReg1(SiS_P3d4,0x14,0x4F);
+
+  } else {
+
+     /* LVDS, 301, 301B, 301LV, 302LV, (302B non-LCDA) */
+
+     index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;  	/* Get index */
+     if(HwDeviceExtension->jChipType < SIS_315H) {
+        index &= 0x3F;
+     }
+
+     for(i=0,j=0;i<=07;i++,j++) {
+       tempah=SiS_CRT1Table[index].CR[i];
+       SiS_SetReg1(SiS_P3d4,j,tempah);
+     }
+     for(j=0x10;i<=10;i++,j++) {
+       tempah=SiS_CRT1Table[index].CR[i];
+       SiS_SetReg1(SiS_P3d4,j,tempah);
+     }
+     for(j=0x15;i<=12;i++,j++) {
+       tempah=SiS_CRT1Table[index].CR[i];
+       SiS_SetReg1(SiS_P3d4,j,tempah);
+     }
+     for(j=0x0A;i<=15;i++,j++) {
+       tempah=SiS_CRT1Table[index].CR[i];
+       SiS_SetReg1(SiS_P3c4,j,tempah);
+     }
+
+     tempah = SiS_CRT1Table[index].CR[16];
+     tempah &= 0xE0;
+     SiS_SetReg1(SiS_P3c4,0x0E,tempah);
+
+     tempah = SiS_CRT1Table[index].CR[16];
+     tempah &= 0x01;
+     tempah <<= 5;
+     if(modeflag & DoubleScanMode)  tempah |= 0x80;
+     SiS_SetRegANDOR(SiS_P3d4,0x09,0xDF,tempah);
+
+     if(SiS_ModeType > 0x03) SiS_SetReg1(SiS_P3d4,0x14,0x4F);
+  }
+}
+
+/* TW: Set offset and pitch - partly overruled by SetPitch() in XF86 */
+/* TW: Checked against 650/LVDS (1.10.07), 650/301LV and 315 BIOS */
+void
+SiS_SetCRT1Offset(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                  USHORT RefreshRateTableIndex,
+		  PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   USHORT temp, DisplayUnit, infoflag;
+
+   infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+
+   DisplayUnit = SiS_GetOffset(ROMAddr,ModeNo,ModeIdIndex,
+                     RefreshRateTableIndex,HwDeviceExtension);
+
+   temp = (DisplayUnit >> 8) & 0x0f;
+   SiS_SetRegANDOR(SiS_P3c4,0x0E,0xF0,temp);
+
+   temp = DisplayUnit & 0xFF;
+   SiS_SetReg1(SiS_P3d4,0x13,temp);
+
+   if(infoflag & InterlaceMode) DisplayUnit >>= 1;
+
+   DisplayUnit <<= 5;
+   temp = (DisplayUnit & 0xff00) >> 8;
+   if (DisplayUnit & 0xff) temp++;
+   temp++;
+   SiS_SetReg1(SiS_P3c4,0x10,temp);
+}
+
+/* TW: New from 650/LVDS 1.10.07, 630/301B and 630/LVDS BIOS */
+void
+SiS_ResetCRT1VCLK(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   USHORT index;
+
+   /* TW: We only need to do this if Panel Link is to be
+    *     initialized, thus on 630/LVDS/301B, and 650/LVDS
+    */
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+       if (SiS_IF_DEF_LVDS == 0)  return;
+   } else {
+       if( (SiS_IF_DEF_LVDS == 0) &&
+           (!(SiS_VBType & VB_SIS301BLV302BLV)) ) {
+	   return;
+      }
+   }
+
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+   	SiS_SetRegANDOR(SiS_P3c4,0x31,0xCF,0x20);
+   } else {
+   	SiS_SetReg1(SiS_P3c4,0x31,0x20);
+   }
+   index = 1;
+   SiS_SetReg1(SiS_P3c4,0x2B,SiS_VCLKData[index].SR2B);
+   SiS_SetReg1(SiS_P3c4,0x2C,SiS_VCLKData[index].SR2C);
+   SiS_SetReg1(SiS_P3c4,0x2D,0x80);
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+   	SiS_SetRegANDOR(SiS_P3c4,0x31,0xcf,0x10);
+   } else {
+   	SiS_SetReg1(SiS_P3c4,0x31,0x10);
+   }
+   index = 0;
+   SiS_SetReg1(SiS_P3c4,0x2B,SiS_VCLKData[index].SR2B);
+   SiS_SetReg1(SiS_P3c4,0x2C,SiS_VCLKData[index].SR2C);
+   SiS_SetReg1(SiS_P3c4,0x2D,0x80);
+}
+
+/* TW: Checked against 650/LVDS, 650/301LV, 315, 630/301B, 630/LVDS BIOS */
+void
+SiS_SetCRT1VCLK(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                PSIS_HW_DEVICE_INFO HwDeviceExtension,
+		USHORT RefreshRateTableIndex)
+{
+  USHORT  index;
+
+#if 0	/* TW: Wrong. 650/301LV uses same table for LCDA and CRT1 */
+  if( (SiS_VBType & VB_SIS301BLV302BLV)
+                       && (SiS_VBInfo & SetCRT2ToLCDA) ){
+
+        /* TW: For 302B/302LV LCDA */
+
+    	index = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
+	                RefreshRateTableIndex,HwDeviceExtension);
+
+    	SiS_SetRegAND(SiS_P3c4,0x31,0xCF);
+
+    	SiS_SetReg1(SiS_P3c4,0x2B,SiS_VBVCLKData[index].Part4_A);
+    	SiS_SetReg1(SiS_P3c4,0x2C,SiS_VBVCLKData[index].Part4_B);
+
+    	if(HwDeviceExtension->jChipType >= SIS_315H) {
+		SiS_SetReg1(SiS_P3c4,0x2D,0x01);
+   	} else {
+    		SiS_SetReg1(SiS_P3c4,0x2D,0x80);
+    	}
+
+  } else {
+#endif
+
+        index = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
+	                  RefreshRateTableIndex,HwDeviceExtension);
+
+#if 0   /* TW: All BIOSes use GetVCLK2Ptr instead */
+    	index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+    	index &= 0x3F;
+#endif
+
+	if(HwDeviceExtension->jChipType >= SIS_315H) {
+	    SiS_SetRegAND(SiS_P3c4,0x31,0xCF);
+	} else {
+	    SiS_SetReg1(SiS_P3c4,0x31,0x00);
 	}
-	SiS_SetReg3 (SiS_P3c9, (USHORT) dh);
-	SiS_SetReg3 (SiS_P3c9, (USHORT) bh);
-	SiS_SetReg3 (SiS_P3c9, (USHORT) bl);
-}
 
-void
-SiS_ClearBuffer (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo)
-{
-	PVOID VideoMemoryAddress =
-	    (PVOID) HwDeviceExtension->pjVideoMemoryAddress;
-	ULONG AdapterMemorySize = (ULONG) HwDeviceExtension->ulVideoMemorySize;
-	PUSHORT pBuffer;
-	int i;
-
-	if (SiS_ModeType >= ModeEGA) {
-		if (ModeNo > 0x13) {
-			SiS_SetMemory (VideoMemoryAddress, AdapterMemorySize,
-				       0);
-		} else {
-			pBuffer = VideoMemoryAddress;
-			for (i = 0; i < 0x4000; i++)
-				pBuffer[i] = 0x0000;
-		}
+    	SiS_SetReg1(SiS_P3c4,0x2B,SiS_VCLKData[index].SR2B);
+    	SiS_SetReg1(SiS_P3c4,0x2C,SiS_VCLKData[index].SR2C);
+
+    	if(HwDeviceExtension->jChipType >= SIS_315H) {
+	    SiS_SetReg1(SiS_P3c4,0x2D,0x01);
 	} else {
-		pBuffer = VideoMemoryAddress;
-		if (SiS_ModeType == ModeCGA) {
-			for (i = 0; i < 0x4000; i++)
-				pBuffer[i] = 0x0720;
-		} else {
-			for (i = 0; i < 0x4000; i++)
-				pBuffer[i] = 0x0000;
-		}
+      	    SiS_SetReg1(SiS_P3c4,0x2D,0x80);
+        }
+#if 0
+  }
+#endif
+}
+
+#if 0  /* TW: Not used */
+void
+SiS_IsLowResolution(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT ModeFlag;
+
+  SiS_SetRegAND(SiS_P3c4,0x0F,0x7F);
+
+  if(ModeNo > 0x13) {
+    ModeFlag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
+      SiS_SetRegOR(SiS_P3c4,0x0F,0x80);
+      SiS_SetRegAND(SiS_P3c4,0x01,0xF7);
+    }
+  }
+}
+#endif
+
+/* TW: Checked against 630/LVDS, 650/LVDS and 315 BIOS */
+void
+SiS_SetCRT1ModeRegs(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                    USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
+{
+  USHORT data,data2,data3;
+  USHORT infoflag=0,modeflag;
+  USHORT resindex,xres;
+
+  if(ModeNo > 0x13) {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  } else {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  }
+
+  SiS_SetRegAND(SiS_P3c4,0x1F,0x3F); 		/* DAC pedestal */
+
+  if(ModeNo > 0x13) data = infoflag;
+  else data = 0;
+
+  data2 = SiS_GetReg1(SiS_P3c4,0x06) & 0xC0;  	/* TW: Preserve Xv display mode (DCLK/TCLK) ! */
+  if(ModeNo > 0x13) {
+    if(SiS_ModeType > 0x02) {
+       data2 |= 0x02;
+       data3 = (SiS_ModeType - ModeVGA) << 2;
+       data2 |= data3;
+    }
+  }
+  if(data & InterlaceMode) data2 |= 0x20;
+  SiS_SetReg1(SiS_P3c4,0x06,data2);
+
+  resindex = SiS_GetResInfo(ROMAddr,ModeNo,ModeIdIndex);
+  if(ModeNo <= 0x13) {
+      	xres = SiS_StResInfo[resindex].HTotal;
+  } else {
+      	xres = SiS_ModeResInfo[resindex].HTotal;
+  }
+
+  data = 0x0000;
+  if(infoflag & InterlaceMode) {
+      if(xres == 1024) data = 0x0035;
+      else data = 0x0048;
+  }
+  data2 = data & 0x00FF;
+  SiS_SetReg1(SiS_P3d4,0x19,data2);
+  data2 = (data & 0xFF00) >> 8;
+  SiS_SetRegANDOR(SiS_P3d4,0x1a,0xFC,data2);
+
+  if(modeflag & HalfDCLK) {
+     SiS_SetRegOR(SiS_P3c4,0x01,0x08);
+  }
+
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+     if(modeflag & LineCompareOff) {
+        SiS_SetRegANDOR(SiS_P3c4,0x0F,0xB7,0x08);
+     } else {
+        SiS_SetRegAND(SiS_P3c4,0x0F,0xB7);
+     }
+     /* 630 BIOS does something for mode 0x12 here */
+  } else {
+     if(modeflag & LineCompareOff) {
+        SiS_SetRegANDOR(SiS_P3c4,0x0F,0xB7,0x08);
+     } else {
+        SiS_SetRegAND(SiS_P3c4,0x0F,0xB7);
+     }
+  }
+
+  if(SiS_ModeType == ModeEGA) {
+     if(ModeNo > 0x13) {
+  	SiS_SetRegOR(SiS_P3c4,0x0F,0x40);
+     }
+  }
+
+  /* TW: 315 BIOS sets SR17 here (0x18bf) */
+#ifdef SIS315H
+  if(HwDeviceExtension->jChipType == SIS_315PRO) {
+      data = SiS_Get310DRAMType(ROMAddr,HwDeviceExtension);
+      data = SiS_SR15[2][data];
+      if(SiS_ModeType == ModeText) {
+          data &= 0xc7;
+      } else {
+          data2 = SiS_GetOffset(ROMAddr,ModeNo,ModeIdIndex,
+                                RefreshRateTableIndex,HwDeviceExtension);
+	  data2 >>= 1;
+	  if(infoflag & InterlaceMode) data2 >>= 1;
+	  data3 = SiS_GetColorDepth(ROMAddr,ModeNo,ModeIdIndex);
+	  data3 >>= 1;
+	  if(data3 == 0) data3++;
+	  data2 /= data3;
+	  if(data2 >= 0x50) {
+	      data &= 0x0f;
+	      data |= 0x50;
+	  }
+      }
+      SiS_SetReg1(SiS_P3c4,0x17,data);
+  }
+#endif
+
+  data = 0x60;
+  if(SiS_ModeType != ModeText) {
+      data = data ^ 0x60;
+      if(SiS_ModeType != ModeEGA) {
+        data = data ^ 0xA0;
+      }
+  }
+  SiS_SetRegANDOR(SiS_P3c4,0x21,0x1F,data);
+
+  SiS_SetVCLKState(ROMAddr,HwDeviceExtension,ModeNo,RefreshRateTableIndex,ModeIdIndex);
+
+#ifdef SIS315H
+  /* TW: New */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+    if (SiS_GetReg1(SiS_P3d4,0x31) & 0x40) {
+        SiS_SetReg1(SiS_P3d4,0x52,0x2c);
+    } else {
+        SiS_SetReg1(SiS_P3d4,0x52,0x6c);
+    }
+  }
+#endif
+}
+
+/* TW: Checked against 315, 650/LVDS, 650/301LV, 630/301B and 630/LVDS BIOS */
+void
+SiS_SetVCLKState(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                 USHORT ModeNo,USHORT RefreshRateTableIndex,
+                 USHORT ModeIdIndex)
+{
+  USHORT data, data2=0;
+  USHORT VCLK, index=0;
+
+  if (ModeNo <= 0x13) VCLK = 0;
+  else {
+     index = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
+	               RefreshRateTableIndex,HwDeviceExtension);
+     VCLK = SiS_VCLKData[index].CLOCK;
+  }
+
+  if(HwDeviceExtension->jChipType < SIS_315H) {		/* 300 series */
+
+    data2 = 0x00;
+    if(VCLK > 150) data2 |= 0x80;
+    SiS_SetRegANDOR(SiS_P3c4,0x07,0x7B,data2); 	/* DAC speed */
+
+    data2 = 0x00;
+    if(VCLK >= 150) data2 |= 0x08;       	/* VCLK > 150 */
+    SiS_SetRegANDOR(SiS_P3c4,0x32,0xF7,data2);
+
+  } else { 						/* 310/325 series */
+
+    data = SiS_GetReg1(SiS_P3c4,0x32);
+    data &= 0xf3;
+    if(VCLK >= 166) data |= 0x0c;         	/* TW: Was 200; is 166 in 650 and 315 BIOSes */
+    SiS_SetReg1(SiS_P3c4,0x32,data);
+
+    if(VCLK >= 166) {				/* TW: Was 200, is 166 in 650 and 315 BIOSes */
+       SiS_SetRegAND(SiS_P3c4,0x1f,0xe7);
+    }
+#if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */
+    data = SiS_GetReg1(SiS_P3c4,0x1F);	  	/* DAC pedestal */
+    data &= 0xE7;
+    if(VCLK<200) data |= 0x10;
+    SiS_SetReg1(SiS_P3c4,0x1F,data);	  	/* DAC pedestal */
+#endif
+  }
+
+  data2 = 0x03;
+  if((VCLK >= 135) && (VCLK < 160)) data2 = 0x02;
+  if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01;
+  if(VCLK >= 260) data2 = 0x00;
+  /* disable 24bit palette RAM gamma correction  */
+  if(HwDeviceExtension->jChipType == SIS_540) {
+    	if((VCLK == 203) || (VCLK < 234)) data2 = 0x02;
+  }
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+      SiS_SetRegANDOR(SiS_P3c4,0x07,0xFC,data2);  	/* DAC speed */
+  } else {
+      /* TW: This is done in 650/LVDS/301LV BIOSes; Not in 315 BIOS */
+      if(ModeNo > 13) data2 &= 0xfc;
+      SiS_SetRegANDOR(SiS_P3c4,0x07,0xF8,data2);  	/* DAC speed */
+  }
+}
+
+void
+SiS_LoadDAC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+   USHORT data,data2;
+   USHORT time,i,j,k;
+   USHORT m,n,o;
+   USHORT si,di,bx,dl;
+   USHORT al,ah,dh;
+   USHORT *table=NULL;
+#if 0
+   USHORT tempah,tempch,tempcl,tempdh,tempal,tempbx;
+#endif
+
+   if (ModeNo<=0x13)
+        data = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   else
+        data = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+#if 0
+   if(!(ds:489 & 0x08)) {
+#endif
+
+	data &= DACInfoFlag;
+	time = 64;
+	if(data == 0x00) table = SiS_MDA_DAC;
+	if(data == 0x08) table = SiS_CGA_DAC;
+	if(data == 0x10) table = SiS_EGA_DAC;
+	if(data == 0x18) {
+	   time = 256;
+	   table = SiS_VGA_DAC;
+	}
+	if(time == 256) j = 16;
+	else j = time;
+
+	SiS_SetReg3(SiS_P3c6,0xFF);
+	SiS_SetReg3(SiS_P3c8,0x00);
+
+	for(i=0; i<j; i++) {
+	   data = table[i];
+	   for(k=0; k<3; k++) {
+		data2 = 0;
+		if(data & 0x01) data2 = 0x2A;
+		if(data & 0x02) data2 += 0x15;
+		SiS_SetReg3(SiS_P3c9,data2);
+		data >>= 2;
+	   }
 	}
-}
 
-void
-SiS_DisplayOn (void)
+	if(time == 256) {
+	   for(i=16; i<32; i++) {
+		data = table[i];
+		for(k=0; k<3; k++) SiS_SetReg3(SiS_P3c9,data);
+	   }
+	   si = 32;
+	   for(m=0; m<9; m++) {
+	      di = si;
+	      bx = si+0x04;
+	      dl = 0;
+	      for(n=0; n<3; n++) {
+		 for(o=0; o<5; o++) {
+		    dh = table[si];
+		    ah = table[di];
+		    al = table[bx];
+		    si++;
+		    SiS_WriteDAC(dl,ah,al,dh);
+		 }         /* for 5 */
+		 si = si - 2;
+		 for(o=0; o<3; o++) {
+		    dh = table[bx];
+		    ah = table[di];
+		    al = table[si];
+		    si--;
+		    SiS_WriteDAC(dl,ah,al,dh);
+		 }         /* for 3 */
+		 dl++;
+	      }            /* for 3 */
+	      si = si + 5;
+	   }               /* for 9 */
+	}
+#if 0
+    }  /* ds:489 & 0x08 */
+#endif
+
+#if 0
+    if((!(ds:489 & 0x08)) && (ds:489 & 0x06)) {
+           tempbx = 0;
+	   for(i=0; i< 256; i++) {
+               SiS_SetReg3(SiS_P3c8-1,tempbx);    	/* 7f87 */
+               tempah = SiS_GetReg3(SiS_P3c8+1);  	/* 7f83 */
+	       tempch = SiS_GetReg3(SiS_P3c8+1);
+	       tempcl = SiS_GetReg3(SiS_P3c8+1);
+	       tempdh = tempah;
+	       tempal = 0x4d * tempdh;          	/* 7fb8 */
+	       tempbx += tempal;
+	       tempal = 0x97 * tempch;
+	       tempbx += tempal;
+	       tempal = 0x1c * tempcl;
+	       tempbx += tempal;
+	       if((tempbx & 0x00ff) > 0x80) tempbx += 0x100;
+	       tempdh = (tempbx & 0x00ff) >> 8;
+	       tempch = tempdh;
+	       tempcl = tempdh;
+	       SiS_SetReg3(SiS_P3c8,(tempbx & 0xff));  	/* 7f7c */
+	       SiS_SetReg3(SiS_P3c8+1,tempdh);          /* 7f92 */
+	       SiS_SetReg3(SiS_P3c8+1,tempch);
+	       SiS_SetReg3(SiS_P3c8+1,tempcl);
+           }
+    }
+#endif
+}
+
+void
+SiS_WriteDAC(USHORT dl, USHORT ah, USHORT al, USHORT dh)
+{
+  USHORT temp;
+  USHORT bh,bl;
+
+  bh=ah;
+  bl=al;
+  if(dl!=0) {
+    temp=bh;
+    bh=dh;
+    dh=temp;
+    if(dl==1) {
+       temp=bl;
+       bl=dh;
+       dh=temp;
+    } else {
+       temp=bl;
+       bl=bh;
+       bh=temp;
+    }
+  }
+  SiS_SetReg3(SiS_P3c9,(USHORT)dh);
+  SiS_SetReg3(SiS_P3c9,(USHORT)bh);
+  SiS_SetReg3(SiS_P3c9,(USHORT)bl);
+}
+
+ULONG
+GetDRAMSize(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  ULONG   AdapterMemorySize=0;
+#ifdef SIS315H
+  USHORT  counter;
+#endif
+  
+#ifdef SIS315H
+  if ((HwDeviceExtension->jChipType == SIS_315H) ||
+      (HwDeviceExtension->jChipType == SIS_315PRO)) {
+    	counter = SiS_GetReg1(SiS_P3c4,0x14) & 0xF0;
+    	counter >>= 4;
+    	AdapterMemorySize= 1 << counter;
+    	AdapterMemorySize *= 1024*1024;
+  } else if((HwDeviceExtension->jChipType == SIS_550) ||
+            (HwDeviceExtension->jChipType == SIS_640) ||
+            (HwDeviceExtension->jChipType == SIS_740) ||
+            (HwDeviceExtension->jChipType == SIS_650)) {
+      		counter = SiS_GetReg1(SiS_P3c4,0x14) & 0x3F;
+      		counter++;
+      		AdapterMemorySize = counter * 4;
+      		AdapterMemorySize *= 1024*1024;
+  }
+#endif
+
+#ifdef SIS300
+  if ((HwDeviceExtension->jChipType==SIS_300) ||
+      (HwDeviceExtension->jChipType==SIS_540) ||
+      (HwDeviceExtension->jChipType==SIS_630) ||
+      (HwDeviceExtension->jChipType==SIS_730)) {
+      	AdapterMemorySize = SiS_GetReg1(SiS_P3c4,0x14);
+      	AdapterMemorySize = AdapterMemorySize&0x3F;
+      	AdapterMemorySize++;
+      	AdapterMemorySize *= 1024*1024;
+  }
+#endif
+
+  return AdapterMemorySize;
+}
+
+void
+SiS_ClearBuffer(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+{
+  PVOID   VideoMemoryAddress = (PVOID)HwDeviceExtension->pjVideoMemoryAddress;
+  ULONG   AdapterMemorySize  = (ULONG)HwDeviceExtension->ulVideoMemorySize;
+  PUSHORT pBuffer;
+  int i;
+
+  if (SiS_ModeType>=ModeEGA) {
+    if (ModeNo>0x13) {
+      AdapterMemorySize = GetDRAMSize(HwDeviceExtension);
+      SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0);
+    } else {
+      pBuffer = VideoMemoryAddress;
+      for(i=0; i<0x4000; i++)
+         pBuffer[i] = 0x0000;
+    }
+  } else {
+    pBuffer = VideoMemoryAddress;
+    if (SiS_ModeType < ModeCGA) {
+      for(i=0; i<0x4000; i++)
+         pBuffer[i] = 0x0720;
+    } else {
+      SiS_SetMemory(VideoMemoryAddress,0x8000,0);
+    }
+  }
+}
+
+void
+SiS_DisplayOn(void)
 {
-
-	SiS_SetRegANDOR (SiS_P3c4, 0x01, 0xDF, 0x00);
+   SiS_SetRegANDOR(SiS_P3c4,0x01,0xDF,0x00);
 }
 
 void
-SiS_DisplayOff (void)
+SiS_DisplayOff(void)
 {
-
-	SiS_SetRegANDOR (SiS_P3c4, 0x01, 0xDF, 0x20);
+   SiS_SetRegANDOR(SiS_P3c4,0x01,0xDF,0x20);
 }
 
+
 /* ========================================== */
 /*  SR CRTC GR */
 void
-SiS_SetReg1 (USHORT port, USHORT index, USHORT data)
+SiS_SetReg1(USHORT port, USHORT index, USHORT data)
 {
-	OutPortByte (port, index);
-	OutPortByte (port + 1, data);
-
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      
-	   mov      ax, index                     
-	   mov      bx, data                      
-	   out      dx, al
-	   mov      ax, bx
-	   inc      dx
-	   out      dx, al
-	   }
-	 */
-
+   OutPortByte(port,index);
+   OutPortByte(port+1,data);
 }
 
 /* ========================================== */
 /*  AR(3C0) */
 void
-SiS_SetReg2 (USHORT port, USHORT index, USHORT data)
+SiS_SetReg2(USHORT port, USHORT index, USHORT data)
 {
-
-	InPortByte (port + 0x3da - 0x3c0);
-	OutPortByte (SiS_P3c0, index);
-	OutPortByte (SiS_P3c0, data);
-	OutPortByte (SiS_P3c0, 0x20);
-
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      
-	   mov      cx, index                     
-	   mov      bx, data                      
-
-	   add      dx, 3dah-3c0h
-	   in       al, dx
-
-	   mov      ax, cx
-	   mov      dx, 3c0h
-	   out      dx, al
-	   mov      ax, bx
-	   out      dx, al
-
-	   mov      ax, 20h
-	   out      dx, al
-	   }
-	 */
-
+   InPortByte(port+0x3da-0x3c0);
+   OutPortByte(SiS_P3c0,index);
+   OutPortByte(SiS_P3c0,data);
+   OutPortByte(SiS_P3c0,0x20);
 }
 
-/* ========================================== */
 void
-SiS_SetReg3 (USHORT port, USHORT data)
+SiS_SetReg3(USHORT port, USHORT data)
 {
-
-	OutPortByte (port, data);
-
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      
-	   mov      ax, data                      
-	   out      dx, al
-
-	   }
-	 */
-
+   OutPortByte(port,data);
 }
 
-/* ========================================== */
 void
-SiS_SetReg4 (USHORT port, ULONG data)
+SiS_SetReg4(USHORT port, ULONG data)
 {
-
-	OutPortLong (port, data);
-
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      ;; port
-	   mov      eax, data                      ;; data
-	   out      dx, eax
-
-	   }
-	 */
+   OutPortLong(port,data);
 }
 
-/* ========================================= */
-UCHAR SiS_GetReg1 (USHORT port, USHORT index)
+UCHAR SiS_GetReg1(USHORT port, USHORT index)
 {
-	UCHAR data;
+   UCHAR   data;
 
-	OutPortByte (port, index);
-	data = InPortByte (port + 1);
+   OutPortByte(port,index);
+   data = InPortByte(port+1);
 
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      ;; port
-	   mov      ax, index                     ;; index
-
-	   out      dx, al
-	   mov      ax, bx
-	   inc      dx
-	   xor      eax, eax
-	   in       al, dx
-	   mov      data, al
-	   }
-	 */
-	return (data);
+   return(data);
 }
 
-/* ========================================== */
-UCHAR SiS_GetReg2 (USHORT port)
+UCHAR
+SiS_GetReg2(USHORT port)
 {
-	UCHAR data;
+   UCHAR   data;
 
-	data = InPortByte (port);
+   data= InPortByte(port);
 
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      ;; port
-	   xor      eax, eax
-	   in       al, dx
-	   mov      data, al
-	   }
-	 */
-	return (data);
+   return(data);
 }
 
-/* ========================================== */
-ULONG SiS_GetReg3 (USHORT port)
+ULONG
+SiS_GetReg3(USHORT port)
 {
-	ULONG data;
+   ULONG   data;
 
-	data = InPortLong (port);
+   data = InPortLong(port);
 
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      ;; port
-	   xor      eax, eax
-	   in       eax, dx
-	   mov      data, eax
-	   }
-	 */
-	return (data);
+   return(data);
 }
 
-/* ========================================== */
 void
-SiS_ClearDAC (ULONG port)
+SiS_ClearDAC(ULONG port)
 {
-	int i;
+   int i;
 
-	OutPortByte (port, 0);
-	port++;
-	for (i = 0; i < 256 * 3; i++) {
-		OutPortByte (port, 0);
-	}
+   OutPortByte(port, 0);
+   port++;
+   for (i=0; i<256*3; i++) {
+      OutPortByte(port, 0);
+   }
 
 }
-
-/*========================================== */
-
+/* ========================================== */
+#if 0  /* TW: Not done in any BIOS */
 void
-SiS_SetInterlace (ULONG ROMAddr, USHORT ModeNo, USHORT RefreshRateTableIndex)
+SiS_SetInterlace(UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex)
 {
-	ULONG Temp;
-	USHORT data, Temp2;
+  ULONG Temp;
+  USHORT data,Temp2;
 
-	Temp = (ULONG) SiS_GetReg1 (SiS_P3d4, 0x01);
-	Temp++;
-	Temp = Temp * 8;
+  if (ModeNo<=0x13) return;
 
-	if (Temp == 1024)
-		data = 0x0035;
-	else if (Temp == 1280)
-		data = 0x0048;
-	else
-		data = 0x0000;
+  Temp = (ULONG)SiS_GetReg1(SiS_P3d4,0x01);
+  Temp++;
+  Temp <<= 3;
 
-	Temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	Temp2 &= InterlaceMode;
-	if (Temp2 == 0)
-		data = 0x0000;
+  if(Temp == 1024) data = 0x0035;
+  else if(Temp == 1280) data = 0x0048;
+  else data = 0x0000;
 
-	SiS_SetReg1 (SiS_P3d4, 0x19, data);
+  Temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  Temp2 &= InterlaceMode;
+  if(Temp2 == 0) data=0x0000;
 
-	Temp = (ULONG) SiS_GetReg1 (SiS_P3d4, 0x1A);
-	Temp2 = (USHORT) (Temp & 0xFC);
-	SiS_SetReg1 (SiS_P3d4, 0x1A, (USHORT) Temp);
+  SiS_SetReg1(SiS_P3d4,0x19,data);
 
-	Temp = (ULONG) SiS_GetReg1 (SiS_P3c4, 0x0f);
-	Temp2 = (USHORT) Temp & 0xBF;
-	if (ModeNo == 0x37)
-		Temp2 = Temp2 | 0x40;
-	SiS_SetReg1 (SiS_P3d4, 0x1A, (USHORT) Temp2);
+  Temp = (ULONG)SiS_GetReg1(SiS_P3d4,0x1A);
+  Temp = (USHORT)(Temp & 0xFC);
+  SiS_SetReg1(SiS_P3d4,0x1A,(USHORT)Temp);
+
+  Temp = (ULONG)SiS_GetReg1(SiS_P3c4,0x0f);
+  Temp2 = (USHORT)Temp & 0xBF;
+  if(ModeNo==0x37) Temp2 |= 0x40;
+  SiS_SetReg1(SiS_P3d4,0x1A,(USHORT)Temp2);
 }
+#endif
 
+/* TW: Checked against 650/LVDS (1.10.07), 650/301LV and 315 BIOS */
+#ifdef SIS315H
 void
-SiS_SetCRT1FIFO (ULONG ROMAddr, USHORT ModeNo,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetCRT1FIFO_310(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
+  USHORT modeflag;
 
-	USHORT data;
-
-	data = SiS_GetReg1 (SiS_P3c4, 0x3D);
-	data &= 0xfe;
-	SiS_SetReg1 (SiS_P3c4, 0x3D, data);	/* diable auto-threshold */
-	if (ModeNo > 0x13) {
-		SiS_SetReg1 (SiS_P3c4, 0x08, 0x34);
-		data = SiS_GetReg1 (SiS_P3c4, 0x09);
-		data &= 0xF0;
-		SiS_SetReg1 (SiS_P3c4, 0x09, data);
-
-		data = SiS_GetReg1 (SiS_P3c4, 0x3D);
-		data |= 0x01;
-		SiS_SetReg1 (SiS_P3c4, 0x3D, data);
-	} else {
-		SiS_SetReg1 (SiS_P3c4, 0x08, 0xAE);
-		data = SiS_GetReg1 (SiS_P3c4, 0x09);
-		data &= 0xF0;
-		SiS_SetReg1 (SiS_P3c4, 0x09, data);
-	}
+  SiS_SetRegAND(SiS_P3c4,0x3D,0xFE);  /* disable auto-threshold */
 
+  if(ModeNo > 0x13) {
+    modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    if( (!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
+       SiS_SetReg1(SiS_P3c4,0x08,0x34);
+       SiS_SetRegAND(SiS_P3c4,0x09,0xF0);
+       SiS_SetRegOR(SiS_P3c4,0x3D,0x01);
+    } else {
+       SiS_SetReg1(SiS_P3c4,0x08,0xAE);
+       SiS_SetRegAND(SiS_P3c4,0x09,0xF0);
+    }
+  } else {
+    SiS_SetReg1(SiS_P3c4,0x08,0xAE);
+    SiS_SetRegAND(SiS_P3c4,0x09,0xF0);
+  }
 }
+#endif
 
+#if 0  /* TW: Unused */
 USHORT
-SiS_CalcDelay (ULONG ROMAddr, USHORT key)
+SiS_CalcDelay(UCHAR *ROMAddr,USHORT key)
 {
-	USHORT data, data2, temp0, temp1;
-	UCHAR ThLowA[] = { 61, 3, 52, 5, 68, 7, 100, 11,
-		43, 3, 42, 5, 54, 7, 78, 11,
-		34, 3, 37, 5, 47, 7, 67, 11
-	};
-	UCHAR ThLowB[] = { 81, 4, 72, 6, 88, 8, 120, 12,
-		55, 4, 54, 6, 66, 8, 90, 12,
-		42, 4, 45, 6, 55, 8, 75, 12
-	};
-	UCHAR ThTiming[] = { 1, 2, 2, 3, 0, 1, 1, 2 };
-
-	data = SiS_GetReg1 (SiS_P3c4, 0x16);
-	data = data >> 6;
-	data2 = SiS_GetReg1 (SiS_P3c4, 0x14);
-	data2 = (data2 >> 4) & 0x0C;
-	data = data | data2;
-	data = data < 1;
-	if (key == 0) {
-		temp0 = (USHORT) ThLowA[data];
-		temp1 = (USHORT) ThLowA[data + 1];
-	} else {
-		temp0 = (USHORT) ThLowB[data];
-		temp1 = (USHORT) ThLowB[data + 1];
-	}
-
-	data2 = 0;
-	data = SiS_GetReg1 (SiS_P3c4, 0x18);
-	if (data & 0x02)
-		data2 = data2 | 0x01;
-	if (data & 0x20)
-		data2 = data2 | 0x02;
-	if (data & 0x40)
-		data2 = data2 | 0x04;
-
-	data = temp1 * ThTiming[data2] + temp0;
-	return (data);
-}
-
-void
-SiS_SetCRT1FIFO2 (ULONG ROMAddr, USHORT ModeNo,
-		  PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		  USHORT RefreshRateTableIndex)
-{
-	USHORT i, index, data, VCLK, data2, MCLK, colorth = 0;
-	USHORT ah, bl, B;
-	ULONG eax;
-	USHORT ThresholdLow = 0;
-	UCHAR FQBQData[] = { 0x01, 0x21, 0x41, 0x61, 0x81,
-		0x31, 0x51, 0x71, 0x91, 0xb1,
-		0x00, 0x20, 0x40, 0x60, 0x80,
-		0x30, 0x50, 0x70, 0x90, 0xb0, 0xFF
-	};
-
-	if (ModeNo >= 0x13) {
-		index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-		if (HwDeviceExtension->jChipType < SIS_315H) {	/* for300 serial */
-			index = index & 0x3F;
-		}
-		VCLK = SiS_VCLKData[index].CLOCK;	/* Get VCLK  */
-		index = SiS_GetReg1 (SiS_P3c4, 0x1A);
-		index = index & 07;
-		MCLK = SiS_MCLKData[index].CLOCK;	/* Get MCLK  */
-		data2 = SiS_ModeType - 0x02;
-		switch (data2) {
-		case 0:
-			colorth = 1;
-			break;
-		case 1:
-			colorth = 2;
-			break;
-		case 2:
-			colorth = 4;
-			break;
-		case 3:
-			colorth = 4;
-			break;
-		case 4:
-			colorth = 6;
-			break;
-		case 5:
-			colorth = 8;
-			break;
-		}
-
-		i = 0;
-		do {
-			B =
-			    (SiS_CalcDelay2 (ROMAddr, FQBQData[i]) * VCLK *
-			     colorth);
-			bl = B / (16 * MCLK);
-			if (B == bl * 16 * MCLK) {
-				bl = bl + 1;
-			} else {
-				bl = bl + 1;
-			}
-
-			if (bl > 0x13) {
-				if (FQBQData[i + 1] == 0xFF) {
-					ThresholdLow = 0x13;
-					break;
-				}
-				i++;
-			} else {
-				ThresholdLow = bl;
-				break;
-			}
-		} while (FQBQData[i] != 0xFF);
-	} else {
-		ThresholdLow = 0x02;
-	}
-
-	data2 = FQBQData[i];
-	data2 = (data2 & 0xf0) >> 4;
-	data2 = data2 << 24;
-
-	SiS_SetReg4 (0xcf8, 0x80000050);
-	eax = SiS_GetReg3 (0xcfc);
-	eax = eax & 0x0f0ffffff;
-	eax = eax | data2;
-	SiS_SetReg4 (0xcfc, eax);
-
-	ah = ThresholdLow;
-	ah = ah << 4;
-	ah = ah | 0x0f;
-	SiS_SetReg1 (SiS_P3c4, 0x08, ah);
-
-	data = ThresholdLow;
-	data = data & 0x10;
-	data = data << 1;
-	SiS_SetRegANDOR (SiS_P3c4, 0x0F, 0xDF, data);
-	SiS_SetReg1 (SiS_P3c4, 0x3B, 0x09);
-
-	data = ThresholdLow + 3;
-	if (data > 0x0f)
-		data = 0x0f;
-	SiS_SetRegANDOR (SiS_P3c4, 0x09, 0x80, data);
+  USHORT data,data2,temp0,temp1;
+  UCHAR   ThLowA[]=   {61,3,52,5,68,7,100,11,
+                       43,3,42,5,54,7, 78,11,
+                       34,3,37,5,47,7, 67,11};
+  UCHAR   ThLowB[]=   {81,4,72,6,88,8,120,12,
+                       55,4,54,6,66,8, 90,12,
+                       42,4,45,6,55,8, 75,12};
+  UCHAR   ThTiming[]= {1,2,2,3,0,1,1,2};
+
+  data=SiS_GetReg1(SiS_P3c4,0x16);
+  data=data>>6;
+  data2=SiS_GetReg1(SiS_P3c4,0x14);
+  data2=(data2>>4)&0x0C;
+  data=data|data2;
+  data=data<1;
+  if(key==0) {
+    temp0=(USHORT)ThLowA[data];
+    temp1=(USHORT)ThLowA[data+1];
+  } else {
+    temp0=(USHORT)ThLowB[data];
+    temp1=(USHORT)ThLowB[data+1];
+  }
+
+  data2=0;
+  data=SiS_GetReg1(SiS_P3c4,0x18);
+  if(data&0x02) data2=data2|0x01;
+  if(data&0x20) data2=data2|0x02;
+  if(data&0x40) data2=data2|0x04;
+
+  data=temp1*ThTiming[data2]+temp0;
+  return(data);
+}
+#endif
+
+#ifdef SIS300
+void
+SiS_SetCRT1FIFO_300(UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                    USHORT RefreshRateTableIndex)
+{
+  USHORT  i,index,data,VCLK,MCLK,colorth=0;
+  ULONG   B,eax,bl,data2;
+  USHORT  ThresholdLow=0;
+  UCHAR   FQBQData[]= { 0x01,0x21,0x41,0x61,0x81,
+                        0x31,0x51,0x71,0x91,0xb1,
+                        0x00,0x20,0x40,0x60,0x80,
+                        0x30,0x50,0x70,0x90,0xb0,0xFF};
+
+  i=0;
+  if(ModeNo >= 0x13) {
+    index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+    index &= 0x3F;
+    VCLK = SiS_VCLKData[index].CLOCK;             /* Get VCLK  */
+
+    index = SiS_GetReg1(SiS_P3c4,0x1A);
+    index &= 0x07;
+    MCLK = SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
+
+    data2 = SiS_ModeType - ModeEGA;
+    switch (data2) {
+        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;
+    }
+
+    do{
+       B = SiS_CalcDelay2(ROMAddr,FQBQData[i]) * VCLK * colorth;
+       bl = B / (MCLK * 16);
+
+       if (B==bl*16*MCLK) {
+         bl = bl + 1;
+       } else {
+         bl = bl + 2;
+       }
+
+       if(bl > 0x13) {
+          if(FQBQData[i+1] == 0xFF) {
+             ThresholdLow = 0x13;
+             break;
+          }
+          i++;
+       } else {
+          ThresholdLow = bl;
+          break;
+       }
+    } while(FQBQData[i] != 0xFF);
+  }
+  else {
+    ThresholdLow = 0x02;
+  }
+
+  /* Write foreground and background queue */
+  data2 = FQBQData[i];
+  data2 = (data2 & 0xf0)>>4;
+  data2 <<= 24;
+
+#ifndef LINUX_XF86
+  SiS_SetReg4(0xcf8,0x80000050);
+  eax = SiS_GetReg3(0xcfc);
+  eax &= 0xf0ffffff;
+  eax |= data2;
+  SiS_SetReg4(0xcfc,eax);
+#else
+  /* We use pci functions X offers. We use pcitag 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.
+   */
+  eax = pciReadLong(0x00000000, 0x50);
+  eax &= 0xf0ffffff;
+  eax |= data2;
+  pciWriteLong(0x00000000, 0x50, eax);
+#endif
+
+  /* TODO: write GUI grant timer (PCI config 0xA3) */
+
+  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+  data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
+  SiS_SetReg1(SiS_P3c4,0x08,data);
+
+  data = (ThresholdLow & 0x10) << 1;
+  SiS_SetRegANDOR(SiS_P3c4,0x0F,0xDF,data);
+
+  /* What is this? */
+  SiS_SetReg1(SiS_P3c4,0x3B,0x09);
+
+  /* Write CRT/CPU threshold high */
+  data = ThresholdLow + 3;
+  if(data > 0x0f) data = 0x0f;
+  SiS_SetRegANDOR(SiS_P3c4,0x09,0x80,data);
 }
 
 USHORT
-SiS_CalcDelay2 (ULONG ROMAddr, UCHAR key)
+SiS_CalcDelay2(UCHAR *ROMAddr,UCHAR key)
 {
-	USHORT data, index;
-	UCHAR LatencyFactor[] = { 97, 88, 86, 79, 77, 00,	/*; 64  bit    BQ=2   */
-		00, 87, 85, 78, 76, 54,	/*; 64  bit    BQ=1   */
-		97, 88, 86, 79, 77, 00,	/*; 128 bit    BQ=2   */
-		00, 79, 77, 70, 68, 48,	/*; 128 bit    BQ=1   */
-		80, 72, 69, 63, 61, 00,	/*; 64  bit    BQ=2   */
-		00, 70, 68, 61, 59, 37,	/*; 64  bit    BQ=1   */
-		86, 77, 75, 68, 66, 00,	/*; 128 bit    BQ=2   */
-		00, 68, 66, 59, 57, 37
-	};			/*; 128 bit    BQ=1   */
-
-	index = (key & 0xE0) >> 5;
-	if (key & 0x10)
-		index = index + 6;
-	if (!(key & 0x01))
-		index = index + 24;
-	data = SiS_GetReg1 (SiS_P3c4, 0x14);
-	if (data & 0x0080)
-		index = index + 12;
-
-	data = LatencyFactor[index];
-	return (data);
+  USHORT data,index;
+  UCHAR  LatencyFactor[] ={ 97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
+                            00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
+                            97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
+                            00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
+                            80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
+                            00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
+                            86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
+                            00, 68, 66, 59, 57, 37};      /*; 128 bit    BQ=1   */
+
+  index = (key & 0xE0) >> 5;
+  if(key & 0x10) index +=6;
+  if(!(key & 0x01)) index += 24;
+  data = SiS_GetReg1(SiS_P3c4,0x14);
+  if(data & 0x0080) index += 12;
+
+  data = LatencyFactor[index];
+  return(data);
 }
+#endif
 
-void
-SiS_CRT2AutoThreshold (USHORT BaseAddr)
-{
-	USHORT temp1;
-	USHORT Part1Port;
-	Part1Port = BaseAddr + SIS_CRT2_PORT_04;
-	temp1 = SiS_GetReg1 (SiS_Part1Port, 0x1);
-	temp1 |= 0x40;
-	SiS_SetReg1 (SiS_Part1Port, 0x1, temp1);
-}
-
-/* =============  ynlai ============== */
-void
-SiS_DetectMonitor (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-	UCHAR DAC_TEST_PARMS[] = { 0x0F, 0x0F, 0x0F };
-	UCHAR DAC_CLR_PARMS[] = { 0x00, 0x00, 0x00 };
-	USHORT SR1F;
-
-	SR1F = SiS_GetReg1 (SiS_P3c4, 0x1F);
-	SiS_SetRegANDOR (SiS_P3c4, 0x1F, 0xFF, 0x04);
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_BridgeIsOn (BaseAddr)) {
-			SiS_SetReg1 (SiS_P3d4, 0x30, 0x41);
-		}
-	}
-	SiSSetMode (HwDeviceExtension, 0x03);	/* InitMode */
-	SiS_SetReg3 (SiS_P3c6, 0xff);
-	SiS_ClearDAC (SiS_P3c8);
-	SiS_LongWait ();
-	SiS_LongWait ();
-	SiS_SetRegANDOR (SiS_P3d4, 0x32, 0xDF, 0x00);
-	if (SiS_TestMonitorType
-	    (DAC_TEST_PARMS[0], DAC_TEST_PARMS[1], DAC_TEST_PARMS[2])) {
-		SiS_SetRegANDOR (SiS_P3d4, 0x32, 0xDF, 0x20);
-	}
-	if (SiS_TestMonitorType
-	    (DAC_TEST_PARMS[0], DAC_TEST_PARMS[1], DAC_TEST_PARMS[2])) {
-		SiS_SetRegANDOR (SiS_P3d4, 0x32, 0xDF, 0x20);
-	}
-	SiS_TestMonitorType (DAC_CLR_PARMS[0], DAC_CLR_PARMS[1],
-			     DAC_CLR_PARMS[2]);
-	SiS_SetReg1 (SiS_P3c4, 0x1F, SR1F);
+/* =============== Autodetection ================ */
+
+#ifndef LINUX_XF86
+
+/* (ynlai) */
+void
+SiS_DetectMonitor(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+  UCHAR  DAC_TEST_PARMS[]={0x0F,0x0F,0x0F};
+  UCHAR  DAC_CLR_PARMS[]={0x00,0x00,0x00};
+  USHORT SR1F;
+
+  SR1F=SiS_GetReg1(SiS_P3c4,0x1F);		/* DAC pedestal */
+  SiS_SetRegANDOR(SiS_P3c4,0x1F,0xFF,0x04);
+  if(SiS_IF_DEF_LVDS==0) {
+    if(SiS_BridgeIsOn(BaseAddr)==0) {    /* TW: Inserted "==0" */
+      SiS_SetReg1(SiS_P3d4,0x30,0x41);
+    }
+  }
+  /*SiSSetMode(HwDeviceExtension,0x03);  */ /* ynlai InitMode */
+
+  SiSSetMode(HwDeviceExtension,0x2E);   /* alan */
+  SiS_SetReg3(SiS_P3c6,0xff);
+  SiS_ClearDAC(SiS_P3c8);
+  SiS_LongWait();
+  SiS_LongWait();
+  SiS_SetRegANDOR(SiS_P3d4,0x32,0xDF,0x00);
+  if(SiS_TestMonitorType(DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
+    SiS_SetRegANDOR(SiS_P3d4,0x32,0xDF,0x20);
+  }
+  if(SiS_TestMonitorType(DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
+    SiS_SetRegANDOR(SiS_P3d4,0x32,0xDF,0x20);
+  }
+  SiS_TestMonitorType(DAC_CLR_PARMS[0],DAC_CLR_PARMS[1],DAC_CLR_PARMS[2]);
+  SiS_SetReg1(SiS_P3c4,0x1F,SR1F);
 }
 
 USHORT
-SiS_TestMonitorType (UCHAR R_DAC, UCHAR G_DAC, UCHAR B_DAC)
+SiS_TestMonitorType(UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC)
 {
-	USHORT temp, tempbx;
+   USHORT temp,tempbx;
 
-	tempbx = R_DAC * 0x4d + G_DAC * 0x97 + B_DAC * 0x1c;
-	if (tempbx > 0x80)
-		tempbx = tempbx + 0x100;
-	tempbx = (tempbx & 0xFF00) >> 8;
-	R_DAC = (UCHAR) tempbx;
-	G_DAC = (UCHAR) tempbx;
-	B_DAC = (UCHAR) tempbx;
-
-	SiS_SetReg3 (SiS_P3c8, 0x00);
-	SiS_SetReg3 (SiS_P3c9, R_DAC);
-	SiS_SetReg3 (SiS_P3c9, G_DAC);
-	SiS_SetReg3 (SiS_P3c9, B_DAC);
-	SiS_LongWait ();
-	temp = SiS_GetReg2 (SiS_P3c2);
-	if (temp & 0x10)
-		return (1);
-	else
-		return (0);
+   tempbx=R_DAC*0x4d+G_DAC*0x97+B_DAC*0x1c;
+   if(tempbx>0x80) tempbx=tempbx+0x100;
+   tempbx = (tempbx&0xFF00)>>8;
+   R_DAC = (UCHAR) tempbx;
+   G_DAC = (UCHAR) tempbx;
+   B_DAC = (UCHAR) tempbx;
+
+   SiS_SetReg3(SiS_P3c8,0x00);
+   SiS_SetReg3(SiS_P3c9,R_DAC);
+   SiS_SetReg3(SiS_P3c9,G_DAC);
+   SiS_SetReg3(SiS_P3c9,B_DAC);
+   SiS_LongWait();
+   temp=SiS_GetReg2(SiS_P3c2);
+   if(temp&0x10) return(1);
+   else return(0);
 }
 
 /* ---- test ----- */
 void
-SiS_GetSenseStatus (PSIS_HW_DEVICE_INFO HwDeviceExtension, ULONG ROMAddr)
+SiS_GetSenseStatus(PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr)
 {
-	USHORT tempax = 0, tempbx, tempcx, temp;
-	USHORT P2reg0 = 0, SenseModeNo = 0, OutputSelect = *pSiS_OutputSelect;
-	USHORT ModeIdIndex, i;
-	USHORT BaseAddr = (USHORT) HwDeviceExtension->ulIOAddress;
-
-	if (SiS_IF_DEF_LVDS == 1) {
-		SiS_GetPanelID ();
-		temp = LCDSense;
-		temp = temp | SiS_SenseCHTV ();
-		tempbx = ~(LCDSense | AVIDEOSense | SVIDEOSense);
-		SiS_SetRegANDOR (SiS_P3d4, 0x32, tempbx, temp);
-	} else {		/* for 301 */
-		if (SiS_IF_DEF_HiVision == 1) {	/* for HiVision */
-			tempax = SiS_GetReg1 (SiS_P3c4, 0x38);
-			temp = tempax & 0x01;
-			tempax = SiS_GetReg1 (SiS_P3c4, 0x3A);
-			temp = temp | (tempax & 0x02);
-			SiS_SetRegANDOR (SiS_P3d4, 0x32, 0xA0, temp);
-		} else {
-			if (SiS_BridgeIsOn (BaseAddr)) {
-				P2reg0 = SiS_GetReg1 (SiS_Part2Port, 0x00);
-				if (!SiS_BridgeIsEnable
-				    (BaseAddr, HwDeviceExtension)) {
-					SenseModeNo = 0x2e;
-					temp =
-					    SiS_SearchModeID (ROMAddr,
-							      SenseModeNo,
-							      &ModeIdIndex);
-					SiS_SetFlag = 0x00;
-					SiS_ModeType = ModeVGA;
-					SiS_VBInfo =
-					    SetCRT2ToRAMDAC | LoadDACFlag |
-					    SetInSlaveMode;
-					SiS_SetCRT2Group301 (BaseAddr, ROMAddr,
-							     SenseModeNo,
-							     HwDeviceExtension);
-					for (i = 0; i < 20; i++) {
-						SiS_LongWait ();
-					}
-				}
-				SiS_SetReg1 (SiS_Part2Port, 0x00, 0x1c);
-				tempax = 0;
-				tempbx = *pSiS_RGBSenseData;
-				/*301b */
-				if (!(SiS_Is301B (BaseAddr))) {
-					tempbx = *pSiS_RGBSenseData2;
-				}
-				/*end 301b */
-				tempcx = 0x0E08;
-				if (SiS_Sense (SiS_Part4Port, tempbx, tempcx)) {
-					if (SiS_Sense
-					    (SiS_Part4Port, tempbx, tempcx)) {
-						tempax = tempax | Monitor2Sense;
-					}
-				}
-
-				tempbx = *pSiS_YCSenseData;
-				/*301b */
-				if (!(SiS_Is301B (BaseAddr))) {
-					tempbx = *pSiS_YCSenseData2;
-				}
-				/*301b */
-				tempcx = 0x0604;
-				if (SiS_Sense (SiS_Part4Port, tempbx, tempcx)) {
-					if (SiS_Sense
-					    (SiS_Part4Port, tempbx, tempcx)) {
-						tempax = tempax | SVIDEOSense;
-					}
-				}
-
-				if (OutputSelect & BoardTVType) {
-					tempbx = *pSiS_VideoSenseData;
-					/*301b */
-					if (!(SiS_Is301B (BaseAddr))) {
-						tempbx = *pSiS_VideoSenseData2;
-					}
-					/*end 301b */
-					tempcx = 0x0804;
-					if (SiS_Sense
-					    (SiS_Part4Port, tempbx, tempcx)) {
-						if (SiS_Sense
-						    (SiS_Part4Port, tempbx,
-						     tempcx)) {
-							tempax =
-							    tempax |
-							    AVIDEOSense;
-						}
-					}
-				} else {
-					if (!(tempax & SVIDEOSense)) {
-						tempbx = *pSiS_VideoSenseData;
-						/*301b */
-						if (!(SiS_Is301B (BaseAddr))) {
-							tempbx =
-							    *pSiS_VideoSenseData2;
-						}
-						/*end 301b */
-						tempcx = 0x0804;
-						if (SiS_Sense
-						    (SiS_Part4Port, tempbx,
-						     tempcx)) {
-							if (SiS_Sense
-							    (SiS_Part4Port,
-							     tempbx, tempcx)) {
-								tempax =
-								    tempax |
-								    AVIDEOSense;
-							}
-						}
-					}
-				}
-			}
-
-			if (SiS_SenseLCD (HwDeviceExtension)) {
-				tempax = tempax | LCDSense;
-			}
-
-			tempbx = 0;
-			tempcx = 0;
-			SiS_Sense (SiS_Part4Port, tempbx, tempcx);
-
-			SiS_SetRegANDOR (SiS_P3d4, 0x32, ~0xDF, tempax);
-			SiS_SetReg1 (SiS_Part2Port, 0x00, P2reg0);
-			if (!(P2reg0 & 0x20)) {
-				SiS_VBInfo = DisableCRT2Display;
-				SiS_SetCRT2Group301 (BaseAddr, ROMAddr,
-						     SenseModeNo,
-						     HwDeviceExtension);
-			}
-		}
-	}
+  USHORT tempax=0,tempbx,tempcx,temp;
+  USHORT P2reg0=0,SenseModeNo=0,OutputSelect=*pSiS_OutputSelect;
+  USHORT ModeIdIndex,i;
+  USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+
+  if(SiS_IF_DEF_LVDS==1){
+    SiS_GetPanelID();
+    temp=LCDSense;
+    temp=temp|SiS_SenseCHTV();
+    tempbx=~(LCDSense|AVIDEOSense|SVIDEOSense);
+    SiS_SetRegANDOR(SiS_P3d4,0x32,tempbx,temp);
+  } else {       /* for 301 */
+    if(SiS_IF_DEF_HiVision==1) {  /* for HiVision */
+      tempax=SiS_GetReg1(SiS_P3c4,0x38);
+      temp=tempax&0x01;
+      tempax=SiS_GetReg1(SiS_P3c4,0x3A);
+      temp=temp|(tempax&0x02);
+      SiS_SetRegANDOR(SiS_P3d4,0x32,0xA0,temp);
+    } else {
+      if(SiS_BridgeIsOn(BaseAddr)==0) {    /* TW: Inserted "==0" */
+        P2reg0 = SiS_GetReg1(SiS_Part2Port,0x00);
+        if(!SiS_BridgeIsEnable(BaseAddr,HwDeviceExtension)) {
+          SenseModeNo=0x2e;
+          temp = SiS_SearchModeID(ROMAddr,&SenseModeNo,&ModeIdIndex);
+          SiS_SetFlag = 0x00;
+          SiS_ModeType = ModeVGA;
+          SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
+          SiS_SetCRT2Group301(BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+          for(i=0;i<20;i++) {
+            SiS_LongWait();
+          }
+        }
+        SiS_SetReg1(SiS_Part2Port,0x00,0x1c);
+        tempax=0;
+        tempbx=*pSiS_RGBSenseData;
+	if(SiS_Is301B(BaseAddr)){
+                tempbx=*pSiS_RGBSenseData2;
+        }
+        tempcx=0x0E08;
+        if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+          if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+            tempax=tempax|Monitor2Sense;
+          }
+        }
+        tempbx=*pSiS_YCSenseData;
+        if(SiS_Is301B(BaseAddr)){
+               tempbx=*pSiS_YCSenseData2;
+        }
+        tempcx=0x0604;
+        if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+          if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+            tempax=tempax|SVIDEOSense;
+          }
+        }
+
+        if(OutputSelect&BoardTVType){
+          tempbx=*pSiS_VideoSenseData;
+        if(SiS_Is301B(BaseAddr)){
+             tempbx=*pSiS_VideoSenseData2;
+        }
+          tempcx=0x0804;
+          if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+            if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+              tempax=tempax|AVIDEOSense;
+            }
+          }
+        } else {
+          if(!(tempax&SVIDEOSense)){
+            tempbx=*pSiS_VideoSenseData;
+            if(SiS_Is301B(BaseAddr)){
+              tempbx=*pSiS_VideoSenseData2;
+            }
+            tempcx=0x0804;
+            if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+              if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+                tempax=tempax|AVIDEOSense;
+              }
+            }
+          }
+        }
+      }
+
+      if(SiS_SenseLCD(HwDeviceExtension)){
+        tempax=tempax|LCDSense;
+      }
+
+      tempbx=0;
+      tempcx=0;
+      SiS_Sense(SiS_Part4Port,tempbx,tempcx);
+  
+      if((SiS_VBType & VB_SIS301LV)||(SiS_VBType & VB_SIS302LV)){
+         tempax &= 0x00ef;   /* 301lv to disable CRT2*/
+      }
+      SiS_SetRegANDOR(SiS_P3d4,0x32,~0xDF,tempax);
+      SiS_SetReg1(SiS_Part2Port,0x00,P2reg0);
+      if(!(P2reg0&0x20)) {
+        SiS_VBInfo = DisableCRT2Display;
+        SiS_SetCRT2Group301(BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+      }
+    }
+  }
 }
 
 BOOLEAN
-SiS_Sense (USHORT Part4Port, USHORT tempbx, USHORT tempcx)
+SiS_Sense(USHORT Part4Port,USHORT tempbx,USHORT tempcx)
 {
-	USHORT temp, i, tempch;
+  USHORT temp,i,tempch;
 
-	temp = tempbx & 0xFF;
-	SiS_SetReg1 (SiS_Part4Port, 0x11, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp | (tempcx & 0x00FF);
-	SiS_SetRegANDOR (SiS_Part4Port, 0x10, ~0x1F, temp);
-
-	for (i = 0; i < 10; i++)
-		SiS_LongWait ();
-
-	tempch = (tempcx & 0x7F00) >> 8;	/*   ynlai [05/22/2001]  */
-	temp = SiS_GetReg1 (SiS_Part4Port, 0x03);
-	temp = temp ^ (0x0E);
-	temp = temp & tempch;	/*   ynlai [05/22/2001]  */
-	if (temp > 0)
-		return 1;
-	else
-		return 0;
+  temp=tempbx&0xFF;
+  SiS_SetReg1(SiS_Part4Port,0x11,temp);
+  temp=(tempbx&0xFF00)>>8;
+  temp=temp|(tempcx&0x00FF);
+  SiS_SetRegANDOR(SiS_Part4Port,0x10,~0x1F,temp);
+
+  for(i=0;i<10;i++) SiS_LongWait();
+
+  tempch=(tempcx&0x7F00)>>8;      /*   ynlai [05/22/2001]  */
+  temp=SiS_GetReg1(SiS_Part4Port,0x03);
+  temp=temp^(0x0E);
+  temp=temp&tempch;               /*   ynlai [05/22/2001]  */
+  if(temp>0) return 1;
+  else return 0;
 }
 
 USHORT
-SiS_SenseLCD (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SenseLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-/*  USHORT SoftSetting; */
-	USHORT temp;
+  USHORT temp;
 
-	temp = SiS_GetPanelID ();
-	if (!temp)
-		temp = SiS_GetLCDDDCInfo (HwDeviceExtension);
-	return (temp);
+  temp=SiS_GetPanelID();
+  if(!temp)  temp=SiS_GetLCDDDCInfo(HwDeviceExtension);
+  return(temp);
 }
 
 BOOLEAN
-SiS_GetLCDDDCInfo (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetLCDDDCInfo(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT temp;
-	//add lcd sense
-	if (HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN)
-		return 0;
-	else {
-		temp = (USHORT) HwDeviceExtension->ulCRT2LCDType;
-		SiS_SetReg1 (SiS_P3d4, 0x36, temp);
-		return 1;
-	}
+  USHORT temp;
+  /*add lcd sense*/
+  if(HwDeviceExtension->ulCRT2LCDType==LCD_UNKNOWN)
+    	return 0;
+  else{
+     	temp=(USHORT)HwDeviceExtension->ulCRT2LCDType;
+     	SiS_SetReg1(SiS_P3d4,0x36,temp);
+  	return 1;
+  }
 }
 
 BOOLEAN
-SiS_GetPanelID (void)
+SiS_GetPanelID(void)
 {
-	USHORT PanelTypeTable[16] =
-	    { SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType00,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType01,
-		SyncPP | PanelRGB18Bit | Panel800x600 | _PanelType02,
-		SyncNN | PanelRGB18Bit | Panel640x480 | _PanelType03,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType04,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType05,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType06,
-		SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType07,
-		SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType08,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType09,
-		SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType0A,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0B,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0C,
-		SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType0D,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0E,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0F
-	};
-	USHORT tempax, tempbx, temp;
-/*  USHORT return_flag; */
-
-	tempax = SiS_GetReg1 (SiS_P3c4, 0x18);
-	tempbx = tempax & 0x0F;
-	if (!(tempax & 0x10)) {
-		if (SiS_IF_DEF_LVDS == 1) {
-			tempbx = 0;
-			temp = SiS_GetReg1 (SiS_P3c4, 0x38);
-			if (temp & 0x40)
-				tempbx = tempbx | 0x08;
-			if (temp & 0x20)
-				tempbx = tempbx | 0x02;
-			if (temp & 0x01)
-				tempbx = tempbx | 0x01;
-			temp = SiS_GetReg1 (SiS_P3c4, 0x39);
-			if (temp & 0x80)
-				tempbx = tempbx | 0x04;
-		} else {
-			return 0;
-		}
-	}
-
-	tempbx = tempbx << 1;
-	tempbx = PanelTypeTable[tempbx];
-	tempbx = tempbx | LCDSync;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_P3d4, 0x36, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	SiS_SetRegANDOR (SiS_P3d4, 0x37, ~(LCDSyncBit | LCDRGB18Bit), temp);
-	return 1;
+  USHORT PanelTypeTable[16]={ SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType00,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType01,
+                              SyncPP | PanelRGB18Bit | Panel800x600  | _PanelType02,
+                              SyncNN | PanelRGB18Bit | Panel640x480  | _PanelType03,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType04,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType05,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType06,
+                              SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType07,
+                              SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType08,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType09,
+                              SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType0A,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0B,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0C,
+                              SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType0D,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0E,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0F
+                              };
+  USHORT tempax,tempbx,temp;
+
+  tempax = SiS_GetReg1(SiS_P3c4,0x18);
+  tempbx = tempax & 0x0F;
+  if(!(tempax & 0x10)){
+    if(SiS_IF_DEF_LVDS==1){
+      tempbx = 0;
+      temp = SiS_GetReg1(SiS_P3c4,0x38);
+      if(temp & 0x40) tempbx |= 0x08;
+      if(temp & 0x20) tempbx |= 0x02;
+      if(temp & 0x01) tempbx |= 0x01;
+      temp=SiS_GetReg1(SiS_P3c4,0x39);
+      if(temp & 0x80) tempbx |= 0x04;
+    } else {
+      return 0;
+    }
+  }
+
+  tempbx <<= 1;
+  tempbx = PanelTypeTable[tempbx];
+  tempbx |= LCDSync;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_P3d4,0x36,temp);
+  temp = (tempbx & 0xFF00) >> 8;
+  SiS_SetRegANDOR(SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
+  return 1;
 }
 
 USHORT
-SiS_SenseCHTV (void)
+SiS_SenseCHTV(void)
 {
-	USHORT temp, push0e, status;
+  USHORT temp,push0e,status;
 
-	status = 0;
-	push0e = SiS_GetCH7005 (0x0e);
-	push0e = (push0e << 8) | 0x0e;
-	SiS_SetCH7005 (0x0b0e);
-	SiS_SetCH7005 (0x0110);
-	SiS_SetCH7005 (0x0010);
-	temp = SiS_GetCH7005 (0x10);
-	if (temp & 0x08)
-		status = status | SVIDEOSense;
-	if (temp & 0x02)
-		status = status | AVIDEOSense;
-	SiS_SetCH7005 (push0e);
-	return (status);
+  status=0;
+  push0e = SiS_GetCH700x(0x0e);
+  push0e = (push0e << 8) | 0x0e;
+  SiS_SetCH700x(0x0b0e);
+  SiS_SetCH700x(0x0110);
+  SiS_SetCH700x(0x0010);
+  temp = SiS_GetCH700x(0x10);
+  if(temp & 0x08) status |= SVIDEOSense;
+  if(temp & 0x02) status |= AVIDEOSense;
+  SiS_SetCH700x(push0e);
+  return(status);
 }
+#endif /* LINUX_XF86 */
+
+/*  ================ for TC only =================  */
 
-/*  ==========================================  */
 #ifdef TC
 
 int
-INT1AReturnCode (union REGS regs)
+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;
+  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)
+FindPCIIOBase(unsigned index,unsigned deviceid)
 {
-	union REGS regs;
+  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 */
+  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);
+  int86(0x1A, &regs, &regs);
 
-	if (INT1AReturnCode (regs) != 0)
-		return 0;
+  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);
+  /* 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;
+  if (INT1AReturnCode(regs)!=0)
+    return 0;
+  return regs.x.cx;
 }
 
+
 void
-main (int argc, char *argv[])
-/* void main() */
+main(int argc, char *argv[])
 {
-	SIS_HW_DEVICE_INFO HwDeviceExtension;
-	USHORT temp;
-	USHORT ModeNo;
+  SIS_HW_DEVICE_INFO  HwDeviceExtension;
+  USHORT temp;
+  USHORT ModeNo;
+
+  /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
+  /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/
 
-	/*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
-	/*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0); */
-#ifdef CONFIG_FB_SIS_300
-	HwDeviceExtension.ulIOAddress =
-	    (FindPCIIOBase (0, 0x6300) & 0xFF80) + 0x30;
-	HwDeviceExtension.jChipType = SIS_630;
+#ifdef SIS300  
+  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30;
+  HwDeviceExtension.jChipType = SIS_630;
 #endif
 
-#ifdef CONFIG_FB_SIS_315
+#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 */
+  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(&HwDeviceExtension);*/
+  SiSSetMode(&HwDeviceExtension,ModeNo);
+}
+#endif /* TC END */
+
+/* ================ LINUX XFREE86 ====================== */
+
+#ifdef LINUX_XF86
+USHORT
+SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+   UShort i = (pScrn->bitsPerPixel+7)/8 - 1;
+   UShort ModeIndex = 0;
+   SISPtr pSiS = SISPTR(pScrn);
+
+   switch(mode->HDisplay)
+   {
+     case 320:
+          if(mode->VDisplay == 480) {
+                ModeIndex = ModeIndex_320x480[i];
+	  }
+          break;
+     case 512:
+          if(mode->VDisplay == 384) {
+             ModeIndex = ModeIndex_512x384[i];
+	  }
+          break;
+     case 640:
+          if(mode->VDisplay == 480) {
+             ModeIndex = ModeIndex_640x480[i];
+	  }
+          break;
+     case 720:
+          if(mode->VDisplay == 480) {
+                ModeIndex = ModeIndex_720x480[i];
+          } else if(mode->VDisplay == 576) {
+                ModeIndex = ModeIndex_720x576[i];
+          }
+          break;
+     case 800:
+	  if(mode->VDisplay == 600) {
+             ModeIndex = ModeIndex_800x600[i];
+	  } else if(pSiS->VGAEngine == SIS_315_VGA) {
+	     if(mode->VDisplay == 480) {
+	           ModeIndex = ModeIndex_800x480[i];
+             }
+	  }
+          break;
+     case 1024:
+          if(mode->VDisplay == 768) {
+	        ModeIndex = ModeIndex_1024x768[i];
+	  } else if(pSiS->VGAEngine == SIS_315_VGA) {
+	     if(mode->VDisplay == 576) {
+	        ModeIndex = ModeIndex_1024x576[i];
+             }
+	  } else if(pSiS->VGAEngine == SIS_300_VGA) {
+	     if(mode->VDisplay == 600) {
+	        ModeIndex = ModeIndex_1024x600[i];
+             }
+	  }
+          break;
+     case 1152:
+          if(pSiS->VGAEngine == SIS_300_VGA) {
+	     if(mode->VDisplay == 768) {
+	        ModeIndex = ModeIndex_1152x768[i];
+             }
+	  }
+	  break;
+     case 1280:
+          if(mode->VDisplay == 960) {
+             if(pSiS->VGAEngine == SIS_300_VGA) {
+	        ModeIndex = ModeIndex_300_1280x960[i];
+             } else {
+                ModeIndex = ModeIndex_310_1280x960[i];
+             }
+	  } else if (mode->VDisplay == 1024) {
+	     ModeIndex = ModeIndex_1280x1024[i];
+	  } else if(pSiS->VGAEngine == SIS_315_VGA) {
+	     if (mode->VDisplay == 768) {
+	        ModeIndex = ModeIndex_1280x768[i];
+	     } else if (mode->VDisplay == 720) {
+	        ModeIndex = ModeIndex_1280x720[i];
+             }
+	  }
+          break;
+     case 1400:
+          if(pSiS->VGAEngine == SIS_315_VGA) {
+	     if(mode->VDisplay == 1050) {
+	        ModeIndex = ModeIndex_1400x1050[i];
+             }
+	  }
+          break;
+     case 1600:
+          if(mode->VDisplay == 1200) {
+             ModeIndex = ModeIndex_1600x1200[i];
+	  }
+          break;
+     case 1920:
+          if(mode->VDisplay == 1440) {
+             ModeIndex = ModeIndex_1920x1440[i];
+	  }
+          break;
+     case 2048:
+          if(pSiS->VGAEngine == SIS_315_VGA) {
+	     if(mode->VDisplay == 1536) {
+	         ModeIndex = ModeIndex_2048x1536[i];
+             }
+	  }
+          break;
+   }
+
+   return(ModeIndex);
+}
+
+USHORT
+SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
+{
+   UShort i = (pScrn->bitsPerPixel+7)/8 - 1;
+   UShort ModeIndex = 0;
+   SISPtr pSiS = SISPTR(pScrn);
+
+   if(VBFlags & CRT2_LCD) {
+
+      if( (mode->HDisplay <= pSiS->LCDwidth) &&
+          (mode->VDisplay <= pSiS->LCDheight) ) {
+
+        if(VBFlags & VB_LVDS) {        		/* LCD on LVDS */
+
+          switch(mode->HDisplay)
+  	  {
+	  case 512:
+		if(mode->VDisplay == 384) {
+		   ModeIndex = ModeIndex_512x384[i];
+		}
+		break;
+	  case 640:
+		if(mode->VDisplay == 480) {
+		   ModeIndex = ModeIndex_640x480[i];
+		}
+		break;
+	  case 800:
+		if(mode->VDisplay == 600) {
+		   ModeIndex = ModeIndex_800x600[i];
+		}
+		break;
+	  case 1024:
+		if(mode->VDisplay == 768) {
+		   ModeIndex = ModeIndex_1024x768[i];
+		} else if(pSiS->VGAEngine == SIS_300_VGA) {
+		   if(mode->VDisplay == 600) {
+		      ModeIndex = ModeIndex_1024x600[i];
+		   }
+		}
+		break;
+	  case 1152:
+		if(pSiS->VGAEngine == SIS_300_VGA) {
+		   if(mode->VDisplay == 768) {
+			ModeIndex = ModeIndex_1152x768[i];
+		   }
+		}
+		break;
+	  case 1280:
+		if(mode->VDisplay == 1024) {
+		   ModeIndex = ModeIndex_1280x1024[i];
+		} else if(pSiS->VGAEngine == SIS_315_VGA) {
+		   if(mode->VDisplay == 768) {
+		      ModeIndex = ModeIndex_1280x768[i];
+		   }
+		}
+		break;
+	  case 1400:
+	        if(mode->VDisplay == 1050) {
+		   if(pSiS->VGAEngine == SIS_315_VGA) {
+		      ModeIndex = ModeIndex_1400x1050[i];
+		   }
+		}
+		break;
+          }
+
+        } else {                       	 	/* LCD on 301(B) */
+
+          switch(mode->HDisplay)
+	  {
+	  case 512:
+		if(mode->VDisplay == 384) {
+		   ModeIndex = ModeIndex_512x384[i];
+		}
+		break;
+	  case 640:
+		if(mode->VDisplay == 480) {
+		   ModeIndex = ModeIndex_640x480[i];
+		}
+		break;
+	  case 800:
+		if(mode->VDisplay == 600) {
+		   ModeIndex = ModeIndex_800x600[i];
+		}
+		break;
+	  case 1024:
+		if(mode->VDisplay == 768) {
+		   ModeIndex = ModeIndex_1024x768[i];
+		} else if(pSiS->VGAEngine == SIS_300_VGA) {
+		   if(mode->VDisplay == 600) {
+			ModeIndex = ModeIndex_1024x600[i];
+		   }
+		}
+		break;
+	  case 1152:  /* ? */
+		if(pSiS->VGAEngine == SIS_300_VGA) {
+		   if(mode->VDisplay == 768) {
+			ModeIndex = ModeIndex_1152x768[i];
+		   }
+		}
+		break;
+	  case 1280:
+		if(mode->VDisplay == 960) {
+		   if(pSiS->VGAEngine == SIS_300_VGA) {
+		      ModeIndex = ModeIndex_300_1280x960[i];
+		   } else {
+		      ModeIndex = ModeIndex_310_1280x960[i];
+		   }
+                } else if (mode->VDisplay == 1024) {
+	             ModeIndex = ModeIndex_1280x1024[i];
+	        }
+	  case 1600:
+		if(mode->VDisplay == 1200) {
+		   ModeIndex = ModeIndex_1600x1200[i];
+		}
+		break;
+	  }
+
+        }
+
+      }
+
+   } else if(VBFlags & CRT2_TV) {
+
+      if(VBFlags & VB_CHRONTEL) {		/* TV on Chrontel */
+
+        switch(mode->HDisplay)
+	{
+      	case 512:
+		if(mode->VDisplay == 384) {
+		   ModeIndex = ModeIndex_512x384[i];
+		}
+		break;
+	case 640:
+		if(mode->VDisplay == 480) {
+		   ModeIndex = ModeIndex_640x480[i];
+		}
+		break;
+	case 800:
+		if(mode->VDisplay == 600) {
+		   ModeIndex = ModeIndex_800x600[i];
+		}
+		break;
+	case 1024:
+		if(mode->VDisplay == 768) {
+		   if(pSiS->VGAEngine == SIS_315_VGA) {
+		      ModeIndex = ModeIndex_1024x768[i];
+		   }
+		}
+		break;
+        }
+
+      } else {				    /* TV on 301(B) */
+
+        switch(mode->HDisplay)
+	{
+      	case 512:
+		if(mode->VDisplay == 384) {
+		   ModeIndex = ModeIndex_512x384[i];
+		}
+		break;
+	case 640:
+		if(mode->VDisplay == 480) {
+		   ModeIndex = ModeIndex_640x480[i];
+		}
+		break;
+	case 720:
+                if(mode->VDisplay == 480) {
+                   ModeIndex = ModeIndex_720x480[i];
+                } else if(mode->VDisplay == 576) {
+                   ModeIndex = ModeIndex_720x576[i];
+                }
+                break;
+	case 800:
+		if(mode->VDisplay == 600) {
+		   ModeIndex = ModeIndex_800x600[i];
+		}
+		break;
+	case 1024:
+		if(mode->VDisplay == 768) {
+		   if(VBFlags & (VB_301B|VB_301LV|VB_302B|VB_302LV)) {
+		      ModeIndex = ModeIndex_1024x768[i];
+		   }
+		}
+		break;
+        }
+
+      }
+
+   } else if(VBFlags & CRT2_VGA) {		/* CRT2 is VGA2 */
+
+	switch(mode->HDisplay)
+	{
+	case 512:
+		if(mode->VDisplay == 384) {
+		    ModeIndex = ModeIndex_512x384[i];
+		}
+		break;
+	case 640:
+		if(mode->VDisplay == 480) {
+		   ModeIndex = ModeIndex_640x480[i];
+		}
+		break;
+	case 800:
+		if(mode->VDisplay == 600) {
+		   ModeIndex = ModeIndex_800x600[i];
+		} else if(pSiS->VGAEngine == SIS_315_VGA) {
+		   if(mode->VDisplay == 480) {
+			ModeIndex = ModeIndex_800x480[i];
+		   }
+		}
+		break;
+	case 1024:
+		if(mode->VDisplay == 768) {
+			ModeIndex = ModeIndex_1024x768[i];
+		} else if(pSiS->VGAEngine == SIS_315_VGA) {
+		   if(mode->VDisplay == 576) {
+			ModeIndex = ModeIndex_1024x576[i];
+		   }
+		}
+		break;
+	case 1152:
+		if(pSiS->VGAEngine == SIS_300_VGA) {
+		   if(mode->VDisplay == 768) {
+			ModeIndex = ModeIndex_1152x768[i];
+		   }
+		}
+		break;
+	case 1280:
+		if (mode->VDisplay == 1024) {
+		   ModeIndex = ModeIndex_1280x1024[i];
+		} else if(pSiS->VGAEngine == SIS_315_VGA) {
+		   if (mode->VDisplay == 768) {
+			ModeIndex = ModeIndex_1280x768[i];
+		   } else if (mode->VDisplay == 720) {
+			ModeIndex = ModeIndex_1280x720[i];
+		   }
+		}
+		break;
+	case 1400:
+		if(pSiS->VGAEngine == SIS_315_VGA) {
+		   ModeIndex = ModeIndex_1400x1050[i];
+		}
+		break;
 	}
-	// SiSInit(&HwDeviceExtension);
-	SiSSetMode (&HwDeviceExtension, ModeNo);
 
+   } else {				/* CRT1 only, no CRT2 */
+
+       ModeIndex = SiS_CalcModeIndex(pScrn, mode);
+
+   }
+
+   return(ModeIndex);
+}
+
+#define MODEID_OFF 0x449
+
+unsigned char
+SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
+{
+    unsigned char ret;
+
+    unsigned char* base = xf86MapVidMem(pScrn->scrnIndex,
+					VIDMEM_MMIO, 0, 0x2000);
+    ret = *(base + MODEID_OFF);
+
+    /* id != 0xff means: set mode */
+    if (id != 0xff)
+	*(base + MODEID_OFF) = id;
+    xf86UnMapVidMem(pScrn->scrnIndex,base,0x2000);
+
+    return ret;
 }
+
 #endif
+
+
+
diff -Nru a/drivers/video/sis/init.h b/drivers/video/sis/init.h
--- a/drivers/video/sis/init.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/sis/init.h	Wed Jul 24 14:03:37 2002
@@ -6,222 +6,328 @@
 #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"
+#include "xf86PciInfo.h"
+#include "xf86_OSproc.h"
+#include "sis.h"
+#include "sis_regs.h"
+#endif
+
+#ifdef LINUX_KERNEL
 #include <linux/types.h>
 #include <asm/io.h>
 #include <linux/sisfb.h>
+#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
 
+USHORT SiS_DRAMType[17][5]={
+	{0x0C,0x0A,0x02,0x40,0x39},
+	{0x0D,0x0A,0x01,0x40,0x48},
+	{0x0C,0x09,0x02,0x20,0x35},
+	{0x0D,0x09,0x01,0x20,0x44},
+	{0x0C,0x08,0x02,0x10,0x31},
+	{0x0D,0x08,0x01,0x10,0x40},
+	{0x0C,0x0A,0x01,0x20,0x34},
+	{0x0C,0x09,0x01,0x08,0x32},
+	{0x0B,0x08,0x02,0x08,0x21},
+	{0x0C,0x08,0x01,0x08,0x30},
+	{0x0A,0x08,0x02,0x04,0x11},
+	{0x0B,0x0A,0x01,0x10,0x28},
+	{0x09,0x08,0x02,0x02,0x01},
+	{0x0B,0x09,0x01,0x08,0x24},
+	{0x0B,0x08,0x01,0x04,0x20},
+	{0x0A,0x08,0x01,0x02,0x10},
+	{0x09,0x08,0x01,0x01,0x00}
+};
+
+USHORT SiS_SDRDRAM_TYPE[13][5] =
+{
+	{ 2,12, 9,64,0x35},
+	{ 1,13, 9,64,0x44},
+	{ 2,12, 8,32,0x31},
+	{ 2,11, 9,32,0x25},
+	{ 1,12, 9,32,0x34},
+	{ 1,13, 8,32,0x40},
+	{ 2,11, 8,16,0x21},
+	{ 1,12, 8,16,0x30},
+	{ 1,11, 9,16,0x24},
+	{ 1,11, 8, 8,0x20},
+	{ 2, 9, 8, 4,0x01},
+	{ 1,10, 8, 4,0x10},
+	{ 1, 9, 8, 2,0x00}
+};
 
-USHORT SiS_DRAMType[17][5] = { 
-	{0x0C, 0x0A, 0x02, 0x40, 0x39},
-	{0x0D, 0x0A, 0x01, 0x40, 0x48},
-	{0x0C, 0x09, 0x02, 0x20, 0x35},
-	{0x0D, 0x09, 0x01, 0x20, 0x44},
-	{0x0C, 0x08, 0x02, 0x10, 0x31},
-	{0x0D, 0x08, 0x01, 0x10, 0x40},
-	{0x0C, 0x0A, 0x01, 0x20, 0x34},
-	{0x0C, 0x09, 0x01, 0x08, 0x32},
-	{0x0B, 0x08, 0x02, 0x08, 0x21},
-	{0x0C, 0x08, 0x01, 0x08, 0x30},
-	{0x0A, 0x08, 0x02, 0x04, 0x11},
-	{0x0B, 0x0A, 0x01, 0x10, 0x28},
-	{0x09, 0x08, 0x02, 0x02, 0x01},
-	{0x0B, 0x09, 0x01, 0x08, 0x24},
-	{0x0B, 0x08, 0x01, 0x04, 0x20},
-	{0x0A, 0x08, 0x01, 0x02, 0x10},
-	{0x09, 0x08, 0x01, 0x01, 0x00}
-};
-
-USHORT SiS_SDRDRAM_TYPE[13][5] = {
-	{2, 12, 9, 64, 0x35},
-	{1, 13, 9, 64, 0x44},
-	{2, 12, 8, 32, 0x31},
-	{2, 11, 9, 32, 0x25},
-	{1, 12, 9, 32, 0x34},
-	{1, 13, 8, 32, 0x40},
-	{2, 11, 8, 16, 0x21},
-	{1, 12, 8, 16, 0x30},
-	{1, 11, 9, 16, 0x24},
-	{1, 11, 8, 8, 0x20},
-	{2, 9, 8, 4, 0x01},
-	{1, 10, 8, 4, 0x10},
-	{1, 9, 8, 2, 0x00}
-};
-
-USHORT SiS_DDRDRAM_TYPE[4][5] = {
-	{2, 12, 9, 64, 0x35},
-	{2, 12, 8, 32, 0x31},
-	{2, 11, 8, 16, 0x21},
-	{2, 9, 8, 4, 0x01}
+USHORT SiS_DDRDRAM_TYPE[4][5] =
+{
+	{ 2,12, 9,64,0x35},
+	{ 2,12, 8,32,0x31},
+	{ 2,11, 8,16,0x21},
+	{ 2, 9, 8, 4,0x01}
 };
 
 UCHAR SiS_ChannelAB, SiS_DataBusWidth;
 
-USHORT SiS_MDA_DAC[] = { 
-	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,
-	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
-};
-
-USHORT SiS_CGA_DAC[] = { 
-	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,
-	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
-};
-
-USHORT SiS_EGA_DAC[] = { 
-	0x00, 0x10, 0x04, 0x14, 0x01, 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
-};
-
-USHORT SiS_VGA_DAC[] = { 
-	0x00, 0x10, 0x04, 0x14, 0x01, 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, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
-	0x0B, 0x0C, 0x0D, 0x0F, 0x10
-};
-
-USHORT SiS_P3c4, SiS_P3d4, SiS_P3c0, SiS_P3ce, SiS_P3c2;
-USHORT SiS_P3ca, SiS_P3c6, SiS_P3c7, SiS_P3c8, SiS_P3c9, SiS_P3da;
-USHORT SiS_Part1Port, SiS_Part2Port;
-USHORT SiS_Part3Port, SiS_Part4Port, SiS_Part5Port;
-USHORT SiS_CRT1Mode;
-
-USHORT flag_clearbuffer;	/*0: no clear frame buffer 1:clear frame buffer  */
-int SiS_RAMType;		/*int      ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex; */
-USHORT SiS_ModeType;
-USHORT SiS_IF_DEF_LVDS, SiS_IF_DEF_TRUMPION, SiS_IF_DEF_DSTN;	/*add for dstn */
-USHORT SiS_IF_DEF_CH7005, SiS_IF_DEF_HiVision;
-USHORT SiS_VBInfo, SiS_LCDResInfo, SiS_LCDTypeInfo, SiS_LCDInfo, SiS_VBType;	/*301b */
-USHORT SiS_SelectCRT2Rate;
-
-extern USHORT SiS_SetFlag;
-
-void SiS_SetMemoryClock (ULONG ROMAddr);
-void SiS_SetDRAMModeRegister (ULONG ROMAddr);
-void SiS_SetDRAMSize_310 (PSIS_HW_DEVICE_INFO);
-void SiS_SetDRAMSize_300 (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT SiS_ChkBUSWidth_300 (ULONG FBAddress);
-UCHAR SiS_Get310DRAMType (ULONG ROMAddr);
-
-void SiS_Delay15us (ULONG);
-BOOLEAN SiS_SearchModeID (ULONG ROMAddr, USHORT ModeNo, USHORT * ModeIdIndex);
-BOOLEAN SiS_CheckMemorySize (ULONG ROMAddr,
-			     PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			     USHORT ModeNo, USHORT ModeIdIndex);
-UCHAR SiS_GetModePtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_SetSeqRegs (ULONG, USHORT StandTableIndex);
-void SiS_SetMiscRegs (ULONG, USHORT StandTableIndex);
-void SiS_SetCRTCRegs (ULONG, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		      USHORT StandTableIndex);
-void SiS_SetATTRegs (ULONG, USHORT StandTableIndex);
-void SiS_SetGRCRegs (ULONG, USHORT StandTableIndex);
-void SiS_ClearExt1Regs (void);
-void SiS_SetSync (ULONG ROMAddr, USHORT RefreshRateTableIndex);
-void SiS_SetCRT1CRTC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex);
-void SiS_SetCRT1VCLK (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      PSIS_HW_DEVICE_INFO, USHORT RefreshRateTableIndex);
-void SiS_SetVCLKState (ULONG ROMAddr, PSIS_HW_DEVICE_INFO, USHORT ModeNo,
-		       USHORT RefreshRateTableIndex);
-void SiS_LoadDAC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_DisplayOn (void);
-void SiS_SetCRT1ModeRegs (ULONG ROMAddr, PSIS_HW_DEVICE_INFO, USHORT ModeNo,
-			  USHORT ModeIdIndex, USHORT RefreshRateTableIndex);
-void SiS_WriteDAC (USHORT, USHORT, USHORT, USHORT);
-void SiS_GetVBType (USHORT BaseAddr);	/*301b */
-USHORT SiS_ChkBUSWidth (ULONG);
-USHORT SiS_GetModeIDLength (ULONG, USHORT);
-USHORT SiS_GetRefindexLength (ULONG, USHORT);
-void SiS_SetInterlace (ULONG ROMAddr, USHORT ModeNo,
-		       USHORT RefreshRateTableIndex);
-USHORT SiS_CalcDelay2 (ULONG, UCHAR);
-USHORT SiS_CalcDelay (ULONG, USHORT);
-void SiS_Set_LVDS_TRUMPION (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetCRT1Offset (ULONG, USHORT, USHORT, USHORT, PSIS_HW_DEVICE_INFO);
-void SiS_SetCRT1FIFO (ULONG, USHORT, PSIS_HW_DEVICE_INFO);
-void SiS_SetCRT1FIFO2 (ULONG, USHORT ModeNo, PSIS_HW_DEVICE_INFO,
-		       USHORT RefreshRateTableIndex);
-void SiS_CRT2AutoThreshold (USHORT BaseAddr);
-void SiS_ClearBuffer (PSIS_HW_DEVICE_INFO, USHORT ModeNo);
-void SiS_SetCRT1Group (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		       USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_DetectMonitor (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void SiS_GetSenseStatus (PSIS_HW_DEVICE_INFO HwDeviceExtension, ULONG ROMAddr);
-USHORT SiS_TestMonitorType (UCHAR R_DAC, UCHAR G_DAC, UCHAR B_DAC);
-USHORT SiS_SenseCHTV (VOID);
-BOOLEAN SiS_Sense (USHORT Part4Port, USHORT tempbx, USHORT tempcx);
-BOOLEAN SiS_GetPanelID (VOID);
-BOOLEAN SiS_GetLCDDDCInfo (PSIS_HW_DEVICE_INFO);
-USHORT SiS_SenseLCD (PSIS_HW_DEVICE_INFO);
-
-extern BOOLEAN SiS_SetCRT2Group301 (USHORT BaseAddr, ULONG ROMAddr,
-				    USHORT ModeNo,
-				    PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_PresetScratchregister (USHORT SiS_P3d4,
-				       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_UnLockCRT2 (PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			    USHORT BaseAddr);
-extern void SiS_LockCRT2 (PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			  USHORT BaseAddr);
-extern BOOLEAN SiS_BridgeIsOn (USHORT BaseAddr);
-extern BOOLEAN SiS_BridgeIsEnable (USHORT BaseAddr, PSIS_HW_DEVICE_INFO);
-extern void SiS_SetTVSystem301 (VOID);
-extern BOOLEAN SiS_GetLCDDDCInfo301 (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN SiS_GetSenseStatus301 (PSIS_HW_DEVICE_INFO HwDeviceExtension,
-				      USHORT BaseAddr, ULONG ROMAddr);
-extern USHORT SiS_GetVCLKLen (ULONG ROMAddr,
-			      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN SiS_SetCRT2Group302 (USHORT BaseAddr, ULONG ROMAddr,
-				    USHORT ModeNo,
-				    PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_GetVBInfo301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-			      USHORT ModeIdIndex,
-			      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN SiS_GetLCDResInfo301 (ULONG ROMAddr, USHORT P3d4, USHORT ModeNo,
-				     USHORT ModeIdIndex);
-extern USHORT SiS_VBInfo, LCDResInfo, LCDTypeInfo, LCDInfo;
-extern USHORT SiS_GetRatePtrCRT2 (ULONG ROMAddr, USHORT ModeNo,
-				  USHORT ModeIdIndex);
-extern void SiS_LongWait (VOID);
-extern void SiS_SetRegANDOR (USHORT Port, USHORT Index, USHORT DataAND,
-			     USHORT DataOR);
-extern USHORT SiS_GetResInfo (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-extern void SiS_SetCH7005 (USHORT tempax);
-extern USHORT SiS_GetCH7005 (USHORT tempax);
-extern BOOLEAN SiS_GetLVDSCRT1Ptr (ULONG ROMAddr, USHORT ModeNo,
-				   USHORT ModeIdIndex,
-				   USHORT RefreshRateTableIndex,
-				   USHORT * ResInfo, USHORT * DisplayType);
-extern BOOLEAN SiS_GetLCDACRT1Ptr (ULONG ROMAddr, USHORT ModeNo,
-				   USHORT ModeIdIndex,
-				   USHORT RefreshRateTableIndex,
-				   USHORT * ResInfo, USHORT * DisplayType);
-extern USHORT SiS_GetVCLK2Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			       USHORT RefreshRateTableIndex,
-			       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN SiS_Is301B (USHORT BaseAddr);	/*301b */
+USHORT SiS_MDA_DAC[] =
+{
+	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,
+        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
+};
 
+USHORT SiS_CGA_DAC[] =
+{
+        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,
+        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
+};
+
+USHORT SiS_EGA_DAC[] =
+{
+        0x00,0x10,0x04,0x14,0x01,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
+};
+
+USHORT SiS_VGA_DAC[] =
+{
+	0x00,0x10,0x04,0x14,0x01,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,0x08,0x0A,0x0C,0x0E,0x10,
+	0x0B,0x0C,0x0D,0x0F,0x10
+};
+
+USHORT   SiS_P3c4,SiS_P3d4,SiS_P3c0,SiS_P3ce,SiS_P3c2;
+USHORT   SiS_P3ca,SiS_P3c6,SiS_P3c7,SiS_P3c8,SiS_P3c9,SiS_P3da;
+USHORT   SiS_Part1Port,SiS_Part2Port;
+USHORT   SiS_Part3Port,SiS_Part4Port,SiS_Part5Port;
+USHORT   SiS_CRT1Mode;
+
+USHORT   flag_clearbuffer;
+int      SiS_RAMType;
+USHORT   SiS_ModeType;
+USHORT   SiS_IF_DEF_LVDS, SiS_IF_DEF_TRUMPION, SiS_IF_DEF_DSTN, SiS_IF_DEF_FSTN;
+USHORT   SiS_IF_DEF_CH70xx, SiS_IF_DEF_HiVision;
+USHORT	 SiS_Backup70xx=0xff;
+USHORT   SiS_VBInfo, SiS_LCDResInfo, SiS_LCDTypeInfo, SiS_LCDInfo, SiS_VBType;
+USHORT   SiS_VBExtInfo, SiS_HiVision;
+USHORT   SiS_SelectCRT2Rate;
+
+extern   USHORT   SiS_SetFlag;
+extern   USHORT   SiS_DDC_Port;
+extern   USHORT   Panel800x600,  Panel1024x768,  Panel1280x1024, Panel1600x1200;
+extern   USHORT   Panel1280x960, Panel1400x1050, Panel320x480,   Panel1152x768;
+extern   USHORT   Panel1152x864, Panel1280x768,  Panel1024x600,  Panel640x480;
+extern   USHORT   PanelMinLVDS,  PanelMin301,    PanelMax;
+extern   USHORT   SiS_ChrontelInit;
+
+void     SiS_SetReg1(USHORT, USHORT, USHORT);
+void     SiS_SetReg2(USHORT, USHORT, USHORT);
+void     SiS_SetReg3(USHORT, USHORT);
+void     SiS_SetReg4(USHORT, ULONG);
+UCHAR    SiS_GetReg1(USHORT, USHORT);
+UCHAR    SiS_GetReg2(USHORT);
+ULONG    SiS_GetReg3(USHORT);
+void     SiS_ClearDAC(ULONG);
+void     SiS_SetMemoryClock(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetDRAMModeRegister(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_SearchVBModeID(UCHAR *ROMAddr, USHORT *ModeNo);
+void     SiS_IsLowResolution(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+ULONG    GetDRAMSize(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+#ifdef SIS300
+void     InitTo300Pointer(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetDRAMSize_300(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_ChkBUSWidth_300(ULONG FBAddress);
+#endif
+
+#ifdef SIS315H
+void     InitTo310Pointer(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+UCHAR    SiS_Get310DRAMType(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_DDR_MRS(void);
+void     SiS_SDR_MRS(void);
+void     SiS_DisableRefresh(void);
+void     SiS_EnableRefresh(UCHAR *ROMAddr);
+void     SiS_SetDRAMSize_310(PSIS_HW_DEVICE_INFO);
+void     SiS_DisableChannelInterleaving(int index,USHORT SiS_DDRDRAM_TYPE[][5]);
+void     SiS_SetDRAMSizingType(int index,USHORT DRAMTYPE_TABLE[][5]);
+void     SiS_CheckBusWidth_310(UCHAR *ROMAddress,ULONG FBAddress,
+                               PSIS_HW_DEVICE_INFO HwDeviceExtension);
+int      SiS_SetRank(int index,UCHAR RankNo,UCHAR SiS_ChannelAB,USHORT DRAMTYPE_TABLE[][5]);
+int      SiS_SetDDRChannel(int index,UCHAR ChannelNo,UCHAR SiS_ChannelAB,
+                           USHORT DRAMTYPE_TABLE[][5]);
+int      SiS_CheckColumn(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_CheckBanks(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_CheckRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_CheckDDRRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_CheckRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_CheckDDRRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_SDRSizing(ULONG FBAddress);
+int      SiS_DDRSizing(ULONG FBAddress);
+int      Is315E(void);
+void     SiS_VerifyMclk(ULONG FBAddr);
+#endif
+
+void     SetEnableDstn(void);
+void     SiS_Delay15us(ULONG);
+BOOLEAN  SiS_SearchModeID(UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
+BOOLEAN  SiS_CheckMemorySize(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                             USHORT ModeNo,USHORT ModeIdIndex);
+UCHAR    SiS_GetModePtr(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_SetSeqRegs(UCHAR *ROMAddr,USHORT StandTableIndex);
+void     SiS_SetMiscRegs(UCHAR *ROMAddr,USHORT StandTableIndex);
+void     SiS_SetCRTCRegs(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                         USHORT StandTableIndex);
+void     SiS_SetATTRegs(UCHAR *ROMAddr,USHORT StandTableIndex,USHORT ModeNo,
+                        PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetGRCRegs(UCHAR *ROMAddr,USHORT StandTableIndex);
+void     SiS_ClearExt1Regs(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetSync(UCHAR *ROMAddr,USHORT RefreshRateTableIndex);
+void     SiS_SetCRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                         USHORT RefreshRateTableIndex,
+			 PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_ResetCRT1VCLK(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT1VCLK(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO,
+                         USHORT RefreshRateTableIndex);
+void     SiS_SetVCLKState(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO, USHORT ModeNo,
+                          USHORT RefreshRateTableIndex, USHORT ModeIdIndex);
+void     SiS_LoadDAC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_DisplayOn(void);
+void 	 SiS_DisplayOff(void);
+void     SiS_SetCRT1ModeRegs(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO,USHORT ModeNo,
+                             USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_WriteDAC(USHORT, USHORT, USHORT, USHORT);
+void     SiS_GetVBType(USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+USHORT   SiS_ChkBUSWidth(UCHAR *ROMAddr);
+USHORT   SiS_GetModeIDLength(UCHAR *ROMAddr, USHORT);
+USHORT   SiS_GetRefindexLength(UCHAR *ROMAddr, USHORT);
+void     SiS_SetInterlace(UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex);
+USHORT   SiS_CalcDelay2(UCHAR *ROMAddr, UCHAR);
+USHORT   SiS_CalcDelay(UCHAR *ROMAddr, USHORT);
+void     SiS_Set_LVDS_TRUMPION(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT1Offset(UCHAR *ROMAddr,USHORT,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
+#ifdef SIS315H
+void     SiS_SetCRT1FIFO_310(UCHAR *ROMAddr,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
 #endif
+#ifdef SIS300
+void     SiS_SetCRT1FIFO_300(UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO,
+                             USHORT RefreshRateTableIndex);
+#endif
+void     SiS_ClearBuffer(PSIS_HW_DEVICE_INFO,USHORT ModeNo);
+void     SiS_SetCRT1Group(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                          USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr);
+void     SiS_DetectMonitor(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+void     SiS_GetSenseStatus(PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr);
+USHORT   SiS_TestMonitorType(UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC);
+USHORT   SiS_SenseCHTV(VOID);
+BOOLEAN  SiS_Sense(USHORT Part4Port,USHORT tempbx,USHORT tempcx);
+BOOLEAN  SiS_GetPanelID(VOID);
+BOOLEAN  SiS_GetLCDDDCInfo(PSIS_HW_DEVICE_INFO);
+USHORT   SiS_SenseLCD(PSIS_HW_DEVICE_INFO);
+void     SiSRegInit(USHORT BaseAddr);
+void     SiSInitPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiSSetLVDSetc(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo);
+void     SiSInitPCIetc(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+#ifdef LINUX_XF86
+USHORT  	SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
+USHORT  	SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
+void    	SiS_SetPitch(ScrnInfoPtr pScrn, UShort BaseAddr);
+void    	SiS_SetPitchCRT1(ScrnInfoPtr pScrn, UShort BaseAddr);
+void    	SiS_SetPitchCRT2(ScrnInfoPtr pScrn, UShort BaseAddr);
+unsigned char 	SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+#endif
+
+extern USHORT    SiS_GetOffset(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                       USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern USHORT    SiS_GetColorDepth(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+extern void      SiS_DisableBridge(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+extern BOOLEAN   SiS_SetCRT2Group301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                                     PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void      SiS_PresetScratchregister(USHORT SiS_P3d4,
+                                           PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void      SiS_UnLockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+extern void      SiS_LockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+extern BOOLEAN   SiS_BridgeIsOn(USHORT BaseAddr);
+extern BOOLEAN   SiS_BridgeIsEnable(USHORT BaseAddr,PSIS_HW_DEVICE_INFO );
+extern void      SiS_SetTVSystem301(VOID);
+extern BOOLEAN   SiS_GetLCDDDCInfo301(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_GetSenseStatus301(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                                       USHORT BaseAddr,UCHAR *ROMAddr);
+extern USHORT    SiS_GetVCLKLen(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_SetCRT2Group302(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                                     PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void      SiS_GetVBInfo301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                                  USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_GetLCDResInfo301(UCHAR *ROMAddr,USHORT P3d4,USHORT ModeNo,
+                                      USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void      SiS_SetHiVision(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+/* extern USHORT  SiS_VBInfo,LCDResInfo,LCDTypeInfo,LCDInfo; */  /* TW: redundant */
+extern USHORT    SiS_GetRatePtrCRT2(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+extern void      SiS_LongWait(VOID);
+extern void      SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR);
+extern void      SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND);
+extern void      SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR);
+extern USHORT    SiS_GetResInfo(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+extern void      SiS_SetCH700x(USHORT tempax);
+extern USHORT    SiS_GetCH700x(USHORT tempax);
+extern void      SiS_SetCH701x(USHORT tempax);
+extern USHORT    SiS_GetCH701x(USHORT tempax);
+extern void      SiS_SetCH70xx(USHORT tempax);
+extern USHORT    SiS_GetCH70xx(USHORT tempax);
+extern BOOLEAN   SiS_GetLVDSCRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                                    USHORT RefreshRateTableIndex,
+		                    USHORT *ResInfo,USHORT *DisplayType);
+extern BOOLEAN   SiS_GetLCDACRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                                    USHORT RefreshRateTableIndex,
+		                    USHORT *ResInfo,USHORT *DisplayType);
+extern USHORT    SiS_GetVCLK2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                                 USHORT RefreshRateTableIndex,
+				 PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_Is301B(USHORT BaseAddr);
+extern BOOLEAN   SiS_LowModeStuff(USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+#endif
+
diff -Nru a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
--- a/drivers/video/sis/init301.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/video/sis/init301.c	Wed Jul 24 14:03:35 2002
@@ -1,5416 +1,7708 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2000/12/02 01:16:16 dawes Exp $ */
+/* $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
+ * (Universal module for Linux kernel framebuffer, XFree86 4.x)
+ *
+ * Assembler-To-C translation
+ * Parts Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Based on BIOS
+ *     1.10.07, 1.10a for SiS650/LVDS+CH7019
+ *     1.07.1b for SiS650/301(B/LV)
+ *     2.04.50 (I) and 2.04.5c (II) for SiS630/301(B)
+ *     2.02.3b, 2.03.02, 2.04.2c and 2.04.5c for 630/LVDS/LVDS+CH7005
+ *     1.09b for 315/301(B)
+ *
+ * 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.
+ *
+ */
 
 #include "init301.h"
-#ifdef CONFIG_FB_SIS_300
+
+#if 0
+#define TWPANEL
+#endif
+
+#if 0	/* TW: Emulate 650/LVDS BIOS 1.10a (1) or 1.10.07 (0) */
+#define TEST1400
+#endif
+
+#ifdef SIS300
 #include "oem300.h"
 #endif
-#ifdef CONFIG_FB_SIS_315
+
+#ifdef SIS315H
 #include "oem310.h"
 #endif
 
+#define SiS_I2CDELAY 1000
+#define SiS_I2CDELAYSHORT 333
+
 BOOLEAN
-SiS_SetCRT2Group301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		     PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetCRT2Group301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT ModeIdIndex;
-	USHORT RefreshRateTableIndex;
+   USHORT ModeIdIndex;
+   USHORT RefreshRateTableIndex;
 
-	SiS_SetFlag = SiS_SetFlag | ProgrammingCRT2;
-	SiS_SearchModeID (ROMAddr, ModeNo, &ModeIdIndex);
-	SiS_SelectCRT2Rate = 4;
-	RefreshRateTableIndex =
-	    SiS_GetRatePtrCRT2 (ROMAddr, ModeNo, ModeIdIndex);
-	SiS_SaveCRT2Info (ModeNo);
-	SiS_DisableBridge (HwDeviceExtension, BaseAddr);
-	SiS_UnLockCRT2 (HwDeviceExtension, BaseAddr);
-	SiS_SetCRT2ModeRegs (BaseAddr, ModeNo, HwDeviceExtension);
-	if (SiS_VBInfo & DisableCRT2Display) {
-		SiS_LockCRT2 (HwDeviceExtension, BaseAddr);
-		SiS_DisplayOn ();
-		return (FALSE);
-	}
-/* SetDefCRT2ExtRegs(BaseAddr);   */
-	SiS_GetCRT2Data (ROMAddr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		SiS_GetLVDSDesData (ROMAddr, ModeNo, ModeIdIndex,
-				    RefreshRateTableIndex);
-	}
-	/*end 301b */
-	if (SiS_IF_DEF_LVDS == 1) {
-		SiS_GetLVDSDesData (ROMAddr, ModeNo, ModeIdIndex,
-				    RefreshRateTableIndex);
-	}
-
-	SiS_SetGroup1 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-		       HwDeviceExtension, RefreshRateTableIndex);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA) && (SiS_IF_DEF_LVDS == 0)) {
-	} else if (SiS_IF_DEF_LVDS == 0 && (!(SiS_VBInfo & SetCRT2ToLCDA))) {
-		SiS_SetGroup2 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-			       RefreshRateTableIndex, HwDeviceExtension);
-		SiS_SetGroup3 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-			       HwDeviceExtension);
-		SiS_SetGroup4 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-			       RefreshRateTableIndex, HwDeviceExtension);
-		SiS_SetGroup5 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex);
-	} else {
-		if (SiS_IF_DEF_CH7005 == 1) {
-			SiS_SetCHTVReg (ROMAddr, ModeNo, ModeIdIndex,
-					RefreshRateTableIndex);
-		}
-		SiS_ModCRT1CRTC (ROMAddr, ModeNo, ModeIdIndex,
-				 RefreshRateTableIndex);
-		SiS_SetCRT2ECLK (ROMAddr, ModeNo, ModeIdIndex,
-				 RefreshRateTableIndex, HwDeviceExtension);
-	}
-
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730) ||
-	    (HwDeviceExtension->jChipType == SIS_300))
-		SiS_OEM300Setting (HwDeviceExtension, BaseAddr, ROMAddr,
-				   ModeNo);
-
-#endif
+   SiS_SetFlag |= ProgrammingCRT2;
 
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||	/* 05/02/01 ynlai for sis550 */
-	    (HwDeviceExtension->jChipType == SIS_315PRO) ||
-	    (HwDeviceExtension->jChipType == SIS_550) ||	/* 05/02/01 ynlai for 550 */
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740)) {	/* 09/03/01 chiawen for 640/740 */
-		SiS_OEM310Setting (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo,
-				   ModeIdIndex);
-		SiS_CRT2AutoThreshold (BaseAddr);
+   SiS_SearchModeID(ROMAddr,&ModeNo,&ModeIdIndex);
+
+   /* TW: Used for shifting CR33 */
+   SiS_SelectCRT2Rate = 4;
+
+   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+
+   RefreshRateTableIndex = SiS_GetRatePtrCRT2(ROMAddr,ModeNo,ModeIdIndex);
+
+   SiS_SaveCRT2Info(ModeNo);
+
+   if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
+      SiS_DisableBridge(HwDeviceExtension,BaseAddr);
+      SiS_SetCRT2ModeRegs(BaseAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+   }
+
+   if(SiS_VBInfo & DisableCRT2Display) {
+      SiS_LockCRT2(HwDeviceExtension, BaseAddr);
+      SiS_DisplayOn();
+      return(FALSE);
+   }
+
+   SiS_GetCRT2Data(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                   HwDeviceExtension);
+
+   /* LVDS, 650/301LV(LCDA) and 630/301B BIOS set up Panel Link */
+   if((SiS_IF_DEF_LVDS == 1) || (SiS_VBType & VB_SIS301BLV302BLV)) {
+   	SiS_GetLVDSDesData(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+	                   HwDeviceExtension);
+   }
+
+   if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
+      SiS_SetGroup1(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+                    HwDeviceExtension,RefreshRateTableIndex);
+   }
+
+   if( (SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCDA) ) {
+
+     	if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV))
+	      	SiS_SetReg1(SiS_Part4Port,0x24,0x0e);
+
+   } else if((SiS_IF_DEF_LVDS == 0) && (!(SiS_VBInfo & SetCRT2ToLCDA))) {
+
+        if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
+
+	   SiS_SetGroup2(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	              RefreshRateTableIndex,HwDeviceExtension);
+      	   SiS_SetGroup3(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	              HwDeviceExtension);
+      	   SiS_SetGroup4(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	              RefreshRateTableIndex,HwDeviceExtension);
+      	   SiS_SetGroup5(BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+
+	   /* TW: 630/301B BIOS does all this: */
+	   if(HwDeviceExtension->jChipType < SIS_315H) {
+	      if(SiS_VBType & VB_SIS301BLV302BLV) {
+	         if(SiS_VBInfo & SetCRT2ToLCD) {
+		    if(SiS_LCDResInfo != Panel640x480) {
+		       SiS_ModCRT1CRTC(ROMAddr,ModeNo,ModeIdIndex,
+		                       RefreshRateTableIndex,HwDeviceExtension);
+                    }
+		    SiS_SetCRT2ECLK(ROMAddr,ModeNo,ModeIdIndex,
+		                    RefreshRateTableIndex,HwDeviceExtension);
+		 }
+              }
+	   }
+
+        }
+
+   } else {
+
+        if(SiS_LCDResInfo != Panel640x480) {
+	        if (SiS_IF_DEF_TRUMPION == 0) {
+    	 	        SiS_ModCRT1CRTC(ROMAddr,ModeNo,ModeIdIndex,
+		                        RefreshRateTableIndex,HwDeviceExtension);
+	        }
+	}
+        if(SiS_IF_DEF_FSTN == 0) {
+     	 	SiS_SetCRT2ECLK(ROMAddr,ModeNo,ModeIdIndex,
+		          RefreshRateTableIndex,HwDeviceExtension);
+	}
+	if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
+     	  if(SiS_IF_DEF_CH70xx != 0) {
+	     /* TW: Inserted from 650/LVDS BIOS */
+	     if (SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+	        if(SiS_IF_DEF_CH70xx == 2) {
+		    SiS_SetCHTVForLCD(HwDeviceExtension,BaseAddr);
+		}
+	     }
+	     if(SiS_VBInfo & SetCRT2ToTV) {
+	        /* TW: Set Chrontel registers only if CRT2 is TV */
+       		SiS_SetCHTVReg(ROMAddr,ModeNo,ModeIdIndex,
+		               RefreshRateTableIndex);
+	     }
+     	  }
+	}
+
+   }
+
+#ifdef SIS300
+   if ( (HwDeviceExtension->jChipType==SIS_540)||
+        (HwDeviceExtension->jChipType==SIS_630)||
+        (HwDeviceExtension->jChipType==SIS_730)||
+        (HwDeviceExtension->jChipType==SIS_300) )
+    {
+	if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
+       	   SiS_OEM300Setting(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
 	}
+    }
 #endif
 
-	SiS_EnableBridge (HwDeviceExtension, BaseAddr);
-	SiS_DisplayOn ();
-	SiS_LockCRT2 (HwDeviceExtension, BaseAddr);
-	return 1;
-}
-
-void
-SiS_SetGroup1 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-	       USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-	       USHORT RefreshRateTableIndex)
-{
-	USHORT temp = 0, tempax = 0, tempbx = 0, tempcx = 0;
-	USHORT pushbx = 0, CRT1Index = 0;
-	USHORT modeflag, resinfo = 0;
-
-	if (ModeNo <= 0x13) {
-	} else {
-		CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		CRT1Index = CRT1Index & 0x3F;
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	}
+#ifdef SIS315H
+   if ( (HwDeviceExtension->jChipType==SIS_315H)||
+        (HwDeviceExtension->jChipType==SIS_315PRO)||
+        (HwDeviceExtension->jChipType==SIS_550) ||
+        (HwDeviceExtension->jChipType==SIS_640) ||
+        (HwDeviceExtension->jChipType==SIS_740) ||
+        (HwDeviceExtension->jChipType==SIS_650))
+   {
+        if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
+	   SiS_OEMLCD(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+           SiS_OEM310Setting(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+           SiS_CRT2AutoThreshold(BaseAddr);
+        }
+   }
+#endif
 
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-	} else {
-		SiS_SetCRT2Offset (SiS_Part1Port, ROMAddr, ModeNo, ModeIdIndex,
-				   RefreshRateTableIndex, HwDeviceExtension);
-		if (HwDeviceExtension->jChipType < SIS_315H)	/* 300 series */
-			SiS_SetCRT2FIFO (SiS_Part1Port, ROMAddr, ModeNo,
-					 HwDeviceExtension);
-		else		/* 310 series */
-			SiS_SetCRT2FIFO2 (SiS_Part1Port, ROMAddr, ModeNo,
-					  HwDeviceExtension);
+   if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
+      SiS_DisplayOn();
+      SiS_EnableBridge(HwDeviceExtension,BaseAddr);
+   }
 
-		SiS_SetCRT2Sync (BaseAddr, ROMAddr, ModeNo,
-				 RefreshRateTableIndex);
-	}
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   if(SiS_IF_DEF_CH70xx == 1) {
+	if(SiS_VBInfo & SetCRT2ToTV) {
+	     /* TW: Disable LCD panel when using TV */
+	     SiS_SetRegOR(SiS_P3c4,0x11,0x0C);
 	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	     /* TW: Disable TV when using LCD */
+	     SiS_SetCH70xxANDOR(0x010E,0xF8);
 	}
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		SiS_SetGroup1_LCDA (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-				    HwDeviceExtension, RefreshRateTableIndex);
-	}
-	/*end 301b */
-	else if (HwDeviceExtension->jChipType < SIS_315H) {	/* 300 series */
-		temp = (SiS_VGAHT - 1) & 0x0FF;	/* BTVGA2HT 0x08,0x09 */
-		SiS_SetReg1 (SiS_Part1Port, 0x08, temp);
-		temp = (((SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x09, ~0x0F0, temp);
-
-		temp = (SiS_VGAHDE + 12) & 0x0FF;	/* BTVGA2HDEE 0x0A,0x0C */
-		SiS_SetReg1 (SiS_Part1Port, 0x0A, temp);
-
-		pushbx = SiS_VGAHDE + 12;	/* bx  BTVGA@HRS 0x0B,0x0C */
-		tempcx = (SiS_VGAHT - SiS_VGAHDE) >> 2;	/* cx */
-		tempbx = pushbx + tempcx;
-		tempcx = tempcx << 1;
-		tempcx = tempcx + tempbx;
-
-		if (SiS_IF_DEF_LVDS == 0) {
-			if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-				tempbx = SiS_CRT1Table[CRT1Index].CR[4];
-				tempbx =
-				    tempbx |
-				    ((SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) <<
-				     2);
-				tempbx = (tempbx - 1) << 3;
-				tempcx = SiS_CRT1Table[CRT1Index].CR[5];
-				tempcx = tempcx & 0x1F;
-				temp = SiS_CRT1Table[CRT1Index].CR[15];
-				temp = (temp & 0x04) << (6 - 2);
-				tempcx = ((tempcx | temp) - 1) << 3;
-			}
-		}
-		/*add for hardware request */
-		if ((SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)) {
-			if (SiS_VBInfo & SetPALTV) {
-				tempbx = 1040;
-				tempcx = 1042;
-			} else {
-				tempbx = 1040;
-				tempcx = 1042;
-			}
-		}
-
-		temp = tempbx & 0x00FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x0B, temp);
+   }
 
-	} else {		/* 310 series */
+   SiS_DisplayOn();
 
-		if (modeflag & HalfDCLK) {	/* for low resolution mode */
-			temp = (SiS_VGAHT / 2 - 1) & 0x0FF;	/* BTVGA2HT 0x08,0x09 */
-			SiS_SetReg1 (SiS_Part1Port, 0x08, temp);
-			temp = (((SiS_VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
-			SiS_SetRegANDOR (SiS_Part1Port, 0x09, ~0x0F0, temp);
-			temp = (SiS_VGAHDE / 2 + 16) & 0x0FF;	/* BTVGA2HDEE 0x0A,0x0C */
-			SiS_SetReg1 (SiS_Part1Port, 0x0A, temp);
-
-			pushbx = SiS_VGAHDE / 2 + 16;
-			tempcx = ((SiS_VGAHT - SiS_VGAHDE) / 2) >> 2;	/* cx */
-			tempbx = pushbx + tempcx;	/* bx  BTVGA@HRS 0x0B,0x0C */
-			tempcx = tempcx + tempbx;
-
-			if (SiS_IF_DEF_LVDS == 0) {
-				if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-					tempbx = SiS_CRT1Table[CRT1Index].CR[4];
-					tempbx =
-					    tempbx |
-					    ((SiS_CRT1Table
-					      [CRT1Index].CR[14] & 0xC0) << 2);
-					tempbx = (tempbx - 3) << 3;	/*(VGAHRS-3)*8 */
-					tempcx = SiS_CRT1Table[CRT1Index].CR[5];
-					tempcx = tempcx & 0x1F;
-					temp = SiS_CRT1Table[CRT1Index].CR[15];
-					temp = (temp & 0x04) << (5 - 2);	/*VGAHRE D[5] */
-					tempcx = ((tempcx | temp) - 3) << 3;	/* (VGAHRE-3)*8 */
-				}
-			}
-			tempbx += 4;
-			tempcx += 4;
-			if (tempcx > (SiS_VGAHT / 2))
-				tempcx = SiS_VGAHT / 2;
-			temp = tempbx & 0x00FF;
-			SiS_SetReg1 (SiS_Part1Port, 0x0B, temp);
+   if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
+      SiS_LockCRT2(HwDeviceExtension, BaseAddr);
+   }
 
-		} else {
-			temp = (SiS_VGAHT - 1) & 0x0FF;	/* BTVGA2HT 0x08,0x09 */
-			SiS_SetReg1 (SiS_Part1Port, 0x08, temp);
-			temp = (((SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
-			SiS_SetRegANDOR (SiS_Part1Port, 0x09, ~0x0F0, temp);
-			temp = (SiS_VGAHDE + 16) & 0x0FF;	/* BTVGA2HDEE 0x0A,0x0C */
-			SiS_SetReg1 (SiS_Part1Port, 0x0A, temp);
-
-			pushbx = SiS_VGAHDE + 16;
-			tempcx = (SiS_VGAHT - SiS_VGAHDE) >> 2;	/* cx */
-			tempbx = pushbx + tempcx;	/* bx  BTVGA@HRS 0x0B,0x0C */
-			tempcx = tempcx + tempbx;
-
-			if (SiS_IF_DEF_LVDS == 0) {
-				if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-					tempbx = SiS_CRT1Table[CRT1Index].CR[4];
-					tempbx =
-					    tempbx |
-					    ((SiS_CRT1Table
-					      [CRT1Index].CR[14] & 0xC0) << 2);
-					tempbx = (tempbx - 3) << 3;	/*(VGAHRS-3)*8 */
-					tempcx = SiS_CRT1Table[CRT1Index].CR[5];
-					tempcx = tempcx & 0x1F;
-					temp = SiS_CRT1Table[CRT1Index].CR[15];
-					temp = (temp & 0x04) << (5 - 2);	/*VGAHRE D[5] */
-					tempcx = ((tempcx | temp) - 3) << 3;	/* (VGAHRE-3)*8 */
-					tempbx += 16;
-					tempcx += 16;
+   return 1;
+}
 
-				}
-			}
-			if (tempcx > SiS_VGAHT)
-				tempcx = SiS_VGAHT;
-			/*add for hardware request */
-			if ((SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)) {
-				if (SiS_VBInfo & SetPALTV) {
-					tempbx = 1040;
-					tempcx = 1042;
-				} else {
-					tempbx = 1040;
-					tempcx = 1042;
-				}
-			}
-			temp = tempbx & 0x00FF;
-			SiS_SetReg1 (SiS_Part1Port, 0x0B, temp);
-		}
+/* TW: Checked with 650/LVDS (1.10.07) and 630+301B/LVDS BIOS */
+BOOLEAN
+SiS_LowModeStuff(USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+    USHORT temp,temp1,temp2;
 
+    if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
+         return(1);
+    temp = SiS_GetReg1(SiS_P3d4,0x11);
+    SiS_SetRegOR(SiS_P3d4,0x11,0x80);
+    temp1 = SiS_GetReg1(SiS_P3d4,0x00);
+    SiS_SetReg1(SiS_P3d4,0x00,0x55);
+    temp2 = SiS_GetReg1(SiS_P3d4,0x00);
+    SiS_SetReg1(SiS_P3d4,0x00,temp1);
+    SiS_SetReg1(SiS_P3d4,0x11,temp);
+    if(HwDeviceExtension->jChipType >= SIS_315H) {
+       if(temp2 == 0x55) return(0);
+       else return(1);
+    } else {
+       if(temp2 != 0x55) return(1);
+       else {
+          SiS_SetRegOR(SiS_P3d4,0x35,0x01);
+          return(0);
+       }
+    }
+}
+
+/* TW: Set Part1 registers */
+/* TW: Checked with 650/LVDS (1.10.07), 650/301LV (II) and 630/301B (II) BIOS */
+void
+SiS_SetGroup1(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+              PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
+{
+  USHORT  temp=0,tempax=0,tempbx=0,tempcx=0,tempbl=0;
+  USHORT  pushbx=0,CRT1Index=0;
+  USHORT  modeflag,resinfo=0;
+
+  if(ModeNo<=0x13) {
+	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+    	CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+
+  /* TW: Removed 301B301LV.. check here; LCDA exists with LVDS as well */
+  if(SiS_VBInfo & SetCRT2ToLCDA) {
+
+	   /* TW: From 650/LVDS BIOS; 301(B+LV) version does not set Sync  */
+	   if (SiS_IF_DEF_LVDS == 1) {
+	       SiS_SetCRT2Sync(BaseAddr,ROMAddr,ModeNo,
+                               RefreshRateTableIndex,HwDeviceExtension);
+	   }
+
+	   SiS_SetGroup1_LCDA(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+     	                   HwDeviceExtension,RefreshRateTableIndex);
+
+  } else {
+
+     if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+         (SiS_IF_DEF_LVDS == 1) &&
+	 (SiS_VBInfo & SetInSlaveMode)) {
+
+        SiS_SetCRT2Sync(BaseAddr,ROMAddr,ModeNo,
+                        RefreshRateTableIndex,HwDeviceExtension);
+
+     } else {
+
+        SiS_SetCRT2Offset(SiS_Part1Port,ROMAddr,ModeNo,ModeIdIndex,
+      		       RefreshRateTableIndex,HwDeviceExtension);
+
+        if (HwDeviceExtension->jChipType < SIS_315H ) {
+#ifdef SIS300
+    	      SiS_SetCRT2FIFO_300(ROMAddr,ModeNo,HwDeviceExtension);
+#endif
+        } else {
+#ifdef SIS315H
+              SiS_SetCRT2FIFO_310(ROMAddr,ModeNo,HwDeviceExtension);
+#endif
 	}
 
-	tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
-	tempbx = pushbx;
-	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
-	tempax = tempax | (tempbx & 0xFF00);
-	temp = (tempax & 0xFF00) >> 8;
-	SiS_SetReg1 (SiS_Part1Port, 0x0C, temp);
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x0D, temp);
-	tempcx = (SiS_VGAVT - 1);
-	temp = tempcx & 0x00FF;
-	if (SiS_IF_DEF_CH7005 == 1) {
-		if (SiS_VBInfo & 0x0C) {
-			temp--;
-		}
-	}
-	SiS_SetReg1 (SiS_Part1Port, 0x0E, temp);
-	tempbx = SiS_VGAVDE - 1;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x0F, temp);
-	temp = ((tempbx & 0xFF00) << 3) >> 8;
-	temp = temp | ((tempcx & 0xFF00) >> 8);
-	SiS_SetReg1 (SiS_Part1Port, 0x12, temp);
-
-	tempax = SiS_VGAVDE;
-	tempbx = SiS_VGAVDE;
-	tempcx = SiS_VGAVT;
-	tempbx = (SiS_VGAVT + SiS_VGAVDE) >> 1;	/*      BTVGA2VRS     0x10,0x11   */
-	tempcx = ((SiS_VGAVT - SiS_VGAVDE) >> 4) + tempbx + 1;	/*      BTVGA2VRE     0x11        */
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-			tempbx = SiS_CRT1Table[CRT1Index].CR[8];
-			temp = SiS_CRT1Table[CRT1Index].CR[7];
-			if (temp & 0x04)
-				tempbx = tempbx | 0x0100;
-			if (temp & 0x080)
-				tempbx = tempbx | 0x0200;
-			temp = SiS_CRT1Table[CRT1Index].CR[13];
-			if (temp & 0x08)
-				tempbx = tempbx | 0x0400;
-			temp = SiS_CRT1Table[CRT1Index].CR[9];
-			tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
-		}
-	}
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x10, temp);
-	temp = ((tempbx & 0xFF00) >> 8) << 4;
-	temp = ((tempcx & 0x000F) | (temp));
-	SiS_SetReg1 (SiS_Part1Port, 0x11, temp);
-	if (SiS_IF_DEF_LVDS == 0) {
-		temp = 0x20;
-		if (SiS_LCDResInfo == Panel1280x1024)
-			temp = 0x20;
-		if (SiS_LCDResInfo == Panel1280x960)
-			temp = 0x24;
-		if (SiS_VBInfo & SetCRT2ToTV)
-			temp = 0x08;
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-			if (SiS_VBInfo & SetInSlaveMode)
-				temp = 0x2c;
-			else
-				temp = 0x20;
-		}
-	} else {
-		temp = 0x20;
-	}
-	if (HwDeviceExtension->jChipType < SIS_315H)	/* 300 series */
-		SiS_SetRegANDOR (SiS_Part1Port, 0x13, ~0x03C, temp);
-	else {			/* 310 series */
+        SiS_SetCRT2Sync(BaseAddr,ROMAddr,ModeNo,
+                        RefreshRateTableIndex,HwDeviceExtension);
 
-		temp >>= 2;
-		temp = 0x11;	/*  ynlai 05/30/2001 for delay compenation  */
-		SiS_SetReg1 (SiS_Part1Port, 0x2D, temp);
-		/*SiS_SetRegANDOR(SiS_Part1Port,0x2D,~0x00F,temp); */
-		SiS_SetRegAND (SiS_Part1Port, 0x13, 0xEF);	/* BDirectLCD=0 for lcd ?? */
-		tempax = 0;
+	/* 1. Horizontal setup */
 
-		if (modeflag & DoubleScanMode)
-			tempax |= 0x80;
-		if (modeflag & HalfDCLK)
-			tempax |= 0x40;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x2C, ~0x0C0, tempax);
+        if (HwDeviceExtension->jChipType < SIS_315H ) {
 
-	}
+                /* ------------- 300 series --------------*/
 
-	if (SiS_IF_DEF_LVDS == 0) {	/*  301  */
-		SiS_SetGroup1_301 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-				   HwDeviceExtension, RefreshRateTableIndex);
-	} else {		/*  LVDS  */
-		SiS_SetGroup1_LVDS (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-				    HwDeviceExtension, RefreshRateTableIndex);
+    		temp = (SiS_VGAHT - 1) & 0x0FF;   			/* BTVGA2HT 0x08,0x09 */
+    		SiS_SetReg1(SiS_Part1Port,0x08,temp);                   /* TW: CRT2 Horizontal Total */
+
+    		temp = (((SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
+    		SiS_SetRegANDOR(SiS_Part1Port,0x09,0x0f,temp);          /* TW: CRT2 Horizontal Total Overflow [7:4] */
+
+    		temp = (SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
+    		SiS_SetReg1(SiS_Part1Port,0x0A,temp);                   /* TW: CRT2 Horizontal Display Enable End */
+
+    		pushbx = SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
+    		tempcx = (SiS_VGAHT - SiS_VGAHDE) >> 2;
+    		tempbx = pushbx + tempcx;
+    		tempcx <<= 1;
+    		tempcx += tempbx;
+
+    		if(SiS_IF_DEF_LVDS == 0) {
+      			if(SiS_VBInfo & SetCRT2ToRAMDAC){
+			        CRT1Index &= 0x3F;
+        			tempbx = SiS_CRT1Table[CRT1Index].CR[4];
+        			tempbx |= ((SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+        			tempbx = (tempbx - 1) << 3;
+        			tempcx = SiS_CRT1Table[CRT1Index].CR[5];
+        			tempcx &= 0x1F;
+        			temp = SiS_CRT1Table[CRT1Index].CR[15];
+        			temp = (temp & 0x04) << (6-2);
+        			tempcx = ((tempcx | temp) - 1) << 3;
+      			}
+
+    			if((SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+        			if(!(SiS_VBInfo & SetPALTV)){
+      					tempbx = 1040;
+      					tempcx = 1042;
+      				}
+    			}
+	        }
+
+    		temp = tempbx & 0x00FF;
+    		SiS_SetReg1(SiS_Part1Port,0x0B,temp);                   /* TW: CRT2 Horizontal Retrace Start */
+
+ 	} else {
+
+     	   /* ---------------------- 310 series ------------------*/    /* (BIOS label Gr1_301) */
+
+     	   if (modeflag & HalfDCLK) {  /* for low resolution modes */
+
+         	temp = ((SiS_VGAHT / 2) - 1) & 0xFF;                    /* BTVGA2HT 0x08,0x09 */
+         	SiS_SetReg1(SiS_Part1Port,0x08,temp);                   /* TW: CRT2 Horizontal Total */
+
+		temp = ((((SiS_VGAHT / 2) - 1) & 0xFF00) >> 8) << 4;
+        	SiS_SetRegANDOR(SiS_Part1Port,0x09,0x0F,temp);        /* TW: CRT2 Horizontal Total Overflow [7:4] */
+
+         	temp = ((SiS_VGAHDE / 2) + 16) & 0xFF;                  /* BTVGA2HDEE 0x0A,0x0C */
+         	SiS_SetReg1(SiS_Part1Port,0x0A,temp);                   /* TW: CRT2 Horizontal Display Enable End */
+
+         	pushbx = (SiS_VGAHDE / 2) + 16;
+         	tempcx = ((SiS_VGAHT - SiS_VGAHDE) / 2) >> 2;           /* cx */
+		if(SiS_IF_DEF_LVDS == 1)
+		           tempcx >>= 1;    /* TW: From LVDS 1.10.07; not done on 301(LV) */
+         	tempbx = pushbx + tempcx;                               /* bx  BTVGA@HRS 0x0B,0x0C */
+         	tempcx += tempbx;
+
+         	if(SiS_IF_DEF_LVDS == 0) {
+                   if(SiS_VBInfo & SetCRT2ToRAMDAC){
+                	tempbx = SiS_CRT1Table[CRT1Index].CR[4];
+                	tempbx |= ((SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+                	tempbx = (tempbx - 3) << 3;         		/*(VGAHRS-3)*8 */
+                	tempcx = SiS_CRT1Table[CRT1Index].CR[5];
+               		tempcx &= 0x1F;
+                	temp = SiS_CRT1Table[CRT1Index].CR[15];
+                	temp = (temp & 0x04) << (5-2);      		/* VGAHRE D[5]  */
+                	tempcx =((tempcx | temp) - 3) << 3;    		/* (VGAHRE-3)*8 */
+             	   }
+                   /* TW: The following is not done in 650/LVDS BIOS  */
+         	   tempbx += 4;
+         	   tempcx += 4;
+
+         	   if (tempcx > (SiS_VGAHT / 2))
+              		   tempcx = SiS_VGAHT / 2;
+         	}
+
+                temp = tempbx & 0x00FF;
+         	SiS_SetReg1(SiS_Part1Port,0x0B,temp);                  /* TW: CRT2 Horizontal Retrace Start */
+
+    	   } else {			/* for high resolution modes */
+
+         	temp = (SiS_VGAHT - 1) & 0xFF;                       	/* BTVGA2HT 0x08,0x09 */
+         	SiS_SetReg1(SiS_Part1Port,0x08,temp);                  /* TW: CRT2 Horizontal Total */
+
+         	temp = (((SiS_VGAHT - 1) & 0xFF00) >> 8 ) << 4;
+	 	SiS_SetRegANDOR(SiS_Part1Port,0x09,0x0F,temp);         /* TW: CRT2 Horizontal Total Overflow [7:4] */
+
+         	temp = (SiS_VGAHDE + 16) & 0xFF;                       /* BTVGA2HDEE 0x0A,0x0C */
+	 	SiS_SetReg1(SiS_Part1Port,0x0A,temp);                  /* TW: CRT2 Horizontal Display Enable End */
+
+         	pushbx = SiS_VGAHDE + 16;
+         	tempcx = (SiS_VGAHT - SiS_VGAHDE) >> 2;                /* cx */
+		if(SiS_IF_DEF_LVDS == 1)
+		           tempcx >>= 1;    /* TW: From LVDS 1.10.07; not done on 301(LV) */
+         	tempbx = pushbx + tempcx;                              /* bx  BTVGA@HRS 0x0B,0x0C */
+         	tempcx += tempbx;
+
+         	if(SiS_IF_DEF_LVDS==0) {
+             	   if(SiS_VBInfo & SetCRT2ToRAMDAC){
+                	tempbx = SiS_CRT1Table[CRT1Index].CR[4];
+                	tempbx |= ((SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+                	tempbx = (tempbx - 3) << 3;         		/*(VGAHRS-3)*8 */
+                	tempcx = SiS_CRT1Table[CRT1Index].CR[5];
+               		tempcx &= 0x1F;
+                	temp = SiS_CRT1Table[CRT1Index].CR[15];
+                	temp = (temp & 0x04) << (5-2);      		/* VGAHRE D[5] */
+                	tempcx = ((tempcx | temp) - 3) << 3;    	/* (VGAHRE-3)*8 */
+                	tempbx += 16;
+                	tempcx += 16;
+             	   }
+		   /* TW: The entire following section is not done in 650/LVDS BIOS */
+         	   if (tempcx > SiS_VGAHT)
+        		tempcx = SiS_VGAHT;
+
+         	   if((SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+             	      if(!(SiS_VBInfo & SetPALTV)){
+      		 	 tempbx = 1040;
+      		 	 tempcx = 1042;
+      	     	      }
+         	   }
+                }
+
+         	temp = tempbx & 0x00FF;
+	 	SiS_SetReg1(SiS_Part1Port,0x0B,temp);                 /* TW: CRT2 Horizontal Retrace Start */
+
+     	   } /* halfdclk */
+
+     	}  /* 310 series */
+
+  	/* TW: 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_Part1Port,0x0C,temp);                        /* TW: Overflow */
+
+  	temp = tempcx & 0x00FF;
+  	SiS_SetReg1(SiS_Part1Port,0x0D,temp);                        /* TW: CRT2 Horizontal Retrace End */
+
+  	/* 2. Vertical setup */
+
+  	tempcx = SiS_VGAVT - 1;
+  	temp = tempcx & 0x00FF;
+
+	/* TW: Matches 650/301LV, 650/LVDS, 630/LVDS(CLEVO), 630/LVDS(no-Ch7005) */
+        if(SiS_IF_DEF_LVDS == 1) {
+	     if(HwDeviceExtension->jChipType < SIS_315H) {
+	          if(SiS_IF_DEF_CH70xx != 0) {
+#ifndef TWPANEL
+		       if(SiS_VBInfo & (SetCRT2ToSVIDEO|SetCRT2ToAVIDEO)) {
+		           temp--;
+		       }
+#else
+		       temp--;
+#endif
+                  }
+	     } else {
+	          if(SiS_IF_DEF_CH70xx != 0) {
+ 		      temp--;
+                  }
+             }
+        }
+  	SiS_SetReg1(SiS_Part1Port,0x0E,temp);                        /* TW: CRT2 Vertical Total */
+
+  	tempbx = SiS_VGAVDE - 1;
+  	temp = tempbx & 0x00FF;
+  	SiS_SetReg1(SiS_Part1Port,0x0F,temp);                        /* TW: CRT2 Vertical Display Enable End */
+
+  	temp = ((tempbx & 0xFF00) << 3) >> 8;
+  	temp |= ((tempcx & 0xFF00) >> 8);
+  	SiS_SetReg1(SiS_Part1Port,0x12,temp);                        /* TW: Overflow (and HWCursor Test Mode) */
+
+	/* TW: For 650/LVDS */
+	if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 1)) {
+           tempbx++;
+   	   tempax = tempbx;
+	   tempcx++;
+	   tempcx = tempcx - tempax;
+	   tempcx >>= 2;
+	   tempbx = tempbx + tempcx;
+	   if(tempcx < 4) tempcx = 4;
+	   tempcx >>= 2;
+	   tempcx = tempcx + tempbx;
+	   tempcx++;
+	} else {
+	   /* TW: For 630/LVDS/301B and 650/301LV: */
+  	   tempbx = (SiS_VGAVT + SiS_VGAVDE) >> 1;                      /*  BTVGA2VRS     0x10,0x11   */
+  	   tempcx = ((SiS_VGAVT - SiS_VGAVDE) >> 4) + tempbx + 1;       /*  BTVGA2VRE     0x11        */
+	}
+
+  	if(SiS_IF_DEF_LVDS == 0) {
+    	   if(SiS_VBInfo & SetCRT2ToRAMDAC){
+      		tempbx = SiS_CRT1Table[CRT1Index].CR[8];
+      		temp = SiS_CRT1Table[CRT1Index].CR[7];
+      		if(temp & 0x04) tempbx |= 0x0100;
+      		if(temp & 0x80) tempbx |= 0x0200;
+      		temp = SiS_CRT1Table[CRT1Index].CR[13];
+      		if(temp & 0x08) tempbx |= 0x0400;
+      		temp = SiS_CRT1Table[CRT1Index].CR[9];
+      		tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
+    	   }
+  	}
+  	temp = tempbx & 0x00FF;
+  	SiS_SetReg1(SiS_Part1Port,0x10,temp);                        /* TW: CRT2 Vertical Retrace Start */
+
+  	temp = ((tempbx & 0xFF00) >> 8) << 4;
+  	temp |= (tempcx & 0x000F);
+  	SiS_SetReg1(SiS_Part1Port,0x11,temp);                        /* TW: CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+
+  	/* 3. Paneldelay */
+
+  	if (HwDeviceExtension->jChipType < SIS_315H ) {
+
+    	   /* ---------- 300 series -------------- */
+
+	   if(SiS_IF_DEF_LVDS == 0) {
+	        temp = 0x20;
+		if(SiS_LCDResInfo == Panel1280x960) temp = 0x24;     /* TW: Not in 630/301B BIOS */
+		if(SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
+		if(SiS_VBInfo & SetCRT2ToHiVisionTV) {		     /* TW: Not in 630/301B BIOS */
+      		    if(SiS_VBInfo & SetInSlaveMode) temp = 0x2c;     /* TW: Not in 630/301B BIOS */
+      		    else temp = 0x20;                                /* TW: Not in 630/301B BIOS */
+    	        }
+		if((ROMAddr) && (SiS_VBType & VB_SIS301BLV302BLV)) {
+		    if(ROMAddr[0x220] & 0x80) {
+		        if(SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV)) temp = ROMAddr[0x221];
+			else if(SiS_VBInfo & SetCRT2ToHiVisionTV) temp = ROMAddr[0x222];
+		        else if(SiS_LCDResInfo == Panel1280x1024) temp = ROMAddr[0x223];
+			else temp = ROMAddr[0x224];
+			temp &= 0x3c;
+		    }
+		}
+		if(HwDeviceExtension->pdc) {
+			temp = HwDeviceExtension->pdc & 0x3c;
+		}
+	   } else {
+	        temp = 0x20;
+		if(SiS_LCDResInfo == Panel640x480) temp = 0x04;
+		if(ROMAddr) {
+		    if(ROMAddr[0x220] & 0x80) {
+		        temp = ROMAddr[0x220] & 0x3c;
+		    }
+		}
+		if(HwDeviceExtension->pdc) {
+			temp = HwDeviceExtension->pdc & 0x3c;
+		}
+	   }
+
+    	   SiS_SetRegANDOR(SiS_Part1Port,0x13,~0x03C,temp);         /* TW: Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+	   /* TW: This register will be adapted according to LCD
+	    *     panel type later in the OEM setup functions.
+	    *     (Various panel types require a different delay
+	    *     such as Clevo 2202; however, on most panels,
+	    *     0x20 does nicely.)
+	    */
+
+  	} else {
+
+      	   /* ----------- 310/325 series ---------------*/
+	   if(SiS_IF_DEF_LVDS == 0) {
+                temp = 0x10;                                        /* TW: Modified (650/301 BIOS) */
+                if(SiS_LCDResInfo == Panel1024x768)  temp = 0x2c;   /* TW: Modified (650/301 BIOS) */
+    	        if(SiS_LCDResInfo == Panel1280x1024) temp = 0x20;
+    	        if(SiS_LCDResInfo == Panel1280x960)  temp = 0x24;
+		if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+      		   if(SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
+      		   else temp = 0x20;
+    	        }
+		tempbl = 0xF0;
+	   } else {
+	        temp = 0x00;
+		if(SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
+		tempbl = 0xF0;
+		if(!(SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
+	   }
+
+           if(SiS_IF_DEF_LVDS == 0) {
+                 temp >>= 2;         				    /* TW: Only in 650/301LV BIOS */
+	   }
+
+	   SiS_SetRegANDOR(SiS_Part1Port,0x2D,tempbl,temp);	    /* TW: Panel Link Delay Compensation */
+           /* TW: This register will be adapted according to LCD
+	    *     panel type later in the OEM setup functions.
+	    *     (Various panel types require a different delay)
+	    */
+
+    	   tempax = 0;
+    	   if (modeflag & DoubleScanMode) tempax |= 0x80;
+    	   if (modeflag & HalfDCLK)       tempax |= 0x40;
+    	   SiS_SetRegANDOR(SiS_Part1Port,0x2C,0x3f,tempax);
+
+  	}
+
+     }  /* Slavemode */
+
+     if(SiS_IF_DEF_LVDS == 0) {
+
+        /* TW: 630/301B BIOS sets up Panel Link, too! (650/LV does not) */
+        if( (SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCD)
+	                       && (HwDeviceExtension->jChipType < SIS_315H)) {
+
+	    SiS_SetGroup1_LVDS(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                       HwDeviceExtension,RefreshRateTableIndex);
+
+        } else if(SiS_VBInfo & SetInSlaveMode) {                              /* Inserted (650/301 BIOS) */
+
+    	    SiS_SetGroup1_301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                      HwDeviceExtension,RefreshRateTableIndex);
+        }
+
+     } else {
+
+        if(HwDeviceExtension->jChipType < SIS_315H) {
+	     SiS_SetGroup1_LVDS(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                        HwDeviceExtension,RefreshRateTableIndex);
+	} else {
+	    /* TW: For 650/LVDS */
+            if((!(SiS_VBInfo & SetCRT2ToTV)) || (SiS_VBInfo & SetInSlaveMode)) {
+    	         SiS_SetGroup1_LVDS(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                            HwDeviceExtension,RefreshRateTableIndex);
+            }
 	}
+
+     }
+   } /* LCDA */
 }
 
+/* TW: Checked against 650/301LV and 630/301B (II) BIOS */
 void
-SiS_SetGroup1_301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		   USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		   USHORT RefreshRateTableIndex)
+SiS_SetGroup1_301(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                  PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
 {
-	USHORT push1, push2;
-	USHORT tempax, tempbx, tempcx, temp;
-	USHORT resinfo, modeflag;
-	USHORT CRT1Index;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		CRT1Index = CRT1Index & 0x3F;
-	}
-
-	if (!(SiS_VBInfo & SetInSlaveMode)) {
-		return;
-	}
-	tempax = 0xFFFF;
-	if (!(SiS_VBInfo & SetCRT2ToTV)) {
-		tempax = SiS_GetVGAHT2 ();
-	}
-	if (modeflag & Charx8Dot)
-		tempcx = 0x08;
-	else
-		tempcx = 0x09;
-	if (tempax >= SiS_VGAHT) {
-		tempax = SiS_VGAHT;
-	}
-	if (modeflag & HalfDCLK) {
-		tempax = tempax >> 1;
-	}
-	tempax = (tempax / tempcx) - 5;
-	tempbx = tempax;
-	temp = 0xFF;		/* set MAX HT */
-	SiS_SetReg1 (SiS_Part1Port, 0x03, temp);
-
-	tempax = SiS_VGAHDE;	/* 0x04 Horizontal Display End */
-	if (modeflag & HalfDCLK)
-		tempax = tempax >> 1;
-	tempax = (tempax / tempcx) - 1;
-	tempbx = tempbx | ((tempax & 0x00FF) << 8);
-	temp = tempax & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x04, temp);
-
-	temp = (tempbx & 0xFF00) >> 8;
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		temp = temp + 2;
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-			if (resinfo == 7)
-				temp = temp - 2;
-		}
-	}
-	SiS_SetReg1 (SiS_Part1Port, 0x05, temp);	/* 0x05 Horizontal Display Start */
-	SiS_SetReg1 (SiS_Part1Port, 0x06, 0x03);	/* 0x06 Horizontal Blank end     */
-	/* 0x07 horizontal Retrace Start */
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		temp = (tempbx & 0x00FF) - 1;
-		if (!(modeflag & HalfDCLK)) {
-			temp = temp - 6;
-			if (SiS_SetFlag & TVSimuMode) {
-				temp = temp - 4;
-				if (ModeNo > 0x13)
-					temp = temp - 10;
-			}
-		}
-	} else {
-		tempcx = tempbx & 0x00FF;
-		tempbx = (tempbx & 0xFF00) >> 8;
-		tempcx = (tempcx + tempbx) >> 1;
-		temp = (tempcx & 0x00FF) + 2;
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			temp = temp - 1;
-			if (!(modeflag & HalfDCLK)) {
-				if ((modeflag & Charx8Dot)) {
-					temp = temp + 4;
-					if (SiS_VGAHDE >= 800) {
-						temp = temp - 6;
-					}
-				}
-			}
-		} else {
-			if (!(modeflag & HalfDCLK)) {
-				temp = temp - 4;
-				if (SiS_LCDResInfo != Panel1280x960) {
-					if (SiS_VGAHDE >= 800) {
-						temp = temp - 7;
-						if (SiS_ModeType == ModeEGA) {
-							if (SiS_VGAVDE == 1024) {
-								temp =
-								    temp + 15;
-								if
-								    (SiS_LCDResInfo
-								     !=
-								     Panel1280x1024)
-								{
-									temp =
-									    temp
-									    + 7;
-								}
-							}
-						}
-						if (SiS_VGAHDE >= 1280) {
-							if (SiS_LCDResInfo !=
-							    Panel1280x960) {
-								if (SiS_LCDInfo
-								    &
-								    LCDNonExpanding)
-								{
-									temp =
-									    temp
-									    +
-									    28;
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-	}
+  USHORT  push1,push2;
+  USHORT  tempax,tempbx,tempcx,temp;
+  USHORT  resinfo,modeflag;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+
+  /* TW: The following is only done if bridge is in slave mode: */
+
+  tempax = 0xFFFF;
+  if(!(SiS_VBInfo & SetCRT2ToTV))  tempax = SiS_GetVGAHT2();
+
+  /* TW: 630/301B does not check this flag, assumes it is set */
+  /*     650/LV BIOS does not check this either; so we set it... */
+  if(SiS_VBType & VB_SIS301BLV302BLV) {
+  	modeflag |= Charx8Dot;
+  }
+
+  if(modeflag & Charx8Dot) tempcx = 0x08;
+  else tempcx = 0x09;
+
+  if(tempax >= SiS_VGAHT) tempax = SiS_VGAHT;
+
+  if(modeflag & HalfDCLK) tempax >>= 1;
+
+  tempax = (tempax / tempcx) - 5;
+  tempbx = tempax & 0xFF;
+
+  temp = 0xFF;                                          /* set MAX HT */
+  SiS_SetReg1(SiS_Part1Port,0x03,temp);
+
+  tempax = SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
+  if(modeflag & HalfDCLK) tempax >>= 1;
+  tempax = (tempax / tempcx) - 1;
+  tempbx |= ((tempax & 0x00FF) << 8);
+  temp = tempax & 0xFF;
+  SiS_SetReg1(SiS_Part1Port,0x04,temp);
+
+  temp = (tempbx & 0xFF00) >> 8;
+  if(SiS_VBInfo & SetCRT2ToTV){
+        if(!(SiS_VBType & VB_SIS301BLV302BLV)) {        /* TW: Inserted from 650/301, 630/301 BIOS */
+    	    temp += 2;
+        }                                               /* TW: Inserted from 650/301, 630/301 BIOS */
+#ifdef oldHV
+    	if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+            if(resinfo == 7) temp -= 2;
+    	}
+#endif
+  }
+  SiS_SetReg1(SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
 
-	SiS_SetReg1 (SiS_Part1Port, 0x07, temp);	/* 0x07 Horizontal Retrace Start */
-	SiS_SetReg1 (SiS_Part1Port, 0x08, 0);	/* 0x08 Horizontal Retrace End   */
+  SiS_SetReg1(SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
 
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		if (SiS_SetFlag & TVSimuMode) {
-			if ((ModeNo == 0x06) || (ModeNo == 0x10)
-			    || (ModeNo == 0x11) || (ModeNo == 0x13)
-			    || (ModeNo == 0x0F)) {
-				SiS_SetReg1 (SiS_Part1Port, 0x07, 0x5b);
-				SiS_SetReg1 (SiS_Part1Port, 0x08, 0x03);
-			}
-			if ((ModeNo == 0x00) || (ModeNo == 0x01)) {
-				if (SiS_VBInfo & SetNTSCTV) {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x2A);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x61);
-				} else {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x2A);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x41);
-					SiS_SetReg1 (SiS_Part1Port, 0x0C, 0xF0);
-				}
-			}
-			if ((ModeNo == 0x02) || (ModeNo == 0x03)
-			    || (ModeNo == 0x07)) {
-				if (SiS_VBInfo & SetNTSCTV) {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x54);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x00);
-				} else {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x55);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x00);
-					SiS_SetReg1 (SiS_Part1Port, 0x0C, 0xF0);
-				}
-			}
-			if ((ModeNo == 0x04) || (ModeNo == 0x05)
-			    || (ModeNo == 0x0D) || (ModeNo == 0x50)) {
-				if (SiS_VBInfo & SetNTSCTV) {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x30);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x03);
-				} else {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x2f);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x02);
-				}
-			}
-		}
-	}
+#ifdef oldHV
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+    temp = (tempbx & 0x00FF) - 1;
+    if(!(modeflag & HalfDCLK)) {
+      temp -= 6;
+      if(SiS_SetFlag & TVSimuMode) {
+        temp -= 2;					/* Modified according to 650/301 BIOS; was 4 */
+        if(ModeNo > 0x13) temp -= 10;
+      }
+    }
+  } else {
+#endif
+    tempcx = tempbx & 0x00FF;
+    tempbx = (tempbx & 0xFF00) >> 8;
+    tempcx = (tempcx + tempbx) >> 1;
+    temp = (tempcx & 0x00FF) + 2;
+    if(SiS_VBInfo & SetCRT2ToTV){
+       temp--;
+       if(!(modeflag & HalfDCLK)){
+          if((modeflag & Charx8Dot)){
+             temp += 4;
+             if(SiS_VGAHDE >= 800) temp -= 6;
+	     /* TW: Inserted from 650/301 BIOS, 630/301B/301 don't do this */
+             if(HwDeviceExtension->jChipType >= SIS_315H) {
+	         if(SiS_VGAHDE == 800) temp += 2;
+             }
+          }
+       }
+    } else {
+       if(!(modeflag & HalfDCLK)){
+         temp -= 4;
+         if(SiS_LCDResInfo != Panel1280x960) {
+           if(SiS_VGAHDE >= 800){
+             temp -= 7;
+             if(SiS_ModeType == ModeEGA){                         /* 650/301LV does not do this */
+               if(SiS_VGAVDE == 1024){                            /* 650/301LV does not do this */
+                 temp += 15;                                      /* 650/301LV does not do this */
+                 if(SiS_LCDResInfo != Panel1280x1024) temp += 7;  /* 650/301LV does not do this */
+               }
+             }
+             if(SiS_VGAHDE >= 1280){
+               if(SiS_LCDResInfo != Panel1280x960) {
+                 if(SiS_LCDInfo & LCDNonExpanding) temp += 28;
+               }
+             }
+           }
+         }
+       }
+    }
+#ifdef oldHV
+  }
+#endif
+  SiS_SetReg1(SiS_Part1Port,0x07,temp);               	/* 0x07 Horizontal Retrace Start */
 
-	SiS_SetReg1 (SiS_Part1Port, 0x18, 0x03);	/* 0x18 SR08                     */
-	SiS_SetRegANDOR (SiS_Part1Port, 0x19, 0xF0, 0x00);
-	SiS_SetReg1 (SiS_Part1Port, 0x09, 0xFF);	/* 0x09 Set Max VT               */
-
-	tempbx = SiS_VGAVT;
-	push1 = tempbx;
-	tempcx = 0x121;
-	tempbx = SiS_VGAVDE;	/* 0x0E Virtical 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;
-	push2 = tempbx;
-	if (SiS_VBInfo & SetCRT2ToLCD) {
-		if (SiS_LCDResInfo == Panel1024x768) {
-			if (!(SiS_SetFlag & LCDVESATiming)) {
-				if (tempbx == 350)
-					tempbx = tempbx + 5;
-				if (tempbx == 480)
-					tempbx = tempbx + 5;
-			}
-		}
-	}
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x10, temp);	/* 0x10 vertical Blank Start */
-	tempbx = push2;
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x0E, temp);
-	if (tempbx & 0x0100) {
-		tempcx = tempcx | 0x0002;
-	}
-	tempax = 0x000B;
-	if (modeflag & DoubleScanMode) {
-		tempax = tempax | 0x08000;
-	}
-	if (tempbx & 0x0200) {
-		tempcx = tempcx | 0x0040;
-	}
-
-	temp = (tempax & 0xFF00) >> 8;
-	SiS_SetReg1 (SiS_Part1Port, 0x0B, temp);
-	if (tempbx & 0x0400) {
-		tempcx = tempcx | 0x0600;
-	}
-	SiS_SetReg1 (SiS_Part1Port, 0x11, 0x00);	/* 0x11 Vertival Blank End */
-
-	tempax = push1;
-	tempax = tempax - tempbx;	/* 0x0C Vertical Retrace Start */
-	tempax = tempax >> 2;
-	push1 = tempax;		/* push ax */
-
-	if (resinfo != 0x09) {
-		tempax = tempax << 1;
-		tempbx = tempax + tempbx;
-	}
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		tempbx = tempbx - 10;
-	} else {
-		if (SiS_SetFlag & TVSimuMode) {
-			if (SiS_VBInfo & SetPALTV) {
-				tempbx = tempbx + 40;
-			}
-		}
-	}
-	tempax = push1;
-	tempax = tempax >> 2;
-	tempax++;
-	tempax = tempax + tempbx;
-	push1 = tempax;		/* push ax  */
-	if ((SiS_VBInfo & SetPALTV)) {
-		if (tempbx <= 513) {
-			if (tempax >= 513) {
-				tempbx = 513;
-			}
-		}
-	}
-	temp = (tempbx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x0C, temp);
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x10, temp);
-	if (tempbx & 0x0100) {
-		tempcx = tempcx | 0x0008;
-	}
-	if (tempbx & 0x0200) {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x0B, 0x0FF, 0x20);
-	}
-	tempbx++;
-	if (tempbx & 0x0100) {
-		tempcx = tempcx | 0x0004;
-	}
-	if (tempbx & 0x0200) {
-		tempcx = tempcx | 0x0080;
-	}
-	if (tempbx & 0x0400) {
-		tempcx = tempcx | 0x0C00;
-	}
-
-	tempbx = push1;		/* pop ax */
-	temp = tempbx & 0x00FF;
-	temp = temp & 0x0F;
-	SiS_SetReg1 (SiS_Part1Port, 0x0D, temp);	/* 0x0D vertical Retrace End */
-	if (tempbx & 0x0010) {
-		tempcx = tempcx | 0x2000;
-	}
-
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x0A, temp);	/* 0x0A CR07 */
-	temp = (tempcx & 0x0FF00) >> 8;
-	SiS_SetReg1 (SiS_Part1Port, 0x17, temp);	/* 0x17 SR0A */
-	tempax = modeflag;
-	temp = (tempax & 0xFF00) >> 8;
-
-	temp = (temp >> 1) & 0x09;
-	SiS_SetReg1 (SiS_Part1Port, 0x16, temp);	/* 0x16 SR01 */
-	SiS_SetReg1 (SiS_Part1Port, 0x0F, 0);	/* 0x0F CR14 */
-	SiS_SetReg1 (SiS_Part1Port, 0x12, 0);	/* 0x12 CR17 */
-	if (SiS_LCDInfo & LCDRGB18Bit)
-		temp = 0x80;
-	else
-		temp = 0x00;
-	SiS_SetReg1 (SiS_Part1Port, 0x1A, temp);	/* 0x1A SR0E */
-	return;
-}
+  SiS_SetReg1(SiS_Part1Port,0x08,0x00);                 /* 0x08 Horizontal Retrace End   */
 
-void
-SiS_SetGroup1_LVDS (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		    USHORT RefreshRateTableIndex)
-{
-	USHORT modeflag, resinfo;
-	USHORT push1, push2, tempax, tempbx, tempcx, temp, pushcx;
-	ULONG tempeax = 0, tempebx, tempecx, tempvcfact = 0;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	}
+  if(SiS_VBInfo & SetCRT2ToTV) {
+        if(SiS_SetFlag & TVSimuMode) {
+            if((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo == 0x11) ||
+	                           (ModeNo == 0x13) || (ModeNo == 0x0F)){
+             	SiS_SetReg1(SiS_Part1Port,0x07,0x5b);
+             	SiS_SetReg1(SiS_Part1Port,0x08,0x03);
+            }
+            if((ModeNo == 0x00) || (ModeNo == 0x01)) {
+             	if(SiS_VBInfo & SetNTSCTV) {
+             		SiS_SetReg1(SiS_Part1Port,0x07,0x2A);
+             		SiS_SetReg1(SiS_Part1Port,0x08,0x61);
+              	} else {
+             		SiS_SetReg1(SiS_Part1Port,0x07,0x2A);
+             		SiS_SetReg1(SiS_Part1Port,0x08,0x41);
+             		SiS_SetReg1(SiS_Part1Port,0x0C,0xF0);
+            	}
+           }
+           if((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo == 0x07)){
+            	if(SiS_VBInfo & SetNTSCTV) {
+           		SiS_SetReg1(SiS_Part1Port,0x07,0x54);
+           		SiS_SetReg1(SiS_Part1Port,0x08,0x00);
+            	} else {
+           		SiS_SetReg1(SiS_Part1Port,0x07,0x55);
+           		SiS_SetReg1(SiS_Part1Port,0x08,0x00);
+           		SiS_SetReg1(SiS_Part1Port,0x0C,0xF0);
+           	}
+           }
+           if((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo == 0x0D)
+	                                           || (ModeNo == 0x50)){
+            	if(SiS_VBInfo & SetNTSCTV) {
+            		SiS_SetReg1(SiS_Part1Port,0x07,0x30);
+            		SiS_SetReg1(SiS_Part1Port,0x08,0x03);
+            	} else {
+           		SiS_SetReg1(SiS_Part1Port,0x07,0x2f);
+           		SiS_SetReg1(SiS_Part1Port,0x08,0x02);
+                }
+           }
+       }
+  }
+
+  SiS_SetReg1(SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08    */
+
+  SiS_SetRegANDOR(SiS_Part1Port,0x19,0xF0,0x00);
+
+  SiS_SetReg1(SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
+
+  tempbx = SiS_VGAVT;
+  push1 = tempbx;
+  tempcx = 0x121;
+  tempbx = 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;
+  push2 = tempbx;
+  if(SiS_VBInfo & SetCRT2ToLCD) {  /* TW: Entire if statement not in 630/301 BIOS */
+    	if(SiS_LCDResInfo == Panel1024x768) {
+      		if(!(SiS_SetFlag & LCDVESATiming)) {
+        		if(tempbx == 350) tempbx += 5;
+        		if(tempbx == 480) tempbx += 5;
+      		}
+    	}
+  }
+  tempbx--;
+  temp = tempbx & 0x00FF;
+  tempbx--;			/* Not in 630/301 BIOS */
+  temp = tempbx & 0x00FF;	/* Not in 630/301 BIOS */
+  SiS_SetReg1(SiS_Part1Port,0x10,temp);        		/* 0x10 vertical Blank Start */
+
+  tempbx = push2;
+  tempbx--;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x0E,temp);
+
+  if(tempbx & 0x0100) {
+  	tempcx |= 0x0002;
+	if(SiS_VBType & VB_SIS301) tempcx |=0x000a;
+  }
+
+  tempax = 0x000B;
+  if(modeflag & DoubleScanMode) tempax |= 0x8000;
+
+  if(tempbx & 0x0200) {
+  	tempcx |= 0x0040;
+	if(SiS_VBType & VB_SIS301) tempax |= 0x2000;
+  }
+
+  if(SiS_VBType & VB_SIS301) {
+        if(SiS_VBInfo & SetPALTV) {
+	      if(SiS_VGAVDE == 480) {
+	             tempax = (tempax & 0x00ff) | 0x2000;
+		     if(modeflag & DoubleScanMode)  tempax |= 0x8000;
+	      }
+	}
+  }
+
+  temp = (tempax & 0xFF00) >> 8;
+  SiS_SetReg1(SiS_Part1Port,0x0B,temp);
+
+  if(tempbx & 0x0400) tempcx |= 0x0600;
+
+  SiS_SetReg1(SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
+
+  tempax = push1;
+  tempax -= tempbx;
+  tempax >>= 2;
+  push1 = tempax;
+
+  if((resinfo != 0x09) || (SiS_VBType & VB_SIS301)) {
+    	tempax <<= 1;
+    	tempbx += tempax;
+  }
+#ifdef oldHV
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+    	tempbx -= 10;
+  } else {
+#endif
+    	if(SiS_SetFlag & TVSimuMode) {
+      	   if(SiS_VBInfo & SetPALTV) {
+	       if(!(SiS_HiVision & 0x03)) {
+                    tempbx += 40;
+		    if(HwDeviceExtension->jChipType >= SIS_315H) {
+		       if(SiS_VGAHDE == 800) tempbx += 10;
+		    }
+      	       }
+	   }
+    	}
+#ifdef oldHV
+  }
+#endif
+  tempax = push1;
+  tempax >>= 2;
+  tempax++;
+  tempax += tempbx;
+  push1 = tempax;
+  if((SiS_VBInfo & SetPALTV)) {
+    	if(tempbx <= 513)  {
+      		if(tempax >= 513) tempbx = 513;
+    	}
+  }
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
+
+  if(!(SiS_VBType & VB_SIS301)) {
+  	tempbx--;
+  	temp = tempbx & 0x00FF;
+  	SiS_SetReg1(SiS_Part1Port,0x10,temp);
+
+	if(tempbx & 0x0100) tempcx |= 0x0008;
+
+  	if(tempbx & 0x0200)
+    		SiS_SetRegOR(SiS_Part1Port,0x0B,0x20);
+
+  	tempbx++;
+  }
+  if(tempbx & 0x0100) tempcx |= 0x0004;
+  if(tempbx & 0x0200) tempcx |= 0x0080;
+  if(tempbx & 0x0400) {
+        if(SiS_VBType & VB_SIS301) tempcx |= 0x0800;
+  	else                       tempcx |= 0x0C00;
+  }
+
+  tempbx = push1;
+  temp = tempbx & 0x00FF;
+  temp &= 0x0F;
+  SiS_SetReg1(SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
+
+  if(tempbx & 0x0010) tempcx |= 0x2000;
+
+  temp = tempcx & 0x00FF;
+
+  if(SiS_VBType & VB_SIS301) {
+	if(SiS_VBInfo & SetPALTV) {
+	      if(SiS_VGAVDE == 480)  temp = 0xa3;
+	}
+  }
+  SiS_SetReg1(SiS_Part1Port,0x0A,temp);                    		/* 0x0A CR07 */
+
+  temp = (tempcx & 0xFF00) >> 8;
+  SiS_SetReg1(SiS_Part1Port,0x17,temp);                    		/* 0x17 SR0A */
+
+  tempax = modeflag;
+  temp = (tempax & 0xFF00) >> 8;
+  temp = (temp >> 1) & 0x09;
+  /* TW: Inserted from 650/301 BIOS; not in 630/301B+301 BIOS */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+       temp |= 0x01;
+  }
+  SiS_SetReg1(SiS_Part1Port,0x16,temp);                    		/* 0x16 SR01 */
+
+  SiS_SetReg1(SiS_Part1Port,0x0F,0x00);                        		/* 0x0F CR14 */
+
+  SiS_SetReg1(SiS_Part1Port,0x12,0x00);                        		/* 0x12 CR17 */
+
+  if(SiS_LCDInfo & LCDRGB18Bit) temp = 0x80;
+  else                          temp = 0x00;
+  SiS_SetReg1(SiS_Part1Port,0x1A,temp);                         	/* 0x1A SR0E */
+
+  return;
+}
+
+/* TW: Checked against 650/LVDS 1.10.07, 630/301B (I,II) and 630/LVDS BIOS */
+void
+SiS_SetGroup1_LVDS(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+		   USHORT ModeIdIndex,
+                   PSIS_HW_DEVICE_INFO HwDeviceExtension,
+		   USHORT RefreshRateTableIndex)
+{
+  USHORT modeflag,resinfo;
+  USHORT push1,push2,tempax,tempbx,tempcx,temp,pushcx;
+  ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+
+#ifdef LINUX_XF86
+#ifdef TWDEBUG
+  xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_LCDHDES, SiS_LCDVDES);
+  xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_HDE, SiS_VDE);
+  xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_VGAHDE, SiS_VGAVDE);
+  xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_HT, SiS_VT);
+  xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_VGAHT, SiS_VGAVT);
+#endif
+#endif
 
-	tempax = SiS_LCDHDES;
-	tempbx = SiS_HDE;
-	tempcx = SiS_HT;
-	tempcx = tempcx - tempbx;	/* HT-HDE  */
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		if (SiS_LCDResInfo == Panel800x600)
-			tempbx = 800;
-		if (SiS_LCDResInfo == Panel1024x768)
-			tempbx = 1024;
-	}
-	push1 = tempax;
-	tempax = tempax + tempbx;	/* lcdhdee  */
-	tempbx = SiS_HT;
-	if (tempax >= tempbx) {
-		tempax = tempax - tempbx;
-	}
-	push2 = tempax;
-	/* push ax   lcdhdee  */
-	tempcx = tempcx >> 2;	/* temp  */
-	tempcx = tempcx + tempax;	/* lcdhrs  */
-	if (tempcx >= tempbx) {
-		tempcx = tempcx - tempbx;
-	}
-	/* v ah,cl  */
-	tempax = tempcx;
-	tempax = tempax >> 3;	/* BPLHRS */
-	temp = tempax & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x14, temp);	/* Part1_14h  */
-	temp = (tempax & 0x00FF) + 10;
-	temp = temp & 0x01F;
-	temp = temp | (((tempcx & 0x00ff) & 0x07) << 5);
-	SiS_SetReg1 (SiS_Part1Port, 0x15, temp);	/* Part1_15h  */
-	tempbx = push2;		/* lcdhdee  */
-	tempcx = push1;		/* lcdhdes  */
-	temp = (tempcx & 0x00FF);
-	temp = temp & 0x07;	/* BPLHDESKEW  */
-	SiS_SetReg1 (SiS_Part1Port, 0x1A, temp);	/* Part1_1Ah  */
-	tempcx = tempcx >> 3;	/* BPLHDES */
-	temp = (tempcx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x16, temp);	/* Part1_16h  */
-	if (tempbx & 0x07)
-		tempbx = tempbx + 8;
-	tempbx = tempbx >> 3;	/* BPLHDEE  */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x17, temp);	/* Part1_17h  */
-
-	tempcx = SiS_VGAVT;
-	tempbx = SiS_VGAVDE;
-	tempcx = tempcx - tempbx;	/* GAVT-VGAVDE  */
-	tempbx = SiS_LCDVDES;	/* VGAVDES  */
-	push1 = tempbx;		/* push bx temppush1 */
-	if (SiS_IF_DEF_TRUMPION == 0) {
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				tempax = SiS_VGAVDE;
-			}
-		}
-		if (SiS_VBInfo & SetCRT2ToLCD) {
-			if (SiS_LCDResInfo == Panel800x600)
-				tempax = 600;
-			if (SiS_LCDResInfo == Panel1024x768)
-				tempax = 768;
-		}
-	} else
-		tempax = SiS_VGAVDE;
-	tempbx = tempbx + tempax;
-	tempax = SiS_VT;	/* VT  */
-	if (tempbx >= SiS_VT) {
-		tempbx = tempbx - tempax;
-	}
-	push2 = tempbx;		/* push bx  temppush2  */
-	tempcx = tempcx >> 1;
-	tempbx = tempbx + tempcx;
-	tempbx++;		/* BPLVRS  */
-	if (tempbx >= tempax) {
-		tempbx = tempbx - tempax;
-	}
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x18, temp);	/* Part1_18h  */
-	tempcx = tempcx >> 3;
-	tempcx = tempcx + tempbx;
-	tempcx++;		/* BPLVRE  */
-	temp = tempcx & 0x00FF;
-	temp = temp & 0x0F;
-	SiS_SetRegANDOR (SiS_Part1Port, 0x19, ~0x00F, temp);	/* Part1_19h  */
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp & 0x07;
-	temp = temp << 3;	/* BPLDESKEW =0 */
-	tempbx = SiS_VGAVDE;
-	if (tempbx != SiS_VDE) {
-		temp = temp | 0x40;
-	}
-	if (SiS_SetFlag & EnableLVDSDDA) {
-		temp = temp | 0x40;
-	}
-	if (SiS_LCDInfo & LCDRGB18Bit) {
-		temp = temp | 0x80;
-	}
-	SiS_SetRegANDOR (SiS_Part1Port, 0x1A, 0x07, temp);	/* Part1_1Ah */
-
-	tempecx = SiS_VGAVT;
-	tempebx = SiS_VDE;
-	tempeax = SiS_VGAVDE;
-	tempecx = tempecx - tempeax;	/* VGAVT-VGAVDE  */
-	tempeax = tempeax << 6;
-	temp = (USHORT) (tempeax % tempebx);
-	tempeax = tempeax / tempebx;
-	if (temp != 0) {
-		tempeax++;
-	}
-	tempebx = tempeax;	/* BPLVCFACT  */
-	if (SiS_SetFlag & EnableLVDSDDA) {
-		tempebx = tempebx & 0x003F;
-	}
-	temp = (USHORT) (tempebx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x1E, temp);	/* Part1_1Eh */
-
-	/*add for 301b different 301 */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		tempecx = SiS_VGAVT;
-		tempebx = SiS_VDE;
-		tempeax = SiS_VGAVDE;
-		tempecx = tempecx - tempeax;	/* VGAVT-VGAVDE  */
-		tempeax = tempeax << 18;
-		temp = (USHORT) (tempeax % tempebx);
-		tempeax = tempeax / tempebx;
-		if (temp != 0) {
-			tempeax++;
-		}
-		tempebx = tempeax;	/* BPLVCFACT  */
-		tempvcfact = tempeax;	/*301b */
-		temp = (USHORT) (tempebx & 0x00FF);
-		SiS_SetReg1 (SiS_Part1Port, 0x37, temp);
-		temp = (USHORT) ((tempebx & 0x00FF00) >> 8);
-		SiS_SetReg1 (SiS_Part1Port, 0x36, temp);
-		temp = (USHORT) ((tempebx & 0x00030000) >> 16);
-		if (SiS_VDE == SiS_VGAVDE) {
-			temp = temp | 0x04;
-		}
+  /* TW: Set up Panel Link */
 
-		SiS_SetReg1 (SiS_Part1Port, 0x35, temp);
-	}
-	/*end for 301b */
+  /* 1. Horizontal setup */
 
-	tempbx = push2;		/* p bx temppush2 BPLVDEE  */
-	tempcx = push1;		/* pop cx temppush1 NPLVDES */
-	push1 = (USHORT) (tempeax & 0xFFFF);
-	if (!(SiS_VBInfo & SetInSlaveMode)) {
-		if (SiS_LCDResInfo == Panel800x600) {
-			if (resinfo == 7)
-				tempcx++;
+  tempax = SiS_LCDHDES;
+   /* TW: Inserted (650/LVDS,630/301B/LVDS) BIOS) */
+  if((SiS_LCDResInfo == Panel640x480) && (!(SiS_VBInfo & SetInSlaveMode)))
+  	tempax -= 8;
+
+  tempcx = SiS_HT;    				  /* Horiz. Total */
+
+  tempbx = SiS_HDE;                               /* Horiz. Display End */
+
+  if(SiS_LCDInfo & LCDNonExpanding) {
+    if(!SiS_IF_DEF_DSTN) {
+ 	if(SiS_LCDResInfo == Panel800x600)        tempbx = 800;
+    	else if(SiS_LCDResInfo == Panel1024x768)  tempbx = 1024;
+/*	else if(SiS_LCDResInfo == Panel1024x600)  tempbx = 1024;  - not done in BIOS */
+/*	else if(SiS_LCDResInfo == Panel1152x768)  tempbx = 1152;  - not done in BIOS */
+	else if(SiS_LCDResInfo == Panel1280x1024) tempbx = 1280;  /* TW */
+        else if(SiS_LCDResInfo != Panel640x480)   tempbx = 1400;  /* TW */
+    }
+  }
+  tempcx = (tempcx - tempbx) >> 2;		 /* HT-HDE / 4 */
+
+  push1 = tempax;
+
+  tempax += tempbx;
+
+  if(tempax >= SiS_HT) tempax -= SiS_HT;
+
+  push2 = tempax;
+
+  /* TW: Inserted this entire "if"-section from 650/LVDS, 630/301B and 630/LVDS BIOS */
+  if(SiS_VBInfo & SetCRT2ToLCD) {
+       if(!SiS_IF_DEF_DSTN){
+     	  if(SiS_LCDResInfo == Panel800x600)        tempcx = 0x0028;
+     	  else if(SiS_LCDResInfo == Panel1400x1050) tempcx = 0x0030;
+     	  else if( (SiS_LCDResInfo == Panel1024x768) ||
+	           (SiS_LCDResInfo == Panel1024x600) ||
+		   (SiS_LCDResInfo == Panel1152x768) ) {
+	  	if(HwDeviceExtension->jChipType < SIS_315H) {
+		     if(SiS_IF_DEF_LVDS == 1) {
+		           tempcx = 0x0017;
+#ifdef TWPANEL
+			   tempcx++;
+#endif
+		     } else {
+		           tempcx = 0x0017;  /* A901; other 301B BIOS 0x0018; */
+		     }
 		} else {
-			if (SiS_LCDResInfo == Panel1024x768) {
-				if (resinfo == 8)
-					tempcx++;
-			}
+		     tempcx = 0x0018;
 		}
-	}
-
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp & 0x07;
-	temp = temp << 3;
-	temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
-	SiS_SetReg1 (SiS_Part1Port, 0x1D, temp);	/* Part1_1Dh */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x1C, temp);	/* Part1_1Ch  */
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x1B, temp);	/* Part1_1Bh  */
-
-	tempecx = SiS_VGAHDE;
-	tempebx = SiS_HDE;
-	tempeax = tempecx;
-	tempeax = tempeax << 6;
-	tempeax = tempeax << 10;
-	tempeax = tempeax / tempebx;
-	if (tempebx == tempecx) {
-		tempeax = 65535;
-	}
-	tempecx = tempeax;
-	tempeax = SiS_VGAHDE;	/*change VGAHT->VGAHDE */
-	tempeax = tempeax << 6;
-	tempeax = tempeax << 10;
-	tempeax = tempeax / tempecx;
-	tempecx = tempecx << 16;
-	tempeax = tempeax - 1;
-	tempecx = tempecx | (tempeax & 0x00FFFF);
-	temp = (USHORT) (tempecx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x1F, temp);	/* Part1_1Fh  */
-
-	tempeax = SiS_VGAVDE;
-	tempeax = tempeax << 18;	/*301b */
-	tempeax = tempeax / tempvcfact;
-	tempbx = (USHORT) (tempeax & 0x0FFFF);
-	if (SiS_LCDResInfo == Panel1024x768)
-		tempbx--;
-	if (SiS_SetFlag & EnableLVDSDDA) {
-		tempbx = 1;
-	}
-	temp = ((tempbx & 0xFF00) >> 8) << 3;
-	temp = temp | (USHORT) (((tempecx & 0x0000FF00) >> 8) & 0x07);
-	SiS_SetReg1 (SiS_Part1Port, 0x20, temp);	/* Part1_20h */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x21, temp);	/* Part1_21h */
-	tempecx = tempecx >> 16;	/* BPLHCFACT  */
-	if (modeflag & HalfDCLK) {
-		tempecx = tempecx >> 1;
-	}
-	temp = (USHORT) ((tempecx & 0x0000FF00) >> 8);
-	SiS_SetReg1 (SiS_Part1Port, 0x22, temp);	/* Part1_22h */
-	temp = (USHORT) (tempecx & 0x000000FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x23, temp);
-	/*add dstn new register */
-	if (SiS_IF_DEF_DSTN) {
-		SiS_SetReg1 (SiS_Part1Port, 0x1E, 0x01);
-		SiS_SetReg1 (SiS_Part1Port, 0x25, 0x00);
-		SiS_SetReg1 (SiS_Part1Port, 0x26, 0x00);
-		SiS_SetReg1 (SiS_Part1Port, 0x27, 0x00);
-		SiS_SetReg1 (SiS_Part1Port, 0x28, 0x87);
-		SiS_SetReg1 (SiS_Part1Port, 0x29, 0x5A);
-		SiS_SetReg1 (SiS_Part1Port, 0x2A, 0x4B);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x44, ~0x007, 0x03);
-		tempbx = SiS_HDE;	/*Blps=lcdhdee(lcdhdes+HDE) +64 */
-		tempbx = tempbx + 64;
-		temp = tempbx & 0x00FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x38, temp);
-		temp = ((tempbx & 0xFF00) >> 8) << 3;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x35, ~0x078, temp);
-		tempbx = tempbx + 32;	/*Blpe=lBlps+32 */
-		temp = tempbx & 0x00FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x39, temp);
-		SiS_SetReg1 (SiS_Part1Port, 0x3A, 0x00);	/*Bflml=0 */
-		SiS_SetRegANDOR (SiS_Part1Port, 0x3C, ~0x007, 0x00);
-		tempbx = SiS_VDE;
-		tempbx = tempbx / 2;
-		temp = tempbx & 0x00FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x3B, temp);
-		temp = ((tempbx & 0xFF00) >> 8) << 3;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x3C, ~0x038, temp);
-		tempeax = SiS_HDE;	/* BDxFIFOSTOP= (HDE*4)/128 */
-		tempeax = tempeax * 4;
-		tempebx = 128;
-		temp = (USHORT) (tempeax % tempebx);
-		tempeax = tempeax / tempebx;
-		if (temp != 0) {
-			tempeax++;
-		}
-		temp = (USHORT) (tempeax & 0x0000003F);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x45, ~0x0FF, temp);
-		SiS_SetReg1 (SiS_Part1Port, 0x3F, 0x00);	/*BDxWadrst0 */
-		SiS_SetReg1 (SiS_Part1Port, 0x3E, 0x00);
-		SiS_SetReg1 (SiS_Part1Port, 0x3D, 0x10);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x3C, ~0x040, 0x00);
-		tempax = SiS_HDE;
-		tempax = tempax >> 4;	/*BDxWadroff = HDE*4/8/8  */
-		pushcx = tempax;
-		temp = tempax & 0x00FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x43, temp);
-		temp = ((tempax & 0xFF00) >> 8) << 3;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x44, ~0x0F8, temp);
-		tempax = SiS_VDE;	/*BDxWadrst1 = BDxWadrst0+BDxWadroff*VDE */
-		tempeax = (tempax * pushcx);
-		tempebx = 0x00100000 + tempeax;
-		temp = (USHORT) tempebx & 0x000000FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x42, temp);
-		temp = (USHORT) ((tempebx & 0x0000FF00) >> 8);
-		SiS_SetReg1 (SiS_Part1Port, 0x41, temp);
-		temp = (USHORT) ((tempebx & 0x00FF0000) >> 16);
-		SiS_SetReg1 (SiS_Part1Port, 0x40, temp);
-		temp = (USHORT) ((tempebx & 0x01000000) >> 24);
-		temp = temp << 7;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x3C, ~0x080, temp);
-		SiS_SetReg1 (SiS_Part1Port, 0x2F, 0x03);
-		SiS_SetReg1 (SiS_Part1Port, 0x03, 0x50);
-		SiS_SetReg1 (SiS_Part1Port, 0x04, 0x00);
-		SiS_SetReg1 (SiS_Part1Port, 0x2F, 0x01);
-		SiS_SetReg1 (SiS_Part1Port, 0x13, 0x00);
-		SiS_SetReg1 (SiS_P3c4, 0x05, 0x86);
-		SiS_SetReg1 (SiS_P3c4, 0x1e, 0x62);
-		SiS_SetReg1 (SiS_Part1Port, 0x19, 0x38);
-		SiS_SetReg1 (SiS_Part1Port, 0x1e, 0x7d);
-	}
-	/*end add dstn */
+	  }
+     	  else if(SiS_LCDResInfo != Panel640x480)   tempcx = 0x0030;
+       }
+  }
+
+  tempcx += tempax;                              /* lcdhrs  */
+  if(tempcx >= SiS_HT) tempcx -= SiS_HT;
+
+  tempax = tempcx >> 3;                          /* BPLHRS */
+  temp = tempax & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x14,temp);		 /* Part1_14h; TW: Panel Link Horizontal Retrace Start  */
+
+  temp = (tempax & 0x00FF) + 10;
+
+  /* TW: Inserted this entire "if"-section from 650/LVDS BIOS */
+  if(SiS_VBInfo & SetCRT2ToLCD) {
+      if(!SiS_IF_DEF_DSTN){
+        if(SiS_LCDResInfo != Panel640x480) {
+	  temp += 6;
+          if(SiS_LCDResInfo != Panel800x600) {
+	    temp++;
+	    if(HwDeviceExtension->jChipType > SIS_315H) {
+	       if(SiS_LCDResInfo != Panel1024x768) {
+	          temp -= 3;
+#ifdef TEST1400
+		  temp = 0x0e;
+#endif
+	       }
+	    }
+	  }
+        }
+      }
+  }
+
+  temp &= 0x1F;
+  temp |= ((tempcx & 0x0007) << 5);
+  if(SiS_IF_DEF_FSTN) temp=0x20;
+  SiS_SetReg1(SiS_Part1Port,0x15,temp);    	 /* Part1_15h; TW: Panel Link Horizontal Retrace End/Skew */
+
+  tempbx = push2;
+  tempcx = push1;                                /* lcdhdes  */
+
+  temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
+  SiS_SetReg1(SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; TW: Panel Link Vertical Retrace Start (2:0) */
+
+  tempcx >>= 3;                                  /* BPLHDES */
+  temp = (tempcx & 0x00FF);
+  if(ModeNo==0x5b) temp--;                       /* fix fstn mode=5b */
+  SiS_SetReg1(SiS_Part1Port,0x16,temp);    	 /* Part1_16h; TW: Panel Link Horizontal Display Enable Start  */
+
+  if(HwDeviceExtension->jChipType < SIS_315H) {  /* TW: Not done in LVDS BIOS 1.10.07 */
+     if(tempbx & 0x07) tempbx += 8;              /* TW: Done in 630/301B and 630/LVDS BIOSes */
+  }
+  tempbx >>= 3;                                  /* BPLHDEE  */
+  temp = tempbx & 0x00FF;
+  if(ModeNo==0x5b) temp--;                    	 /* fix fstn mode=5b */
+  SiS_SetReg1(SiS_Part1Port,0x17,temp);   	 /* Part1_17h; TW: Panel Link Horizontal Display Enable End  */
+
+  /* 2. Vertical setup */
+
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+
+      /* TW: This entire section from 630/301B and 630/LVDS/LVDS+CH BIOS */
+      tempcx = SiS_VGAVT;
+      tempbx = SiS_VGAVDE;
+      if(SiS_LCDInfo & LCDNonExpanding) {
+         if(SiS_LCDResInfo != Panel640x480) {
+	    tempbx = 600;
+	    if(SiS_LCDResInfo != Panel800x600) {
+	       tempbx = 768;
+	       if( (SiS_LCDResInfo != Panel1024x768) && (SiS_LCDResInfo != Panel1152x768) ) {
+	 	    tempbx = 600;
+	       }
+	    }
+         }
+      }
+      tempcx -= tempbx;
+
+  } else {
+
+      tempcx = SiS_VGAVT - SiS_VGAVDE;                  /* VGAVT-VGAVDE  */
+
+  }
+
+  tempbx = SiS_LCDVDES;	   		 	 	/* VGAVDES  */
+  push1 = tempbx;
+
+  tempax = SiS_VGAVDE;
+
+  if((SiS_IF_DEF_TRUMPION == 0) && (!(SiS_LCDInfo & 0x0100))
+                                && (SiS_LCDResInfo != Panel640x480)) {
+    	if(SiS_VBInfo & SetCRT2ToLCD) {
+	    if(!SiS_IF_DEF_DSTN){
+      		if(SiS_LCDResInfo == Panel800x600)        tempax = 600;
+      		else if(SiS_LCDResInfo == Panel1024x768)  tempax = 768;
+		else if(SiS_LCDResInfo == Panel1024x600)  tempax = 600;   /* TW */
+      		else if(SiS_LCDResInfo == Panel1152x768)  tempax = 768;   /* TW */
+		else if(SiS_LCDResInfo == Panel1280x1024) tempax = 1024;  /* TW */
+		else if(SiS_LCDResInfo == Panel1400x1050) tempax = 1050;  /* TW */
+		else                                      tempax = 600;
+            }
+    	}
+  }
+
+  tempbx = tempbx + tempax;
+  if(tempbx >= SiS_VT) tempbx -= SiS_VT;
+
+  push2 = tempbx;                             	 /* push bx  temppush  */
+
+  tempcx >>= 1;
+
+  /* TW: Inserted this entire "if" section (650/LVDS; 630/301B; 630/LVDS) */
+  if((SiS_VBInfo & SetCRT2ToLCD) && (SiS_LCDResInfo != Panel640x480)){
+     if(!SiS_IF_DEF_DSTN){
+     	if(SiS_LCDResInfo == Panel800x600)        tempcx = 0x0001;
+     	else if( (SiS_LCDResInfo == Panel1024x768) ||
+	         (SiS_LCDResInfo == Panel1152x768) ) {
+		if(HwDeviceExtension->jChipType < SIS_315H) {
+		      if(SiS_IF_DEF_LVDS == 1) {
+			    tempcx = 0x0002;
+#ifdef TWPANEL
+			    tempcx++;
+#endif
+		      } else {
+		            tempcx = 0x0002;   /* TW: A901; other 301B BIOS sets 0x0003; */
+		      }
+		} else tempcx = 0x0003;
+        }
+     	else if(SiS_LCDResInfo == Panel1280x768)  tempcx = 0x0003;
+     	else if(SiS_LCDResInfo == Panel1280x1024) tempcx = 0x0001;
+     	else if(SiS_LCDResInfo == Panel1400x1050) tempcx = 0x0001;
+     	else 				          tempcx = 0x0057;
+     }
+  }
 
-	return;
-}
+  tempbx += tempcx;			 	/* BPLVRS  */
 
-/*301b*/
-void
-SiS_SetGroup1_LCDA (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		    USHORT RefreshRateTableIndex)
-{
-	USHORT modeflag, resinfo;
-	USHORT push1, push2, tempax, tempbx, tempcx, temp;
-	ULONG tempeax = 0, tempebx, tempecx, tempvcfact;	/*301b */
-	SiS_SetRegOR (SiS_Part1Port, 0x2D, 0x20);
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	}
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+#ifdef TWPANEL
+      if(SiS_IF_DEF_CH70xx == 0)
+#endif
+   	  tempbx++;
+  }
 
-	tempax = SiS_LCDHDES;
-	tempbx = SiS_HDE;
-	tempcx = SiS_HT;
-
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		if (SiS_LCDResInfo == Panel1280x1024)
-			tempbx = 1280;
-		if (SiS_LCDResInfo == Panel1024x768)
-			tempbx = 1024;
-	}
-	tempcx = tempcx - tempbx;	/* HT-HDE  */
-	push1 = tempax;
-	tempax = tempax + tempbx;	/* lcdhdee  */
-	tempbx = SiS_HT;
-	if (tempax >= tempbx) {
-		tempax = tempax - tempbx;
-	}
-	push2 = tempax;
-	/* push ax   lcdhdee  */
-	tempcx = tempcx >> 2;	/* temp  */
-	tempcx = tempcx + tempax;	/* lcdhrs  */
-	if (tempcx >= tempbx) {
-		tempcx = tempcx - tempbx;
-	}
-	/* v ah,cl  */
-	tempax = tempcx;
-	tempax = tempax >> 3;	/* BPLHRS */
-	temp = tempax & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x14, temp);	/* Part1_14h  */
-	temp = (tempax & 0x00FF) + 10;
-	temp = temp & 0x01F;
-	temp = temp | (((tempcx & 0x00ff) & 0x07) << 5);
-	SiS_SetReg1 (SiS_Part1Port, 0x15, temp);	/* Part1_15h  */
-	tempbx = push2;		/* lcdhdee  */
-	tempcx = push1;		/* lcdhdes  */
-	temp = (tempcx & 0x00FF);
-	temp = temp & 0x07;	/* BPLHDESKEW  */
-	SiS_SetReg1 (SiS_Part1Port, 0x1A, temp);	/* Part1_1Ah  */
-	tempcx = tempcx >> 3;	/* BPLHDES */
-	temp = (tempcx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x16, temp);	/* Part1_16h  */
-	if (tempbx & 0x07)
-		tempbx = tempbx + 8;
-	tempbx = tempbx >> 3;	/* BPLHDEE  */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x17, temp);	/* Part1_17h  */
-
-	tempcx = SiS_VGAVT;
-	tempbx = SiS_VGAVDE;
-	tempcx = tempcx - tempbx;	/* GAVT-VGAVDE  */
-	tempbx = SiS_LCDVDES;	/* VGAVDES  */
-	push1 = tempbx;		/* push bx temppush1 */
-	if (SiS_IF_DEF_TRUMPION == 0) {
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				tempax = SiS_VGAVDE;
-			}
-		}
+#ifdef TEST1400  /* Not done on 650/LVDS 1.10.07, done in 650/LVDS 1.10a */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+          tempbx++;
+  }
+#endif
 
-		if (SiS_LCDResInfo == Panel1024x768)
-			tempax = 768;
-		if (SiS_LCDResInfo == Panel1280x1024)
-			tempax = 1024;
-
-	} else
-		tempax = SiS_VGAVDE;
-	tempbx = tempbx + tempax;
-	tempax = SiS_VT;	/* VT  */
-	if (tempbx >= SiS_VT) {
-		tempbx = tempbx - tempax;
-	}
-	push2 = tempbx;		/* push bx  temppush2  */
-	tempcx = tempcx >> 1;
-	tempbx = tempbx + tempcx;
-	tempbx++;		/* BPLVRS  */
-	if (tempbx >= tempax) {
-		tempbx = tempbx - tempax;
-	}
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x18, temp);	/* Part1_18h  */
-	tempcx = tempcx >> 3;
-	tempcx = tempcx + tempbx;
-	tempcx++;		/* BPLVRE  */
-	temp = tempcx & 0x00FF;
-	temp = temp & 0x0F;
-	SiS_SetRegANDOR (SiS_Part1Port, 0x19, ~0x00F, temp);	/* Part1_19h  */
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp & 0x07;
-	temp = temp << 3;	/* BPLDESKEW =0 */
-	tempbx = SiS_VGAVDE;
-	if (tempbx != SiS_VDE) {
-		temp = temp | 0x40;
-	}
-	if (SiS_SetFlag & EnableLVDSDDA) {
-		temp = temp | 0x40;
-	}
-	if (SiS_LCDInfo & LCDRGB18Bit) {
-		temp = temp | 0x80;
-	}
-	SiS_SetRegANDOR (SiS_Part1Port, 0x1A, 0x07, temp);	/* Part1_1Ah */
-
-	tempbx = push2;		/* p bx temppush2 BPLVDEE  */
-	tempcx = push1;		/* pop cx temppush1 NPLVDES */
-	push1 = (USHORT) (tempeax & 0xFFFF);
-
-	if (!(SiS_VBInfo & SetInSlaveMode)) {
-		if (SiS_LCDResInfo == Panel800x600) {
-			if (resinfo == 7)
+  if(tempbx >= SiS_VT) tempbx -= SiS_VT;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x18,temp);       	 /* Part1_18h; TW: Panel Link Vertical Retrace Start  */
+
+  tempcx >>= 3;
+
+  /* TW: Inserted this entire "if" section (650/LVDS, 630/LVDS, 630/301B) */
+  if(SiS_VBInfo & SetCRT2ToLCD) {
+     if( (HwDeviceExtension->jChipType < SIS_315H) &&
+         (SiS_LCDResInfo == Panel640x480) )     tempcx = 0x0001;
+     else if(SiS_LCDResInfo == Panel1400x1050)  tempcx = 0x0002;
+     else if(SiS_LCDResInfo == Panel800x600)    tempcx = 0x0003;
+     else if(SiS_LCDResInfo != Panel640x480)  {
+     		if(HwDeviceExtension->jChipType < SIS_315H) {
+		        if(SiS_IF_DEF_LVDS == 1) {
+				tempcx = 0x0004;
+#ifdef TWPANEL
 				tempcx++;
-		} else {
-			if (SiS_LCDResInfo == Panel1024x768) {
-				if (resinfo == 8)
-					tempcx++;
+#endif
+		        } else {
+				tempcx = 0x0004;   /* A901; Other BIOS sets 0x0005; */
 			}
+		} else {
+			tempcx = 0x0005;
 		}
-	}
+     }
+  }
+
+  tempcx = tempcx + tempbx + 1;                  /* BPLVRE  */
+  temp = tempcx & 0x000F;
+  SiS_SetRegANDOR(SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; TW: Panel Link Vertical Retrace End (3:0); Misc.  */
+
+  temp = ((tempbx & 0x0700) >> 8) << 3;          /* BPLDESKEW =0 */
+  if(SiS_VGAVDE != SiS_VDE)	  temp |= 0x40;
+  if(SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
+  if(SiS_LCDInfo & LCDRGB18Bit)   {
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
+         if(SiS_GetReg1(SiS_Part1Port,0x00) & 0x01) {	/* TW: Inserted from 650/LVDS 1.10.07 */
+            temp |= 0x80;
+         }
+      } else {
+	 if( (HwDeviceExtension->jChipType == SIS_630) ||
+	     (HwDeviceExtension->jChipType == SIS_730) ) {
+	    if(HwDeviceExtension->jChipRevision >= 0x30) {
+	       temp |= 0x80;
+	    }
+	 }
+      }
+  }         /* TW: in follwing line, 0x87 was 0x07 (modified according to 650/LVDS BIOS) */
+  SiS_SetRegANDOR(SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; TW: Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
+
+  if (HwDeviceExtension->jChipType < SIS_315H) {
+
+        /* 300 series */
+
+        tempeax = SiS_VGAVDE << 6;
+        temp = (USHORT)(tempeax % (ULONG)SiS_VDE);
+        tempeax = tempeax / (ULONG)SiS_VDE;
+        if(temp != 0) tempeax++;
+        tempebx = tempeax;                         /* BPLVCFACT  */
+
+  	if(SiS_SetFlag & EnableLVDSDDA) {
+	     tempebx = 0x003F;    
+	}
+
+  	temp = (USHORT)(tempebx & 0x00FF);
+  	SiS_SetReg1(SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; TW: Panel Link Vertical Scaling Factor */
+
+  } else {
+
+        /* 310 series */
+
+	SiS_SetReg1(SiS_Part1Port,0x1E,0x23);      /* Inserted from 650/LVDS BIOS */
+
+	tempeax = SiS_VGAVDE << 18;
+    	temp = (USHORT)(tempeax % (ULONG)SiS_VDE);
+    	tempeax = tempeax / SiS_VDE;
+    	if(temp != 0) tempeax++;
+    	tempebx = tempeax;                         /* BPLVCFACT  */
+        tempvcfact = tempeax;
+    	temp = (USHORT)(tempebx & 0x00FF);
+    	SiS_SetReg1(SiS_Part1Port,0x37,temp);      /* Part1_37h; TW: Panel Link Vertical Scaling Factor */
+    	temp = (USHORT)((tempebx & 0x00FF00) >> 8);
+    	SiS_SetReg1(SiS_Part1Port,0x36,temp);      /* Part1_36h; TW: Panel Link Vertical Scaling Factor */
+    	temp = (USHORT)((tempebx & 0x00030000) >> 16);
+    	if(SiS_VDE == SiS_VGAVDE) temp |= 0x04;
+    	SiS_SetReg1(SiS_Part1Port,0x35,temp);      /* Part1_35h; TW: Panel Link Vertical Scaling Factor */
+
+  }
+
+  tempbx = push2;                                  /* p bx temppush1 BPLVDEE  */
+  tempcx = push1;
+
+  push1 = temp;					   /* TW: For 630/301B and 630/LVDS */
+
+  if(!(SiS_VBInfo & SetInSlaveMode)) {
+   	if(!SiS_IF_DEF_DSTN){
+    		if(SiS_LCDResInfo == Panel800x600) {
+      			if(resinfo == 7) tempcx++;
+		}
+		if(HwDeviceExtension->jChipType < SIS_315H) {   /* TW: Not done in 650/LVDS 1.10.07 */
+	    	    if(resinfo == 8) tempcx++;			/* TW: But in 630/301B and 630/LVDS */
+		}
+	}
+  }
+  /* TW: Inserted (650/LVDS, 630/LVDS, 630/301B) */
+  if(SiS_LCDResInfo == Panel640x480) {
+     tempcx = SiS_VGAVDE;
+     tempbx = SiS_VGAVDE - 1;
+  }
+
+  temp = ((tempbx & 0x0700) >> 8) << 3;
+  temp |= ((tempcx & 0x0700) >> 8);
+  SiS_SetReg1(SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; TW: Vertical Display Overflow; Control Signal */
+
+  temp = tempbx & 0x00FF;
+  if(SiS_IF_DEF_FSTN) temp++;
+  SiS_SetReg1(SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; TW: Panel Link Vertical Display Enable End  */
+
+  temp = tempcx & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; TW: Panel Link Vertical Display Enable Start  */
+
+  /* 3. Additional horizontal setup (scaling, etc) */
+
+  tempecx = SiS_VGAHDE;
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     if(modeflag & HalfDCLK)			/* TW: Added this entire if statement */
+        tempecx >>= 1;
+  }
+  tempebx = SiS_HDE;
+  if(tempecx == tempebx) tempeax = 0xFFFF;
+  else {
+     tempeax = tempecx;
+     tempeax <<= 16;
+     temp = (USHORT)(tempeax % tempebx);
+     tempeax = tempeax / tempebx;
+     if(HwDeviceExtension->jChipType >= SIS_315H) {
+         if(temp) tempeax++;			/* TW: Not done in 630/301B or 630/LVDS, but for 650/LVDS */
+     }
+  }
+  tempecx = tempeax;
 
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp & 0x07;
-	temp = temp << 3;
-	temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
-	SiS_SetReg1 (SiS_Part1Port, 0x1D, temp);	/* Part1_1Dh */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x1C, temp);	/* Part1_1Ch  */
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x1B, temp);	/* Part1_1Bh  */
-
-	tempecx = SiS_VGAVT;
-	tempebx = SiS_VDE;
-	tempeax = SiS_VGAVDE;
-	tempecx = tempecx - tempeax;	/* VGAVT-VGAVDE  */
-	tempeax = tempeax << 18;
-	temp = (USHORT) (tempeax % tempebx);
-	tempeax = tempeax / tempebx;
-	if (temp != 0) {
-		tempeax++;
-	}
-	tempebx = tempeax;	/* BPLVCFACT  */
-	tempvcfact = tempeax;	/*301b */
-	temp = (USHORT) (tempebx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x37, temp);
-	temp = (USHORT) ((tempebx & 0x00FF00) >> 8);
-	SiS_SetReg1 (SiS_Part1Port, 0x36, temp);
-	temp = (USHORT) ((tempebx & 0x00030000) >> 16);
-	if (SiS_VDE == SiS_VGAVDE) {
-		temp = temp | 0x04;
-	}
-
-	SiS_SetReg1 (SiS_Part1Port, 0x35, temp);
-
-	tempecx = SiS_VGAHDE;
-	tempebx = SiS_HDE;
-	tempeax = tempecx;
-	tempeax = tempeax << 6;
-	tempeax = tempeax << 10;
-	tempeax = tempeax / tempebx;
-	if (tempebx == tempecx) {
-		tempeax = 65535;
-	}
-	tempecx = tempeax;
-	tempeax = SiS_VGAHDE;	/*301b to change HT->HDE */
-	tempeax = tempeax << 6;
-	tempeax = tempeax << 10;
-	tempeax = tempeax / tempecx;
-	tempecx = tempecx << 16;
-	tempeax = tempeax - 1;
-	tempecx = tempecx | (tempeax & 0x00FFFF);
-	temp = (USHORT) (tempecx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x1F, temp);	/* Part1_1Fh  */
-
-	tempeax = SiS_VGAVDE;
-	tempeax = tempeax << 18;	/*301b */
-	tempeax = tempeax / tempvcfact;
-	tempbx = (USHORT) (tempeax & 0x0FFFF);
-	if (SiS_LCDResInfo == Panel1024x768)
-		tempbx--;
-	if (SiS_SetFlag & EnableLVDSDDA) {
-		tempbx = 1;
-	}
-	temp = ((tempbx & 0xFF00) >> 8) << 3;
-	temp = temp | (USHORT) (((tempecx & 0x0000FF00) >> 8) & 0x07);
-	SiS_SetReg1 (SiS_Part1Port, 0x20, temp);	/* Part1_20h */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x21, temp);	/* Part1_21h */
-	tempecx = tempecx >> 16;	/* BPLHCFACT  */
-
-	temp = (USHORT) ((tempecx & 0x0000FF00) >> 8);
-	SiS_SetReg1 (SiS_Part1Port, 0x22, temp);	/* Part1_22h */
-	temp = (USHORT) (tempecx & 0x000000FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x23, temp);
-	return;
-}
-
-/*end 301b*/
+  if (HwDeviceExtension->jChipType >= SIS_315H) {
+      tempeax = SiS_VGAHDE;
+      if(modeflag & HalfDCLK)			/* TW: Added this entire if statement */
+          tempeax >>= 1;
+      tempeax <<= 16;
+      tempeax = (tempeax / tempecx) - 1;
+  } else {
+      tempeax = ((SiS_VGAHT << 16) / tempecx) - 1;    
+  }
+  tempecx <<= 16;
+  tempecx |= (tempeax & 0xFFFF);
+  temp = (USHORT)(tempecx & 0x00FF);
+  SiS_SetReg1(SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; TW: Panel Link DDA Operational Number in each horiz. line */
+
+  tempbx = SiS_VDE;                              /* TW: added following if statement */
+  if (HwDeviceExtension->jChipType >= SIS_315H) {
+      tempeax = (SiS_VGAVDE << 18) / tempvcfact;
+      tempbx = (USHORT)(tempeax & 0x0FFFF);
+  } else {
+      tempax = SiS_VGAVDE << 6;
+      tempbx = push1;
+      tempbx &= 0x3f;
+      if(tempbx == 0) tempbx = 64;
+      tempax = tempax / tempbx;
+      tempbx = tempax;
+  }
+  if(SiS_LCDResInfo == Panel1024x768) tempbx--;
+  if(SiS_SetFlag & EnableLVDSDDA)     tempbx = 1;
+
+  temp = ((tempbx & 0xFF00) >> 8) << 3;
+  temp |= (USHORT)((tempecx & 0x0700) >> 8);
+  SiS_SetReg1(SiS_Part1Port,0x20,temp);  	/* Part1_20h; TW: Overflow register */
+
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x21,temp);  	/* Part1_21h; TW: Panel Link Vertical Accumulator Register */
+
+  tempecx >>= 16;                               /* BPLHCFACT  */
+  if(HwDeviceExtension->jChipType < SIS_315H) { /* TW: Added this entire if statement from 630/301B+LVDS BIOSes */
+      if(modeflag & HalfDCLK) tempecx >>= 1;
+  }
+  temp = (USHORT)((tempecx & 0xFF00) >> 8);
+  SiS_SetReg1(SiS_Part1Port,0x22,temp);     	/* Part1_22h; TW: Panel Link Horizontal Scaling Factor High */
+
+  temp = (USHORT)(tempecx & 0x00FF);
+  SiS_SetReg1(SiS_Part1Port,0x23,temp);         /* Part1_22h; TW: Panel Link Horizontal Scaling Factor Low */
+
+  /* 630/301B and 630/LVDS do something for 640x480 panels here */
+
+  /* add dstn new register */
+  if(SiS_IF_DEF_DSTN){
+     	SiS_SetReg1(SiS_Part1Port,0x1E,0x01);
+     	SiS_SetReg1(SiS_Part1Port,0x25,0x00);
+     	SiS_SetReg1(SiS_Part1Port,0x26,0x00);
+     	SiS_SetReg1(SiS_Part1Port,0x27,0x00);
+     	SiS_SetReg1(SiS_Part1Port,0x28,0x87);
+     	SiS_SetReg1(SiS_Part1Port,0x29,0x5A);
+     	SiS_SetReg1(SiS_Part1Port,0x2A,0x4B);
+     	SiS_SetRegANDOR(SiS_Part1Port,0x44,~0x007,0x03);
+     	tempbx = SiS_HDE + 64;                       /*Blps = lcdhdee(lcdhdes+HDE) + 64*/
+     	temp = tempbx & 0x00FF;
+     	SiS_SetReg1(SiS_Part1Port,0x38,temp);
+     	temp=((tempbx & 0xFF00) >> 8) << 3;
+     	SiS_SetRegANDOR(SiS_Part1Port,0x35,~0x078,temp);
+     	tempbx += 32;		                     /*Blpe=lBlps+32*/
+     	temp = tempbx & 0x00FF;
+     	if(SiS_IF_DEF_FSTN)  temp=0;
+     	SiS_SetReg1(SiS_Part1Port,0x39,temp);
+     	SiS_SetReg1(SiS_Part1Port,0x3A,0x00);        /*Bflml=0*/
+     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x007,0x00);
+     	tempbx = SiS_VDE / 2;
+     	temp = tempbx & 0x00FF;
+     	SiS_SetReg1(SiS_Part1Port,0x3B,temp);
+     	temp = ((tempbx & 0xFF00) >> 8) << 3;
+     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x038,temp);
+     	tempeax = 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_Part1Port,0x45,~0x0FF,temp);
+     	SiS_SetReg1(SiS_Part1Port,0x3F,0x00);         /* BDxWadrst0 */
+     	SiS_SetReg1(SiS_Part1Port,0x3E,0x00);
+     	SiS_SetReg1(SiS_Part1Port,0x3D,0x10);
+     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x040,0x00);
+     	tempax = SiS_HDE >> 4;                        /* BDxWadroff = HDE*4/8/8 */
+     	pushcx = tempax;
+     	temp = tempax & 0x00FF;
+     	SiS_SetReg1(SiS_Part1Port,0x43,temp);
+     	temp = ((tempax & 0xFF00) >> 8) << 3;
+     	SiS_SetRegANDOR(SiS_Part1Port,0x44,~0x0F8,temp);
+     	tempax = SiS_VDE;                             /*BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
+     	tempeax = (tempax * pushcx);
+     	tempebx = 0x00100000 + tempeax;
+     	temp = (USHORT)tempebx & 0x000000FF;
+     	SiS_SetReg1(SiS_Part1Port,0x42,temp);
+     	temp = (USHORT)((tempebx & 0x0000FF00)>>8);
+     	SiS_SetReg1(SiS_Part1Port,0x41,temp);
+     	temp = (USHORT)((tempebx & 0x00FF0000)>>16);
+     	SiS_SetReg1(SiS_Part1Port,0x40,temp);
+     	temp = (USHORT)(((tempebx & 0x01000000)>>24) << 7);
+     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x080,temp);
+     	SiS_SetReg1(SiS_Part1Port,0x2F,0x03);
+     	SiS_SetReg1(SiS_Part1Port,0x03,0x50);
+     	SiS_SetReg1(SiS_Part1Port,0x04,0x00);
+     	SiS_SetReg1(SiS_Part1Port,0x2F,0x01);
+     	SiS_SetReg1(SiS_Part1Port,0x13,0x00);
+     	SiS_SetReg1(SiS_P3c4,0x05,0x86);        /* Unlock */
+     	SiS_SetReg1(SiS_P3c4,0x1e,0x62);
+     	if(SiS_IF_DEF_FSTN){
+         	SiS_SetReg1(SiS_P3c4,0x2b,0x1b);
+         	SiS_SetReg1(SiS_P3c4,0x2c,0xe3);
+         	SiS_SetReg1(SiS_P3c4,0x1e,0x62);
+         	SiS_SetReg1(SiS_P3c4,0x2e,0x04);
+         	SiS_SetReg1(SiS_P3c4,0x2f,0x42);
+         	SiS_SetReg1(SiS_P3c4,0x32,0x01);
+         	SiS_SetReg1(SiS_Part1Port,0x2b,0x02);
+         	SiS_SetReg1(SiS_Part1Port,0x2c,0x00);
+         	SiS_SetReg1(SiS_Part1Port,0x2d,0x00);
+     	}
+     	SiS_SetRegANDOR(SiS_Part1Port,0x19,0x0f,0x30);
+     	SiS_SetReg1(SiS_Part1Port,0x1e,0x7d);
+     	SiS_SetReg1(SiS_Part1Port,0x2e,0xe0);
+  }
+
+  return;
+
+}
+
+#ifdef SIS315H
 void
-SiS_SetTPData ()
+SiS_CRT2AutoThreshold(USHORT BaseAddr)
 {
-	return;
+  SiS_SetRegOR(SiS_Part1Port,0x01,0x40);
 }
+#endif
 
+
+/* TW: For LVDS / 302b/lv - LCDA (this must only be called on 310/325 series!) */
+/* TW: Double-checked against 650/LVDS and 650/301 BIOS */
 void
-SiS_SetCRT2Offset (USHORT SiS_Part1Port, ULONG ROMAddr, USHORT ModeNo,
-		   USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetGroup1_LCDA(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
 {
-	USHORT offset;
-	UCHAR temp;
-
-	if (SiS_VBInfo & SetInSlaveMode) {
-		return;
-	}
-	offset =
-	    SiS_GetOffset (ROMAddr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-			   HwDeviceExtension);
-	temp = (UCHAR) (offset & 0xFF);
-	SiS_SetReg1 (SiS_Part1Port, 0x07, temp);
-	temp = (UCHAR) ((offset & 0xFF00) >> 8);
-	SiS_SetReg1 (SiS_Part1Port, 0x09, temp);
-	temp = (UCHAR) (((offset >> 3) & 0xFF) + 1);
-	SiS_SetReg1 (SiS_Part1Port, 0x03, temp);
+  USHORT modeflag,resinfo;
+  USHORT push1,push2,tempax,tempbx,tempcx,temp;
+  ULONG tempeax=0,tempebx,tempecx,tempvcfact;
+
+  if(SiS_IF_DEF_LVDS == 1)					/* TW: From 650/LVDS BIOS */
+      SiS_SetRegANDOR(SiS_Part1Port,0x13,0xfb,0x04);      	/* TW: From 650/LVDS BIOS */
+
+  if(SiS_IF_DEF_LVDS == 1)					/* TW: From 650/LVDS 1.10.07 */
+     SiS_SetRegOR(SiS_Part1Port,0x2D,0x00);			/* TW: From 650/LVDS 1.10.07 */
+  else
+     SiS_SetRegOR(SiS_Part1Port,0x2D,0x20);
+
+  if(ModeNo<=0x13) {
+    modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+    modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+
+  tempax = SiS_LCDHDES;
+  tempbx = SiS_HDE;
+  tempcx = SiS_HT;
+  
+  if(SiS_LCDInfo & LCDNonExpanding) {
+    	if(SiS_LCDResInfo == Panel1280x1024)     tempbx = 1280;
+    	else if(SiS_LCDResInfo == Panel1024x768) tempbx = 1024;
+	else tempbx = 1400;                                     /* TW: From 650/LVDS BIOS; OK with 650/301 */
+  }
+  tempcx = tempcx - tempbx;                                    	/* HT-HDE  */
+  push1 = tempax;
+  tempax = tempax + tempbx;                                    	/* lcdhdee  */
+  tempbx = SiS_HT;
+  if(tempax >= tempbx)	tempax = tempax-tempbx;
+  push2=tempax;
+                                                           	/* push ax   lcdhdee  */
+  tempcx >>= 2;                                        	        /* temp  */
+  tempcx = tempcx + tempax;                                    	/* lcdhrs  */
+  if(tempcx >= tempbx) tempcx = tempcx - tempbx;
+                                                           	/* v ah,cl  */
+  tempax = tempcx;
+  tempax = tempax >> 3;                                        	/* BPLHRS */
+  temp = tempax & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x14,temp);                         /* Part1_14h  */
+
+  temp = (tempax & 0x00FF) + 10;
+  temp = temp & 0x01F;
+  temp = temp | (((tempcx & 0x00ff) & 0x07) << 5);
+  SiS_SetReg1(SiS_Part1Port,0x15,temp);                         /* Part1_15h  */
+
+  tempbx = push2;                                          	/* lcdhdee  */
+  tempcx = push1;                                          	/* lcdhdes  */
+  temp = (tempcx & 0x00FF);
+  temp = temp & 0x07;                                  		/* BPLHDESKEW  */
+  SiS_SetReg1(SiS_Part1Port,0x1A,temp);                         /* Part1_1Ah  */
+
+  tempcx = tempcx >> 3;                                        	/* BPLHDES */
+  temp = (tempcx & 0x00FF);
+  SiS_SetReg1(SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
+
+  if(tempbx & 0x07) tempbx += 8;
+  tempbx >>= 3;                                        		/* BPLHDEE  */
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x17,temp);                        	/* Part1_17h  */
+
+  tempcx = SiS_VGAVT;
+  tempbx = SiS_VGAVDE;
+  tempcx = tempcx-tempbx;                                    	/* GAVT-VGAVDE  */
+  tempbx = SiS_LCDVDES;                                        	/* VGAVDES  */
+  push1 = tempbx;                                      		/* push bx temppush1 */
+  if(SiS_IF_DEF_TRUMPION == 0){
+    if(SiS_LCDResInfo == Panel1024x768)   tempax = 768;
+    if(SiS_LCDResInfo == Panel1280x1024)  tempax = 1024;
+    if(SiS_LCDResInfo == Panel1400x1050)  tempax = 1050;        /* TW: Inserted from 650/LVDS BIOS */
+    else                                  tempax = 960;         /* TW: Inserted from 650/301 BIOS */
+#if 0                                                           /* TW: Removed (650/LVDS BIOS) */
+    if(SiS_IF_DEF_CH70xx == 1) {
+      if(SiS_VBInfo & SetCRT2ToTV) {
+        tempax = SiS_VGAVDE;
+      }
+    }
+#endif
+  } else tempax = SiS_VGAVDE;  /* Trumpion */
+  tempbx = tempbx + tempax;
+  tempax = SiS_VT;                                             	/* VT  */
+  if(tempbx >= SiS_VT)  tempbx = tempbx - tempax;
+
+  push2 = tempbx;                                      		/* push bx  temppush2  */
+  tempcx >>= 1;
+  tempbx = tempbx + tempcx;
+  tempbx++;                                                	/* BPLVRS  */
+  if(tempbx >= tempax)   tempbx = tempbx - tempax;
+  temp = tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x18,temp);                         /* Part1_18h  */
+
+  tempcx >>= 3;
+  tempcx = tempcx + tempbx;
+  tempcx++;                                                	/* BPLVRE  */
+  temp = tempcx & 0x00FF;
+  temp &= 0x0F;
+  if(SiS_IF_DEF_LVDS == 1) {
+     SiS_SetRegANDOR(SiS_Part1Port,0x19,0xf0,temp);             /* TW: Inserted from 650/LVDS BIOS */
+  } else {
+     temp |= 0x30;                                              /* TW: Inserted from 650/301 BIOS */
+     SiS_SetRegANDOR(SiS_Part1Port,0x19,0xC0,temp);             /* Part1_19h  (Was ~0x0f) */
+  }
+
+  temp = (tempbx & 0xFF00) >> 8;
+  temp &= 0x07;
+  temp <<= 3;  		                               		/* BPLDESKEW =0 */
+  tempbx = SiS_VGAVDE;
+  if(tempbx != SiS_VDE)              temp |= 0x40;
+  if(SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
+  if(SiS_IF_DEF_LVDS == 1) {
+      if(SiS_LCDInfo & LCDRGB18Bit)  temp |= 0x80;              /* TW: 650/301 BIOS does not check this! */
+      SiS_SetRegANDOR(SiS_Part1Port,0x1A,0x87,temp);            /* Part1_1Ah */
+  } else {
+      SiS_SetRegANDOR(SiS_Part1Port,0x1A,0x07,temp);            /* Part1_1Ah */
+  }
+
+  tempbx = push2;                                      		/* p bx temppush2 BPLVDEE  */
+  tempcx = push1;                                      		/* pop cx temppush1 NPLVDES */
+  push1 = (USHORT)(tempeax & 0xFFFF);
+
+  if(!(SiS_VBInfo & SetInSlaveMode)) {
+    if(SiS_LCDResInfo == Panel800x600) {
+      if(resinfo == 7) tempcx++;
+    }
+    if(SiS_IF_DEF_LVDS == 0) {	                                /* TW: Inserted from 650/LVDS BIOS */
+        if(resinfo == 8) tempcx++;				/* TW: Modified according to 650/301 BIOSes */
+    }
+    if(SiS_LCDResInfo == Panel640x480) {                        /* TW: Inserted from 650/301+LVDS BIOSes */
+        tempbx = SiS_VGAVDE;                                    /* TW: Inserted from 650/301+LVDS BIOS */
+	tempcx = tempbx;					/* TW: Inserted from 650/301+LVDS BIOS */
+        tempbx--;						/* TW: Inserted from 650/301+LVDS BIOS */
+    }
+  }
+
+  temp = (tempbx & 0xFF00) >> 8;
+  temp &= 0x07;
+  temp <<= 3;
+  temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
+  SiS_SetReg1(SiS_Part1Port,0x1D,temp);                          /* Part1_1Dh */
+
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x1C,temp);                          /* Part1_1Ch  */
+
+  temp = tempcx & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x1B,temp);                          /* Part1_1Bh  */ 
+
+  tempecx = SiS_VGAVT;
+  tempebx = SiS_VDE;
+  tempeax = SiS_VGAVDE;
+  tempecx = tempecx-tempeax;                                 	/* VGAVT-VGAVDE  */
+  tempeax <<= 18;
+  temp = (USHORT)(tempeax % tempebx);
+  tempeax = tempeax / tempebx;
+  if(temp != 0)  tempeax++;
+  tempebx = tempeax;                                        	/* BPLVCFACT  */
+  tempvcfact = tempeax;
+  temp=(USHORT)(tempebx & 0x00FF);
+  SiS_SetReg1(SiS_Part1Port,0x37,temp);
+
+  temp=(USHORT)((tempebx & 0x00FF00) >> 8);
+  SiS_SetReg1(SiS_Part1Port,0x36,temp);
+
+  temp = (USHORT)((tempebx & 0x00030000) >> 16);
+  if(SiS_VDE==SiS_VGAVDE) temp |= 0x04;
+  SiS_SetReg1(SiS_Part1Port,0x35,temp);
+  
+  tempecx = SiS_VGAHDE;
+  tempebx = SiS_HDE;
+  tempeax = tempecx;
+  tempeax <<= 16;
+  tempeax = tempeax / tempebx;
+  if(tempebx == tempecx)  tempeax = 0xFFFF;
+  tempecx = tempeax;
+  tempeax = SiS_VGAHDE;
+  tempeax <<= 16;
+  tempeax = tempeax / tempecx;
+  tempecx <<= 16;
+  tempeax--;
+  tempecx = tempecx | (tempeax & 0xFFFF);
+  temp=(USHORT)(tempecx & 0x00FF);
+  SiS_SetReg1(SiS_Part1Port,0x1F,temp);                          /* Part1_1Fh  */
+
+  tempeax = SiS_VGAVDE;
+  tempeax <<= 18;
+  tempeax = tempeax / tempvcfact;
+  tempbx = (USHORT)(tempeax & 0x0FFFF);
+
+  if(SiS_LCDResInfo == Panel1024x768) tempbx--;
+
+  if(SiS_SetFlag & EnableLVDSDDA)  tempbx = 1;
+
+  temp = ((tempbx & 0xFF00) >> 8) << 3;
+  temp = temp | (USHORT)(((tempecx & 0x0000FF00) >> 8) & 0x07);
+  SiS_SetReg1(SiS_Part1Port,0x20,temp);                         /* Part1_20h */
+
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x21,temp);                         /* Part1_21h */
+
+  tempecx >>= 16;   	                                  	/* BPLHCFACT  */
+  if(!(modeflag & HalfDCLK)) tempecx >>= 1;			/* TW: Inserted from BIOS */
+  temp=(USHORT)((tempecx & 0x0000FF00) >> 8);
+  SiS_SetReg1(SiS_Part1Port,0x22,temp);                         /* Part1_22h */
+
+  temp=(USHORT)(tempecx & 0x000000FF);
+  SiS_SetReg1(SiS_Part1Port,0x23,temp);
+
+  /* TW: Only for 650/LVDS and 301LV/302LV */
+  if((SiS_IF_DEF_LVDS == 1) || (SiS_VBInfo & (VB_SIS301LV|VB_SIS302LV))){
+  	SiS_SetReg1(SiS_Part1Port,0x1e,0x20);
+  }
+
+  return;
+}
+
+/* TW: Double-checked against 650/LVDS (1.10.07) and 650/301 BIOS */
+void SiS_SetCRT2Offset(USHORT SiS_Part1Port,UCHAR *ROMAddr,USHORT ModeNo,
+                       USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
+		       PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT offset;
+  UCHAR temp;
+
+  if(SiS_VBInfo & SetInSlaveMode) return;
+
+  offset = SiS_GetOffset(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                         HwDeviceExtension);
+  temp = (UCHAR)(offset & 0xFF);
+  SiS_SetReg1(SiS_Part1Port,0x07,temp);
+  temp = (UCHAR)((offset & 0xFF00) >> 8);
+  SiS_SetReg1(SiS_Part1Port,0x09,temp);
+  temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
+  SiS_SetReg1(SiS_Part1Port,0x03,temp);
 }
 
+/* TW: Checked with 650/LVDS and 650/301 BIOS */
 USHORT
-SiS_GetOffset (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-	       USHORT RefreshRateTableIndex,
-	       PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetOffset(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+              USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT temp, colordepth;
-	USHORT modeinfo, index, infoflag;
-	USHORT ColorDepth[] = { 0x01, 0x02, 0x04 };
-
-	modeinfo = SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
-	infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	if (HwDeviceExtension->jChipType < SIS_315H) {	/* 300 series */
-		index = (modeinfo >> 4) & 0xFF;
-	} else {		/* 310 series */
-
-		index = (modeinfo >> 8) & 0xFF;
-	}
-	temp = SiS_ScreenOffset[index];
-	if (infoflag & InterlaceMode) {
-		temp = temp << 1;
-	}
-	colordepth = SiS_GetColorDepth (ROMAddr, ModeNo, ModeIdIndex);
-
-	if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
-		temp = ModeNo - 0x7C;
-		colordepth = ColorDepth[temp];
-		temp = 0x6B;
-		if (infoflag & InterlaceMode) {
-			temp = temp << 1;
-		}
-		return (temp * colordepth);
-	} else
-		return (temp * colordepth);
+  USHORT temp,colordepth;
+  USHORT modeinfo,index,infoflag;
+  USHORT mode960low, mode960high;
+#if 0
+  USHORT ColorDepth[] = { 0x01, 0x02, 0x04 };
+#endif
+
+  modeinfo = SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+  infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  if (HwDeviceExtension->jChipType < SIS_315H ) {
+    	index = (modeinfo >> 4) & 0xFF;
+	/* TW: Modes 1280x960 changed number, so this is redundant */
+	mode960low = 0x7c;
+	mode960high = 0x7e;
+  } else {
+    	index = (modeinfo >> 8) & 0xFF;       /* TW: In 650 BIOS (LVDS AND 301), 1280x960 modes are 7b-7d! */
+	mode960low = 0x7c;                    /* TW: This is a bug in both BIOS versions ! */
+	mode960high = 0x7e;		      /* TW: Corrected here in LVDS BIOS 1.10.07, but not in tables! */
+  }
+
+#if 0
+  /* TW: Not doing this strange stuff makes 1280x960 at least work on CRT1 */
+  if((ModeNo >= mode960low) && (ModeNo <= mode960high)) {
+    	temp = ModeNo - mode960low;
+    	colordepth = ColorDepth[temp];
+    	temp = 0x6b;  /* TW: Why the heck? */
+  } else {
+#endif
+        temp = SiS_ScreenOffset[index];
+        colordepth = SiS_GetColorDepth(ROMAddr,ModeNo,ModeIdIndex);
+#if 0
+  }
+#endif
+
+  if(infoflag & InterlaceMode) temp <<= 1;
+
+  temp *= colordepth;
+
+  /* TW: Added this entire "if"-section from 650/LVDS BIOS */
+  if((ModeNo >= 0x26) && (ModeNo <= 0x28)) {
+        colordepth >>= 1;
+	temp += colordepth;
+  }
+
+  return(temp);
 }
 
+/* Checked with 650/LVDS BIOS */
 USHORT
-SiS_GetColorDepth (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_GetColorDepth(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-	USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
-	SHORT index;
-	USHORT modeflag;
+  USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
+  SHORT  index;
+  USHORT modeflag;
+
+  if(ModeNo <= 0x13)
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  else
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+  index = (modeflag & ModeInfoFlag) - ModeEGA;
+  if(index < 0) index = 0;
+  return(ColorDepth[index]);
+}
+
+/* TW: Checked against 650/LVDS (1.10.07), 650/301 and 630/301B BIOS */
+void
+SiS_SetCRT2Sync(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT tempah=0,tempbl,infoflag,flag;
+
+  flag = 0;
+  tempbl = 0xC0;   /* TW: Severe BIOS bug in all BIOSes except 650/LVDS 1.10.07 */
+
+  infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+
+  if(SiS_IF_DEF_LVDS == 1) {				     /* LVDS */
+    if(SiS_VBInfo & SetCRT2ToLCD) {
+      tempah = SiS_LCDInfo;
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
+              tempbl = tempah & 0xc0;
+      }
+      if(SiS_LCDInfo & LCDSync) {
+        flag = 1;
+      }
+    }
+  } else if ( (HwDeviceExtension->jChipType < SIS_315H) &&   /* 630/301B */
+              (SiS_VBType & VB_SIS301BLV302BLV) ) {
+     if(SiS_VBInfo & SetCRT2ToLCD) {
+        tempah = SiS_LCDInfo;
+	if(SiS_LCDInfo & LCDSync) {
+           flag = 1;
+        }
+     }
+  } else if (HwDeviceExtension->jChipType < SIS_315H) {      /* 630/301 */
+     if(SiS_VBInfo & SetCRT2ToLCD) {
+         tempah = SiS_LCDInfo;
+	 if(SiS_LCDInfo & LCDNonExpandingShift) {
+	    flag = 1;
+	 }
+     }
+  }
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
-	index = (modeflag & ModeInfoFlag) - ModeEGA;
-	if (index < 0)
-		index = 0;
-	return (ColorDepth[index]);
-}
+  if(flag != 1) tempah = infoflag >> 8;
 
-void
-SiS_SetCRT2Sync (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		 USHORT RefreshRateTableIndex)
-{
-	USHORT tempah = 0, infoflag, flag;
+  tempah &= 0xC0;
+  tempah |= 0x20;
 
-	flag = 0;
-	infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	if (SiS_IF_DEF_LVDS == 1) {
-		if (SiS_VBInfo & SetCRT2ToLCD) {
-			tempah = SiS_LCDInfo;
-			if (tempah & LCDSync) {
-				flag = 1;
-			}
-		}
-	}
-	if (flag != 1)
-		tempah = infoflag >> 8;
-	tempah = tempah & 0xC0;
-	tempah = tempah | 0x20;
-	if (!(SiS_LCDInfo & LCDRGB18Bit))
-		tempah = tempah | 0x10;
-	if (SiS_IF_DEF_CH7005 == 1)
-		tempah = tempah | 0xC0;
-
-	SiS_SetRegANDOR (SiS_Part1Port, 0x19, 0x3F, tempah);
-}
+  if(!(SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
 
-void
-SiS_SetCRT2FIFO (USHORT SiS_Part1Port, ULONG ROMAddr, USHORT ModeNo,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT temp, index;
-	USHORT modeidindex, refreshratetableindex;
-	USHORT VCLK, MCLK, colorth = 0, data, data2;
-	ULONG eax;
-	UCHAR LatencyFactor[] = { 97, 88, 86, 79, 77, 00,	/*; 64  bit    BQ=2   */
-		00, 87, 85, 78, 76, 54,	/*; 64  bit    BQ=1   */
-		97, 88, 86, 79, 77, 00,	/*; 128 bit    BQ=2   */
-		00, 79, 77, 70, 68, 48,	/*; 128 bit    BQ=1   */
-		80, 72, 69, 63, 61, 00,	/*; 64  bit    BQ=2   */
-		00, 70, 68, 61, 59, 37,	/*; 64  bit    BQ=1   */
-		86, 77, 75, 68, 66, 00,	/*; 128 bit    BQ=2   */
-		00, 68, 66, 59, 57, 37
-	};			/*; 128 bit    BQ=1   */
-
-	SiS_SearchModeID (ROMAddr, ModeNo, &modeidindex);
-	SiS_SetFlag = SiS_SetFlag & (~ProgrammingCRT2);
-	SiS_SelectCRT2Rate = 0;
-	refreshratetableindex = SiS_GetRatePtrCRT2 (ROMAddr, ModeNo, modeidindex);	/* 11.GetRatePtr */
-	if (ModeNo >= 0x13) {
-		index = SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
-		index = index & 0x3F;
-		VCLK = SiS_VCLKData[index].CLOCK;	/* Get VCLK  */
-		index = SiS_GetReg1 (SiS_P3c4, 0x1A);
-		index = index & 07;
-		MCLK = SiS_MCLKData[index].CLOCK;	/* Get MCLK  */
-		data2 = SiS_ModeType - 0x02;
-		switch (data2) {
-		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;
-		}
-		data2 = (data2 * VCLK) / MCLK;	/*  bx */
+  if (SiS_LCDResInfo == Panel640x480) {
+	/* TW: BIOS does something here (301, 301LV and LVDS) @@@ */
+  }
+
+  if(!(SiS_VBType & VB_SIS301)) {
+  	tempah &= 0x3f;
+  	tempah |= tempbl;
+  }
+
+  SiS_SetRegANDOR(SiS_Part1Port,0x19,0x3F,tempah);
+}
+
+/* TW: Set FIFO on 300 series */
+/* TW: Checked against 630/301B BIOS; does not set PCI registers */
+void
+SiS_SetCRT2FIFO_300(UCHAR *ROMAddr,USHORT ModeNo,
+                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT temp,index;
+  USHORT modeidindex,refreshratetableindex;
+  USHORT VCLK,MCLK,colorth=0,data2;
+  ULONG  data,eax;
+  UCHAR  LatencyFactor[] = {
+  	97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
+        00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
+        97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
+        00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
+        80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
+        00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
+        86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
+        00, 68, 66, 59, 57, 37};      /*; 128 bit    BQ=1   */
+
+  SiS_SearchModeID(ROMAddr,&ModeNo,&modeidindex);
+  SiS_SetFlag &= (~ProgrammingCRT2);
+  SiS_SelectCRT2Rate = 0;
+  refreshratetableindex = SiS_GetRatePtrCRT2(ROMAddr,ModeNo,modeidindex);
+
+  if(ModeNo >= 0x13) {
+    index = SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
+    index &= 0x3F;
+    VCLK = SiS_VCLKData[index].CLOCK;
+    index = SiS_GetReg1(SiS_P3c4,0x1A);
+    index &= 0x07;
+    MCLK = SiS_MCLKData_0[index].CLOCK;
+    data2 = SiS_ModeType - 0x02;
+    switch (data2) {
+      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;
+    }
+    /* data2=(data2*VCLK)/MCLK;   */  /*  bx */
+    data2 = (colorth * VCLK) / MCLK;  /* TW */
+
+    temp = SiS_GetReg1(SiS_P3c4,0x14);
+    temp = ((temp&0x00FF)>>6)<<1;
+    if(temp == 0) temp=1;
+    temp <<= 2;
+
+    data2 = temp - data2;
+
+/*  if(data2%(28*16)) {		 TW: WRONG
+      	data2=data2/(28*16);
+      	data2++;
+    } else {
+      	data2=data2/(28*16);
+    } */
+    if((28*16) % data2) {		/* TW */
+      	data2 = (28 * 16) / data2;
+      	data2++;
+    } else {
+      	data2 = (28 * 16) / data2;
+    }
+
+    index = 0;
+    temp = SiS_GetReg1(SiS_P3c4,0x14);
+    if(temp & 0x0080) index += 12;
+
+#ifndef LINUX_XF86
+    SiS_SetReg4(0xcf8,0x800000A0);
+    eax=SiS_GetReg3(0xcfc);
+#else
+  /* TW: 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.
+   */
+    eax = pciReadLong(0x00000000, 0xA0);
+#endif
+    temp=(USHORT)(eax>>24);
+    if(!(temp&0x01)) index += 24;
 
-		temp = SiS_GetReg1 (SiS_P3c4, 0x14);
-		temp = ((temp & 0x00FF) >> 6) << 1;
-		if (temp == 0)
-			temp = 1;
-		temp = temp << 2;
-
-		data2 = temp - data2;
-		if (data2 % (28 * 16)) {
-			data2 = data2 / (28 * 16);
-			data2++;
-		} else {
-			data2 = data2 / (28 * 16);
-		}
+#ifndef LINUX_XF86
+    SiS_SetReg4(0xcf8,0x80000050);
+    eax=SiS_GetReg3(0xcfc);
+#else
+    eax = pciReadLong(0x00000000, 0x50);
+#endif
+    temp=(USHORT)(eax >> 24);
+    if(temp & 0x01) index += 6;
 
-		index = 0;
-		temp = SiS_GetReg1 (SiS_P3c4, 0x14);
-		if (temp & 0x0080)
-			index = index + 12;
-		SiS_SetReg4 (0xcf8, 0x800000A0);
-		eax = SiS_GetReg3 (0xcfc);
-		temp = (USHORT) (eax >> 24);
-		if (!(temp & 0x01))
-			index = index + 24;
-
-		SiS_SetReg4 (0xcf8, 0x80000050);
-		eax = SiS_GetReg3 (0xcfc);
-		temp = (USHORT) (eax >> 24);
-		if (temp & 0x01)
-			index = index + 6;
-		temp = (temp & 0x0F) >> 1;
-		index = index + temp;
-		data = LatencyFactor[index];
-		data = data + 15;
-		temp = SiS_GetReg1 (SiS_P3c4, 0x14);
-		if (!(temp & 0x80))
-			data = data + 5;
-		data = data + data2;
-
-		SiS_SetFlag = SiS_SetFlag | ProgrammingCRT2;
-		data = data * VCLK * colorth;
-		if (data % (MCLK << 4)) {
-			data = data / (MCLK << 4);
-			data++;
-		} else {
-			data = data / (MCLK << 4);
-		}
-		temp = 0x16;
-/*  Revision ID  */
-		temp = 0x13;
-/*  Revision ID  */
-		SiS_SetRegANDOR (SiS_Part1Port, 0x01, ~0x01F, temp);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x02, ~0x01F, temp);
-	}
-}
-
-void
-SiS_SetCRT2FIFO2 (USHORT SiS_Part1Port, ULONG ROMAddr, USHORT ModeNo,
-		  PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-#ifdef CONFIG_FB_SIS_315
-	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, 55, 87, 84, 116, 103, 135, 119,
-		    151 };
-#endif
-	USHORT temp, temp1, temp2, temp3;
-	USHORT index;
-	USHORT CRT1ModeNo, CRT2ModeNo;
-	USHORT ModeIdIndex;
-	USHORT RefreshRateTableIndex;
-
-	SiS_SetReg1 (SiS_Part1Port, 0x1, 0x3B);
-/* CRT1ModeNo=(UCHAR)SiS_GetReg1(SiS_P3d4,0x34); *//* get CRT1 ModeNo */
-	CRT1ModeNo = SiS_CRT1Mode;
-	/* CRT1ModeNo =ModeNo; */
-	SiS_SearchModeID (ROMAddr, CRT1ModeNo, &ModeIdIndex);	/* Get ModeID Table */
-	SiS_SetFlag = SiS_SetFlag & (~ProgrammingCRT2);
-
-	RefreshRateTableIndex = SiS_GetRatePtrCRT2 (ROMAddr, CRT1ModeNo, ModeIdIndex);	/* Set REFIndex-> for crt1 refreshrate */
-	index =
-	    SiS_GetVCLK2Ptr (ROMAddr, CRT1ModeNo, ModeIdIndex,
-			     RefreshRateTableIndex, HwDeviceExtension);
-	temp1 = SiS_VCLKData[index].CLOCK;	/* Get VCLK  */
-
-	temp2 = SiS_GetColorDepth (ROMAddr, CRT1ModeNo, ModeIdIndex);
-#ifdef CONFIG_FB_SIS_315
-	index = SiS_Get310DRAMType (ROMAddr);
-#endif
-	temp3 = SiS_MCLKData[index].CLOCK;	/* Get MCLK  */
-
-	temp = SiS_GetReg1 (SiS_P3c4, 0x14);
-	if (temp & 0x02)
-		temp = 16;
-	else
-		temp = 8;
-
-	temp = temp - temp1 * temp2 / temp3;	/* 16-DRamBus - DCLK*BytePerPixel/MCLK */
-
-	if ((52 * 16 % temp) == 0)
-		temp = 52 * 16 / temp + 40;
-	else
-		temp = 52 * 16 / temp + 40 + 1;
-
-	/* get DRAM latency */
-	temp1 = (SiS_GetReg1 (SiS_P3c4, 0x17) >> 3) & 0x7;	/* SR17[5:3] DRAM Queue depth */
-	temp2 = (SiS_GetReg1 (SiS_P3c4, 0x17) >> 6) & 0x3;	/* SR17[7:6] DRAM Grant length */
-
-#ifdef CONFIG_FB_SIS_315
-	if (SiS_Get310DRAMType (ROMAddr) < 2) {
-		for (temp3 = 0; temp3 < 16; temp3 += 2) {
-			if ((CombCode[temp3] == temp1)
-			    && (CombCode[temp3 + 1] == temp2)) {
-				temp3 = CRT2ThLow[temp3 >> 1];
-			}
-		}
-	} else {
-		for (temp3 = 0; temp3 < 16; temp3 += 2) {
-			if ((CombCode[temp3] == temp1)
-			    && (CombCode[temp3 + 1] == temp2)) {
-				temp3 = CRT2ThLow[8 + (temp3 >> 1)];
-			}
-		}
-	}
+    temp = (temp & 0x0F) >> 1;
+    index += temp;
+    data = LatencyFactor[index];
+    data += 15;
+    temp = SiS_GetReg1(SiS_P3c4,0x14);
+    if(!(temp & 0x80)) data += 5;
+
+    data += data2;
+
+    SiS_SetFlag |= ProgrammingCRT2;
+
+    data = data * VCLK * colorth;
+    if(data % (MCLK << 4)) {
+      	data = data / (MCLK << 4);
+      	data++;
+    } else {
+      	data = data / (MCLK << 4);
+    }
+
+    /* TW: Inserted this entire section */
+    temp = SiS_GetReg1(SiS_Part1Port,0x01);
+    if( ( (HwDeviceExtension->jChipType == SIS_630) ||
+         (HwDeviceExtension->jChipType == SIS_730) ) &&
+       (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
+    {
+	temp = (temp & (~0x1F)) | 0x1b;
+    } else {
+	temp = (temp & (~0x1F)) | 0x16;
+    }
+    SiS_SetRegANDOR(SiS_Part1Port,0x01,0xe0,temp);
+
+    if(data <= 6) data = 6;
+    if(data > 0x14) data = 0x14;
+    if( (HwDeviceExtension->jChipType == SIS_630) &&
+        (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
+    {
+   	if(data > 0x13) data = 0x13;
+    }
+    SiS_SetRegANDOR(SiS_Part1Port,0x02,~0x01F,data);
+   /* TW end */
+  }
+}
+
+/* TW: Set FIFO on 310 series */
+#ifdef SIS315H
+void
+SiS_SetCRT2FIFO_310(UCHAR *ROMAddr,USHORT ModeNo,
+                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+
+  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,
+                        55, 87, 84,116,103,135,119,151};
+  USHORT temp3,tempax,tempbx,tempcx;
+  USHORT tempcl, tempch;
+  USHORT index;
+  USHORT CRT1ModeNo,CRT2ModeNo;
+  USHORT ModeIdIndex;
+  USHORT RefreshRateTableIndex;
+  USHORT SelectRate_backup;
+
+  SiS_SetReg1(SiS_Part1Port,0x01,0x3B);
+
+  CRT1ModeNo = SiS_CRT1Mode;                             /* get CRT1 ModeNo */
+  SiS_SearchModeID(ROMAddr,&CRT1ModeNo,&ModeIdIndex);
+
+  SiS_SetFlag &= (~ProgrammingCRT2);
+  SelectRate_backup = SiS_SelectCRT2Rate;
+  SiS_SelectCRT2Rate = 0;
+
+  /* Set REFIndex for crt1 refreshrate */
+  RefreshRateTableIndex = SiS_GetRatePtrCRT2(ROMAddr,CRT1ModeNo,
+                                             ModeIdIndex);
+
+  index = SiS_GetVCLK2Ptr(ROMAddr,CRT1ModeNo,ModeIdIndex,
+                          RefreshRateTableIndex,HwDeviceExtension);
+  tempax = SiS_VCLKData[index].CLOCK;                         /* Get DCLK (VCLK?) */
+
+  tempbx = SiS_GetColorDepth(ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
+  tempbx >>= 1;
+  if(!tempbx) tempbx++;
+
+  tempax *= tempbx;
+
+  tempbx = SiS_GetMCLK(ROMAddr, HwDeviceExtension);		     /* Get MCLK */
+
+  tempax /= tempbx;
+
+  tempbx = tempax;
+
+#if 0 /* TW: BIOS code is skrewed */
+  if(SiS_GetReg1(SiS_P3c4,0x14) & 0x02) {
+   	tempax = 16;
+  } else {
+    	tempax = 8;
+  }
 #endif
+  tempax = 16;
 
-	temp += temp3;		/* CRT1 Request Period */
+  tempax -= tempbx;
 
-	CRT2ModeNo = ModeNo;	/* get CRT2 ModeNo */
-	SiS_SearchModeID (ROMAddr, CRT2ModeNo, &ModeIdIndex);	/* Get ModeID Table */
-	SiS_SetFlag = SiS_SetFlag | ProgrammingCRT2;
-	RefreshRateTableIndex = SiS_GetRatePtrCRT2 (ROMAddr, CRT1ModeNo, ModeIdIndex);	/* Set REFIndex-> for crt1 refreshrate */
-	index =
-	    SiS_GetVCLK2Ptr (ROMAddr, CRT2ModeNo, ModeIdIndex,
-			     RefreshRateTableIndex, HwDeviceExtension);
-	temp1 = SiS_VCLKData[index].CLOCK;	/* Get VCLK  */
-
-	temp2 = SiS_GetColorDepth (ROMAddr, CRT2ModeNo, ModeIdIndex);
-#ifdef CONFIG_FB_SIS_315
-	index = SiS_Get310DRAMType (ROMAddr);
-#endif
-	temp3 = SiS_MCLKData[index].CLOCK;	/* Get MCLK  */
-
-	if ((temp * temp1 * temp2) % (16 * temp3) == 0)
-		temp = temp * temp1 * temp2 / (16 * temp3);	/* CRT1 Request period * TCLK*BytePerPixel/(MCLK*16) */
-	else
-		temp = temp * temp1 * temp2 / (16 * temp3) + 1;	/* CRT1 Request period * TCLK*BytePerPixel/(MCLK*16) */
-
-	if (temp > 0x37)
-		temp = 0x37;
-
-	SiS_SetRegANDOR (SiS_Part1Port, 0x02, ~0x3F, temp);
+  tempbx = tempax;    /* tempbx = 16-DRamBus - DCLK*BytePerPixel/MCLK */
 
-}
+  tempax = ((52 * 16) / tempbx);
 
-void
-SiS_GetLVDSDesData (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex)
-{
-
-	USHORT modeflag;
-	USHORT PanelIndex, ResIndex;
-	SiS_LVDSDesStruct *PanelDesPtr = NULL;
-	if ((SiS_IF_DEF_LVDS == 0)
-	    && ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {	/*301b *//*for test */
-		SiS_GetLVDSDesPtrA (ROMAddr, ModeNo, ModeIdIndex,
-				    RefreshRateTableIndex, &PanelIndex,
-				    &ResIndex);
-		switch (PanelIndex) {
-		case 0:
-			PanelDesPtr = LVDS1024x768Des_1;
-			break;
-		case 1:
-			PanelDesPtr = LVDS1280x1024Des_1;
-			break;
-		case 2:
-			PanelDesPtr = LVDS1280x960Des_1;
-			break;
-		case 3:
-			PanelDesPtr = LVDS1024x768Des_2;
-			break;
-		case 4:
-			PanelDesPtr = LVDS1280x1024Des_2;
-			break;
-		case 5:
-			PanelDesPtr = LVDS1280x960Des_2;
-			break;
-		}
-	} else {
-		SiS_GetLVDSDesPtr (ROMAddr, ModeNo, ModeIdIndex,
-				   RefreshRateTableIndex, &PanelIndex,
-				   &ResIndex);
-		switch (PanelIndex) {
-		case 0:
-			PanelDesPtr = SiS_PanelType00_1;
-			break;
-		case 1:
-			PanelDesPtr = SiS_PanelType01_1;
-			break;
-		case 2:
-			PanelDesPtr = SiS_PanelType02_1;
-			break;
-		case 3:
-			PanelDesPtr = SiS_PanelType03_1;
-			break;
-		case 4:
-			PanelDesPtr = SiS_PanelType04_1;
-			break;
-		case 5:
-			PanelDesPtr = SiS_PanelType05_1;
-			break;
-		case 6:
-			PanelDesPtr = SiS_PanelType06_1;
-			break;
-		case 7:
-			PanelDesPtr = SiS_PanelType07_1;
-			break;
-		case 8:
-			PanelDesPtr = SiS_PanelType08_1;
-			break;
-		case 9:
-			PanelDesPtr = SiS_PanelType09_1;
-			break;
-		case 10:
-			PanelDesPtr = SiS_PanelType0a_1;
-			break;
-		case 11:
-			PanelDesPtr = SiS_PanelType0b_1;
-			break;
-		case 12:
-			PanelDesPtr = SiS_PanelType0c_1;
-			break;
-		case 13:
-			PanelDesPtr = SiS_PanelType0d_1;
-			break;
-		case 14:
-			PanelDesPtr = SiS_PanelType0e_1;
-			break;
-		case 15:
-			PanelDesPtr = SiS_PanelType0f_1;
-			break;
-		case 16:
-			PanelDesPtr = SiS_PanelType00_2;
-			break;
-		case 17:
-			PanelDesPtr = SiS_PanelType01_2;
-			break;
-		case 18:
-			PanelDesPtr = SiS_PanelType02_2;
-			break;
-		case 19:
-			PanelDesPtr = SiS_PanelType03_2;
-			break;
-		case 20:
-			PanelDesPtr = SiS_PanelType04_2;
-			break;
-		case 21:
-			PanelDesPtr = SiS_PanelType05_2;
-			break;
-		case 22:
-			PanelDesPtr = SiS_PanelType06_2;
-			break;
-		case 23:
-			PanelDesPtr = SiS_PanelType07_2;
-			break;
-		case 24:
-			PanelDesPtr = SiS_PanelType08_2;
-			break;
-		case 25:
-			PanelDesPtr = SiS_PanelType09_2;
-			break;
-		case 26:
-			PanelDesPtr = SiS_PanelType0a_2;
-			break;
-		case 27:
-			PanelDesPtr = SiS_PanelType0b_2;
-			break;
-		case 28:
-			PanelDesPtr = SiS_PanelType0c_2;
-			break;
-		case 29:
-			PanelDesPtr = SiS_PanelType0d_2;
-			break;
-		case 30:
-			PanelDesPtr = SiS_PanelType0e_2;
-			break;
-		case 31:
-			PanelDesPtr = SiS_PanelType0f_2;
-			break;
-		case 32:
-			PanelDesPtr = SiS_CHTVUNTSCDesData;
-			break;
-		case 33:
-			PanelDesPtr = SiS_CHTVONTSCDesData;
-			break;
-		case 34:
-			PanelDesPtr = SiS_CHTVUPALDesData;
-			break;
-		case 35:
-			PanelDesPtr = SiS_CHTVOPALDesData;
-			break;
-		}
-	}
-	SiS_LCDHDES = (PanelDesPtr + ResIndex)->LCDHDES;
-	SiS_LCDVDES = (PanelDesPtr + ResIndex)->LCDVDES;
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		if (SiS_LCDResInfo >= Panel1024x768) {
-			if (ModeNo <= 0x13) {
-				modeflag =
-				    SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-				if (!(modeflag & HalfDCLK)) {
-					SiS_LCDHDES = 320;
-				}
-			}
-		}
-	}
-	return;
+  if ((52*16 % tempbx) != 0) {
+    	tempax++;
+  }
+  tempcx = tempax;
+  tempcx += 40;
+
+  /* get DRAM latency */
+  tempcl = (SiS_GetReg1(SiS_P3c4,0x17) >> 3) & 0x7;     /* SR17[5:3] DRAM Queue depth */
+  tempch = (SiS_GetReg1(SiS_P3c4,0x17) >> 6) & 0x3;     /* SR17[7:6] DRAM Grant length */
+
+  for (temp3 = 0; temp3 < 16; temp3 += 2) {
+    if ((CombCode[temp3] == tempcl) && (CombCode[temp3+1] == tempch)) {
+      temp3 = CRT2ThLow[temp3 >> 1];
+    }
+  }
+
+  tempcx +=  temp3;                                      /* CRT1 Request Period */
+
+  CRT2ModeNo = ModeNo;                                   /* get CRT2 ModeNo */
+  SiS_SearchModeID(ROMAddr,&CRT2ModeNo,&ModeIdIndex);    /* Get ModeID Table */
+
+  SiS_SetFlag |= ProgrammingCRT2;
+  SiS_SelectCRT2Rate = SelectRate_backup;
+
+  RefreshRateTableIndex=SiS_GetRatePtrCRT2(ROMAddr,CRT1ModeNo,
+                                           ModeIdIndex);
+
+  index = SiS_GetVCLK2Ptr(ROMAddr,CRT2ModeNo,ModeIdIndex,
+                          RefreshRateTableIndex,HwDeviceExtension);
+  tempax = SiS_VCLKData[index].CLOCK;                          /* Get VCLK  */
+
+  tempbx = SiS_GetColorDepth(ROMAddr,CRT2ModeNo,ModeIdIndex);  /* Get colordepth */
+  tempbx >>= 1;
+  if(!tempbx) tempbx++;
+
+  tempax *= tempbx;
+
+  tempax *= tempcx;
+
+  tempbx = SiS_GetMCLK(ROMAddr, HwDeviceExtension);		       /* Get MCLK */
+  tempbx <<= 4;
 
+  tempcx = tempax;
+  tempax /= tempbx;
+  if(tempcx % tempbx) tempax++;		/* CRT1 Request period * TCLK * BytePerPixel / (MCLK*16) */
+
+  if (tempax > 0x37)  tempax = 0x37;
+
+  /* TW: 650/LVDS (1.10.07, 1.10.00), 650/301LV overrule calculated value; 315 does not */
+  if(HwDeviceExtension->jChipType == SIS_650) {
+  	tempax = 0x04;
+  }
+
+  SiS_SetRegANDOR(SiS_Part1Port,0x02,~0x3F,tempax);
 }
 
-void
-SiS_GetLVDSDesPtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex, USHORT * PanelIndex,
-		   USHORT * ResIndex)
+USHORT
+SiS_GetMCLK(UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT tempbx, tempal;
+  USHORT index;
 
-	tempbx = 0;
-	if (SiS_IF_DEF_CH7005 == 1) {
-		if (!(SiS_VBInfo & SetCRT2ToLCD)) {
-			tempbx = 32;
-			if (SiS_VBInfo & SetPALTV)
-				tempbx = tempbx + 2;
-			if (SiS_VBInfo & SetCHTVOverScan)
-				tempbx = tempbx + 1;
-		}
-	}
-	if (SiS_VBInfo & SetCRT2ToLCD) {
-		tempbx = SiS_LCDTypeInfo;
-		if (SiS_LCDInfo & LCDNonExpanding) {
-			tempbx = tempbx + 16;
-		}
-	}
-	if (ModeNo <= 0x13) {
-		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-	tempal = tempal & 0x1F;
-	*PanelIndex = tempbx;
-	*ResIndex = tempal;
+  index = SiS_Get310DRAMType(ROMAddr,HwDeviceExtension);
+  if(index >= 4) {
+    index -= 4;
+    return(SiS_MCLKData_1[index].CLOCK);
+  } else {
+    return(SiS_MCLKData_0[index].CLOCK);
+  }
 }
+#endif
 
-/*301b*/
+/* TW: Checked against 650/LVDS 1.10.07 BIOS */
 void
-SiS_GetLVDSDesPtrA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex, USHORT * PanelIndex,
-		    USHORT * ResIndex)
+SiS_GetLVDSDesData(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,
+		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT tempbx, tempal;
+  USHORT modeflag;
+  USHORT PanelIndex,ResIndex;
+  SiS_LVDSDesStruct  *PanelDesPtr=NULL;
+
+  if((SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCDA) ) {
+
+     SiS_GetLVDSDesPtrA(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                        &PanelIndex,&ResIndex);
+     switch (PanelIndex)
+     {
+     	case  0: PanelDesPtr = LVDS1024x768Des_1;   break;  /* --- expanding --- */
+     	case  1: PanelDesPtr = LVDS1280x1024Des_1;  break;
+     	case  2: PanelDesPtr = LVDS1280x960Des_1;   break;
+     	case  3: PanelDesPtr = LVDS1024x768Des_2;   break;  /* --- non expanding --- */
+     	case  4: PanelDesPtr = LVDS1280x1024Des_2;  break;
+     	case  5: PanelDesPtr = LVDS1280x960Des_2;   break;
+     }
 
-	tempbx = 0;
-	tempbx = SiS_LCDResInfo;
-	tempbx = tempbx - Panel1024x768;
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		tempbx = tempbx + 3;
-	}
+  } else {
 
-	if (ModeNo <= 0x13) {
-		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-	tempal = tempal & 0x1F;
-	*PanelIndex = tempbx;
-	*ResIndex = tempal;
-}
+     SiS_GetLVDSDesPtr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                       &PanelIndex,&ResIndex,HwDeviceExtension);
 
-/*end 301b*/
+     switch (PanelIndex)
+     {
+     	case  0: PanelDesPtr = SiS_PanelType00_1;   break; /* --- expanding --- | Gericom 1st supersonic (310) */
+     	case  1: PanelDesPtr = SiS_PanelType01_1;   break;
+     	case  2: PanelDesPtr = SiS_PanelType02_1;   break;
+     	case  3: PanelDesPtr = SiS_PanelType03_1;   break;
+     	case  4: PanelDesPtr = SiS_PanelType04_1;   break;
+     	case  5: PanelDesPtr = SiS_PanelType05_1;   break;
+     	case  6: PanelDesPtr = SiS_PanelType06_1;   break;
+     	case  7: PanelDesPtr = SiS_PanelType07_1;   break;
+     	case  8: PanelDesPtr = SiS_PanelType08_1;   break;
+     	case  9: PanelDesPtr = SiS_PanelType09_1;   break;
+     	case 10: PanelDesPtr = SiS_PanelType0a_1;   break;
+     	case 11: PanelDesPtr = SiS_PanelType0b_1;   break;
+     	case 12: PanelDesPtr = SiS_PanelType0c_1;   break;	/* TW: Clevo 2202 (300)  */
+     	case 13: PanelDesPtr = SiS_PanelType0d_1;   break;
+     	case 14: PanelDesPtr = SiS_PanelType0e_1;   break;	/* TW: Uniwill N271S2 (300) */
+     	case 15: PanelDesPtr = SiS_PanelType0f_1;   break;
+     	case 16: PanelDesPtr = SiS_PanelType00_2;   break;  /* --- non-expanding --- */
+     	case 17: PanelDesPtr = SiS_PanelType01_2;   break;
+     	case 18: PanelDesPtr = SiS_PanelType02_2;   break;
+     	case 19: PanelDesPtr = SiS_PanelType03_2;   break;
+     	case 20: PanelDesPtr = SiS_PanelType04_2;   break;
+     	case 21: PanelDesPtr = SiS_PanelType05_2;   break;
+     	case 22: PanelDesPtr = SiS_PanelType06_2;   break;
+     	case 23: PanelDesPtr = SiS_PanelType07_2;   break;
+     	case 24: PanelDesPtr = SiS_PanelType08_2;   break;
+     	case 25: PanelDesPtr = SiS_PanelType09_2;   break;
+     	case 26: PanelDesPtr = SiS_PanelType0a_2;   break;
+     	case 27: PanelDesPtr = SiS_PanelType0b_2;   break;
+     	case 28: PanelDesPtr = SiS_PanelType0c_2;   break;     /* TW: Gericom 2200C (300) */
+     	case 29: PanelDesPtr = SiS_PanelType0d_2;   break;
+     	case 30: PanelDesPtr = SiS_PanelType0e_2;   break;
+     	case 31: PanelDesPtr = SiS_PanelType0f_2;   break;
+     	case 32: PanelDesPtr = SiS_CHTVUNTSCDesData;   break;
+     	case 33: PanelDesPtr = SiS_CHTVONTSCDesData;   break;
+     	case 34: PanelDesPtr = SiS_CHTVUPALDesData;    break;
+     	case 35: PanelDesPtr = SiS_CHTVOPALDesData;    break;
+     }
+  }
+  SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+  SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
+
+  if(SiS_LCDInfo & LCDNonExpanding){
+    if(!(SiS_SetFlag & CRT2IsVGA)) {
+      if((HwDeviceExtension->jChipType < SIS_315H) || (SiS_LCDResInfo != Panel1280x1024)) {  /* TW: New from 650/LVDS 1.10.07 */
+        if(SiS_LCDResInfo >= Panel1024x768){
+          if(ModeNo <= 0x13){
+	    modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	    if(HwDeviceExtension->jChipType < SIS_315H) {
+	         if(!(modeflag & HalfDCLK)) {
+                     SiS_LCDHDES = 320;
+		 }
+	    } else {
+	         /* TW: New from 650/LVDS 1.10.07 */
+	         if(SiS_LCDResInfo == Panel1024x768)
+	             SiS_LCDHDES = 480;
+                 if(SiS_LCDResInfo == Panel1400x1050)
+	             SiS_LCDHDES = 804;
+                 if(!(modeflag & HalfDCLK)) {
+                     SiS_LCDHDES = 320;
+	             if(SiS_LCDResInfo == Panel1400x1050)
+	                SiS_LCDHDES = 632;
+                 }
+            }
+          }
+        }
+      }
+    }
+  }
+  return;
+}
+
+/* TW: Checked against 630/LVDS (2.04.5c) and 650/LVDS (1.10.07) BIOS */
+void
+SiS_GetLVDSDesPtr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                  USHORT RefreshRateTableIndex,USHORT *PanelIndex,
+		  USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT tempbx,tempal,modeflag;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+
+  tempbx = 0;
+  if(SiS_IF_DEF_CH70xx != 0) {
+    if(!(SiS_VBInfo & SetCRT2ToLCD)) {
+      tempbx = 32;
+      if(SiS_VBInfo & SetPALTV) tempbx += 2;
+      if(SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+    }
+  }
+  if(SiS_VBInfo & SetCRT2ToLCD) {
+    tempbx = SiS_LCDTypeInfo;
+    if(SiS_LCDInfo & LCDNonExpanding) tempbx += 16;
+    /* TW: Inserted from 650/LVDS (1.10.07) BIOS */
+    if(SiS_LCDInfo & 0x0100) {
+       if(modeflag & HalfDCLK) tempbx += 16;
+    }
+  }
+  /* TW: Inserted from 630/LVDS and 650/LVDS (1.10.07) BIOS */
+  if(SiS_SetFlag & CRT2IsVGA) {
+    if(SiS_LCDResInfo != Panel640x480)  {
+       tempal = 0x07;
+       if(HwDeviceExtension->jChipType < SIS_315H) {
+          if(SiS_GetReg1(SiS_P3c4,0x13) & 0x80) tempal++;
+       }
+    }
+  }
+
+  *PanelIndex = tempbx;
+  *ResIndex = tempal & 0x1F;
+}
+
+void
+SiS_GetLVDSDesPtrA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,USHORT *PanelIndex,
+		   USHORT *ResIndex)
+{
+  USHORT tempbx=0,tempal;
+
+  tempbx = SiS_LCDResInfo - PanelMin301;  /* TW: *not* PanelMinLVDS! */
+  if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 3;
+
+  if(ModeNo<=0x13)
+    	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  else
+    	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+  *PanelIndex = tempbx;
+  *ResIndex = tempal & 0x1F;
+}
+
+/* TW: Checked against 650/LVDS (1.10.07), 650/301LV, 630/301 and 630/301B (II) BIOS */
+void
+SiS_SetCRT2ModeRegs(USHORT BaseAddr,USHORT ModeNo, USHORT ModeIdIndex,
+                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT i,j,modeflag;
+  USHORT tempcl,tempah,tempbl,temp;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+  
+  /* TW: BIOS does not do this (neither 301 nor LVDS) */
+  /*     (But it's harmless; see SetCRT2Offset) */
+  SiS_SetReg1(SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
+
+  /* TW: Removed 301B302B301LV302LV check here to match 650/LVDS BIOS */
+  if(SiS_VBInfo & SetCRT2ToLCDA) {
+
+	/* TW:   1. for LVDS/302B/302LV **LCDA** */
+
+      SiS_SetRegANDOR(SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
+      SiS_SetRegAND(SiS_Part1Port,0x2E,0xF7);
+#if 0  /* TW: Not done in 650/301, 650/LVDS or 650/301LV BIOS*/
+      SiS_SetRegANDOR(SiS_Part1Port,0x13,0xFB,0x04);
+      SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xCF,0x30);
+      SiS_SetRegANDOR(SiS_Part4Port,0x21,0x3F,0xC0);
+      SiS_SetRegANDOR(SiS_Part4Port,0x23,0x7F,0x00);
+#endif
 
-void
-SiS_SetCRT2ModeRegs (USHORT BaseAddr, USHORT ModeNo,
-		     PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT i, j;
-	USHORT tempcl, tempah;
-/*301b*/
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x00, ~0x050, 0x40);
-		SiS_SetRegAND (SiS_Part1Port, 0x2E, 0xF7);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x13, 0xFB, 0x04);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x2c, 0xCF, 0x30);
-		SiS_SetRegANDOR (SiS_Part4Port, 0x21, 0x3F, 0xC0);
-		SiS_SetRegANDOR (SiS_Part4Port, 0x23, 0x7F, 0x00);
-	}
-	/*end 301b */
-	else {
-		for (i = 0, j = 4; i < 3; i++, j++)
-			SiS_SetReg1 (SiS_Part1Port, j, 0);
-
-		tempcl = SiS_ModeType;
-		if (HwDeviceExtension->jChipType < SIS_315H) {	/* 300 series */
-			if (ModeNo > 0x13) {
-				tempcl = tempcl - ModeVGA;
-				if ((tempcl > 0) || (tempcl == 0)) {
-					tempah = ((0x010 >> tempcl) | 0x080);
-				}
-			} else {
-				tempah = 0x080;
-			}
-			if (SiS_VBInfo & SetInSlaveMode) {
-				tempah = (tempah ^ 0x0A0);
-			}
-		} else {	/* 310 series */
+  } else {
 
-			if (ModeNo > 0x13) {
-				tempcl = tempcl - ModeVGA;
-				if ((tempcl > 0) || (tempcl == 0)) {
-					tempah = (0x008 >> tempcl);
-					if (tempah == 0)
-						tempah = 1;
-					tempah |= 0x040;
-				}
-			} else {
-				tempah = 0x040;
-			}
+    for(i=0,j=4;i<3;i++,j++) SiS_SetReg1(SiS_Part1Port,j,0);
 
-			if (SiS_VBInfo & SetInSlaveMode) {
-				tempah = (tempah ^ 0x050);
-			}
+    tempcl = SiS_ModeType;
 
-		}
+    if(HwDeviceExtension->jChipType < SIS_315H) {
 
-		if (SiS_VBInfo & CRT2DisplayFlag) {
-			tempah = 0;
-		}
-		SiS_SetReg1 (SiS_Part1Port, 0x00, tempah);
+      /* ---- 300 series ---- */
 
-		if (SiS_IF_DEF_LVDS == 0) {	/* ifdef 301 */
-			tempah = 0x01;
-			if (!(SiS_VBInfo & SetInSlaveMode)) {
-				tempah = (tempah | 0x02);
-			}
-			if (!(SiS_VBInfo & SetCRT2ToRAMDAC)) {
-				tempah = (tempah ^ 0x05);
-				if (!(SiS_VBInfo & SetCRT2ToLCD)) {
-					tempah = (tempah ^ 0x01);
-				}
-			}
+      /* TW: Inserted entire if-section from 630/301B BIOS */
+      if(SiS_VBType & VB_SIS301BLV302BLV) {
+	  temp = SiS_GetReg1(SiS_P3c4,0x32);
+	  temp &= 0xef;
+	  temp |= 0x02;
+	  if(SiS_VBInfo & SetCRT2ToTV) {
+	     temp |= 0x10;
+	     temp &= 0xfd;
+	  }
+	  SiS_SetReg1(SiS_P3c4,0x32,temp);
+      }
 
-			tempcl = tempah;	/* 05/03/01 ynlai for TV display bug */
+      if(ModeNo > 0x13){
+        tempcl -= ModeVGA;
+        if((tempcl > 0) || (tempcl == 0)) {  /* TW: tempcl is USHORT -> always true! */
+           tempah = ((0x010 >> tempcl) | 0x080);
+        }
+      } else  tempah = 0x080;
 
-			if (HwDeviceExtension->jChipType < SIS_315H) {	/* 300 series */
-				tempah = (tempah << 5) & 0xFF;
-				if (SiS_VBInfo & CRT2DisplayFlag) {
-					tempah = 0;
-				}
-				SiS_SetReg1 (SiS_Part1Port, 0x01, tempah);
+      if(SiS_VBInfo & SetInSlaveMode)  tempah = (tempah ^ 0x0A0);
 
-				tempah = tempah >> 5;
-			} else {	/* 310 series */
+    } else {
 
-				if (SiS_VBInfo & CRT2DisplayFlag) {
-					tempah = 0;
-				}
-				tempah =
-				    (SiS_GetReg1 (SiS_Part1Port, 0x2E) & 0xF8) |
-				    tempah;
-				SiS_SetReg1 (SiS_Part1Port, 0x2E, tempah);
-				tempah = tempcl;
-			}
+    /* ---- 310 series ---- */
 
-			if ((SiS_ModeType == ModeVGA)
-			    && (!(SiS_VBInfo & SetInSlaveMode))) {
-				tempah = tempah | 0x010;
-			}
+      /* TW: Inserted from 650/301/301LV BIOS */
+      if(SiS_VBType & VB_SIS301BLV302BLV) {
+        if(SiS_VBInfo & CRT2DisplayFlag) {
+	   SiS_SetRegOR(SiS_Part1Port,0x2e,0x08);
+        }
+      }
 
-			if (SiS_LCDResInfo == Panel1024x768)
-				tempah = tempah | 0x080;
+      if(ModeNo > 0x13) {
+        tempcl -= ModeVGA;
+        if((tempcl > 0) || (tempcl == 0)) {  /* TW: tempcl is USHORT -> always true! */
+           tempah = (0x008 >> tempcl);
+           if (tempah == 0) tempah = 1;
+           tempah |= 0x040;
+        }
+      } else  tempah = 0x040;
 
-			if ((SiS_LCDResInfo == Panel1280x1024)
-			    || (SiS_LCDResInfo == Panel1280x960)) {
-				tempah = tempah | 0x080;
-			}
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				if (SiS_VBInfo & SetInSlaveMode) {
-					if (
-					    ((SiS_VBType & VB_SIS301B)
-					     || (SiS_VBType & VB_SIS302B))) {	/*301b */
-						if (SiS_SetFlag & TVSimuMode)
-							tempah = tempah | 0x020;
-					} else
-						tempah = tempah | 0x020;
-				}
-			}
-			SiS_SetRegANDOR (SiS_Part4Port, 0x0D, ~0x0BF, tempah);
-			tempah = 0;
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				if (SiS_VBInfo & SetInSlaveMode) {
-					if (
-					    ((SiS_VBType & VB_SIS301B)
-					     || (SiS_VBType & VB_SIS302B))) {	/*301b */
-						{
-							SiS_SetFlag =
-							    SiS_SetFlag |
-							    RPLLDIV2XO;
-							tempah = tempah | 0x40;
-						}
-					} else {
-						if (!(SiS_SetFlag & TVSimuMode)) {
-							if (!
-							    (SiS_VBInfo &
-							     SetCRT2ToHiVisionTV))
-							{
-								SiS_SetFlag =
-								    SiS_SetFlag
-								    |
-								    RPLLDIV2XO;
-								tempah =
-								    tempah |
-								    0x40;
-							}
-						}
-					}
-				} else {
-					SiS_SetFlag = SiS_SetFlag | RPLLDIV2XO;
-					tempah = tempah | 0x40;
-				}
-			}
-			if (SiS_LCDResInfo == Panel1280x1024)
-				tempah = tempah | 0x80;
-			if (SiS_LCDResInfo == Panel1280x960)
-				tempah = tempah | 0x80;
-			SiS_SetReg1 (SiS_Part4Port, 0x0C, tempah);
-		} else {
-			/*LVDS*/ tempah = 0;
-			if (!(SiS_VBInfo & SetInSlaveMode)) {
-				tempah = tempah | 0x02;
-			}
-			SiS_SetRegANDOR (SiS_Part1Port, 0x2e, 0xF0, tempah);
-		}
-	}
-/*301b*/
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (!(SiS_VBInfo & SetCRT2ToLCDA))) {
-		if (SiS_IsDualEdge (BaseAddr))
-			SiS_SetRegANDOR (SiS_Part1Port, 0x13, 0xFB, 0x00);
-		else
-			SiS_SetRegANDOR (SiS_Part1Port, 0x13, 0xFF, 0x00);
-		if (SiS_IsDualEdge (BaseAddr))
-			SiS_SetRegANDOR (SiS_Part1Port, 0x2c, 0xCF, 0x00);
-		else
-			SiS_SetRegANDOR (SiS_Part1Port, 0x2c, 0xFF, 0x00);
-		if (SiS_IsDualEdge (BaseAddr))
-			SiS_SetRegANDOR (SiS_Part4Port, 0x21, 0x3F, 0x00);
-		else
-			SiS_SetRegANDOR (SiS_Part4Port, 0x21, 0xFF, 0x00);
-
-		if (SiS_IsDualEdge (BaseAddr))
-			SiS_SetRegANDOR (SiS_Part4Port, 0x23, 0xFF, 0x80);
-		else
-			SiS_SetRegANDOR (SiS_Part4Port, 0x23, 0xFF, 0x00);
-	}
-
-/*end 301b*/
-}
-void
-SiS_GetCRT2Data (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex)
-{
-	if (SiS_IF_DEF_LVDS == 0) {	/*301  */
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-			if (SiS_VBInfo & SetCRT2ToLCDA)
-				SiS_GetCRT2DataLVDS (ROMAddr, ModeNo,
-						     ModeIdIndex,
-						     RefreshRateTableIndex);
-			else
-				SiS_GetCRT2Data301 (ROMAddr, ModeNo,
-						    ModeIdIndex,
-						    RefreshRateTableIndex);
-		} else
-			SiS_GetCRT2Data301 (ROMAddr, ModeNo, ModeIdIndex,
-					    RefreshRateTableIndex);
-		return;
-	} else {		/*LVDS */
-		SiS_GetCRT2DataLVDS (ROMAddr, ModeNo, ModeIdIndex,
-				     RefreshRateTableIndex);
-		return;
-	}
-}
-
-void
-SiS_GetCRT2DataLVDS (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		     USHORT RefreshRateTableIndex)
-{
-	USHORT tempax, tempbx;
-	USHORT CRT2Index, ResIndex;
-	SiS_LVDSDataStruct *LVDSData = NULL;
-
-	SiS_GetCRT2ResInfo (ROMAddr, ModeNo, ModeIdIndex);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		SiS_GetCRT2PtrA (ROMAddr, ModeNo, ModeIdIndex,
-				 RefreshRateTableIndex, &CRT2Index, &ResIndex);
-		switch (CRT2Index) {
-		case 0:
-			LVDSData = SiS_LVDS1024x768Data_1;
-			break;
-		case 1:
-			LVDSData = SiS_LVDS1280x1024Data_1;
-			break;
-		case 2:
-			LVDSData = SiS_LVDS1280x1024Data_1;
-			break;
-			/*  case  2:  LVDSData=SiS_LVDS1280x960Data_1;  break; */
-		case 3:
-			LVDSData = SiS_LVDS1024x768Data_2;
-			break;
-		case 4:
-			LVDSData = SiS_LVDS1280x1024Data_2;
-			break;
-		case 5:
-			LVDSData = SiS_LVDS1280x1024Data_2;
-			break;
-			/*  case  5:  LVDSData=SiS_LVDS1280x960Data_2;  break; */
-		}
-	}
+      if(SiS_VBInfo & SetInSlaveMode)  tempah = (tempah ^ 0x050);
 
-	else {
-		SiS_GetCRT2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &CRT2Index, &ResIndex);
-		switch (CRT2Index) {
-		case 0:
-			LVDSData = SiS_LVDS800x600Data_1;
-			break;
-		case 1:
-			LVDSData = SiS_LVDS1024x768Data_1;
-			break;
-		case 2:
-			LVDSData = SiS_LVDS1280x1024Data_1;
-			break;
-		case 3:
-			LVDSData = SiS_LVDS800x600Data_2;
-			break;
-		case 4:
-			LVDSData = SiS_LVDS1024x768Data_2;
-			break;
-		case 5:
-			LVDSData = SiS_LVDS1280x1024Data_2;
-			break;
-		case 6:
-			LVDSData = SiS_LVDS640x480Data_1;
-			break;
-		case 7:
-			LVDSData = SiS_CHTVUNTSCData;
-			break;
-		case 8:
-			LVDSData = SiS_CHTVONTSCData;
-			break;
-		case 9:
-			LVDSData = SiS_CHTVUPALData;
-			break;
-		case 10:
-			LVDSData = SiS_CHTVOPALData;
-			break;
-		}
+    }
+
+    if(SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
+
+    SiS_SetReg1(SiS_Part1Port,0x00,tempah);  	/* FUNCTION CONTROL */
+
+    if(SiS_IF_DEF_LVDS == 0) {
+
+	/* TW:   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
+
+    	tempah = 0x01;
+    	if(!(SiS_VBInfo & SetInSlaveMode)) {
+      		tempah |= 0x02;
+    	}
+    	if(!(SiS_VBInfo & SetCRT2ToRAMDAC)) {
+      		tempah = (tempah ^ 0x05);
+      		if(!(SiS_VBInfo & SetCRT2ToLCD)) {
+        		tempah = (tempah ^ 0x01);
+      		}
+    	}
+
+    	tempcl = tempah;
+
+    	if(HwDeviceExtension->jChipType < SIS_315H) {
+
+		/* --- 300 series --- */
+      		tempah = (tempah << 5) & 0xFF;
+      		if(SiS_VBInfo & CRT2DisplayFlag)  tempah=0;
+      		SiS_SetReg1(SiS_Part1Port,0x01,tempah);
+
+      		tempah = tempcl;
+
+    	} else {
+
+		/* --- 310 series --- */
+      		if(SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
+      		tempah = (SiS_GetReg1(SiS_Part1Port,0x2E) & 0xF8) | tempah;
+      		SiS_SetReg1(SiS_Part1Port,0x2E,tempah);
+
+      		tempah = tempcl;
+    	}
+
+    	if((SiS_ModeType == ModeVGA) && (!(SiS_VBInfo & SetInSlaveMode))) {
+      		tempah |= 0x010;
 	}
-	SiS_VGAHT = (LVDSData + ResIndex)->VGAHT;
-	SiS_VGAVT = (LVDSData + ResIndex)->VGAVT;
-	SiS_HT = (LVDSData + ResIndex)->LCDHT;
-	SiS_VT = (LVDSData + ResIndex)->LCDVT;
-/*301b*/
-	if ((SiS_IF_DEF_LVDS == 0)
-	    && ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {	/*for test */
-		if (!(SiS_LCDInfo & LCDNonExpanding)) {
-			if (SiS_LCDResInfo == Panel1024x768) {
-				tempax = 1024;
-				tempbx = 768;
-			} else {
-				tempax = 1280;
-				tempbx = 1024;
-			}
-			SiS_HDE = tempax;
-			SiS_VDE = tempbx;
+
+	/* TW: Inserted from 630/301 BIOS */
+	if(SiS_VBType & VB_SIS301) {
+		if(SiS_LCDResInfo == Panel1280x1024) {
+			tempah |= 0x80;
 		}
 	} else {
-		if (SiS_IF_DEF_TRUMPION == 0) {
-			if (SiS_VBInfo & SetCRT2ToLCD) {
-				if (!(SiS_LCDInfo & LCDNonExpanding)) {
-					if (SiS_LCDResInfo == Panel800x600) {
-						tempax = 800;
-						tempbx = 600;
-					} else if (SiS_LCDResInfo ==
-						   Panel1024x768) {
-						tempax = 1024;
-						tempbx = 768;
-					} else {
-						tempax = 1280;
-						tempbx = 1024;
-					}
-					SiS_HDE = tempax;
-					SiS_VDE = tempbx;
-				}
-			}
-		}
+		tempah |= 0x80;
 	}
-	return;
-}
 
-void
-SiS_GetCRT2Data301 (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex)
-{
-	USHORT tempax, tempbx, modeflag;
-	USHORT resinfo;
-	USHORT CRT2Index, ResIndex;
-	SiS_LCDDataStruct *LCDPtr = NULL;
-	SiS_TVDataStruct *TVPtr = NULL;
+    	if(SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)){   /* TW: Added -HiVision like in BIOS (650+630) */
+      		if(SiS_VBInfo & SetInSlaveMode) {
+          		tempah |= 0x20;
+      		}
+    	}
+    	SiS_SetRegANDOR(SiS_Part4Port,0x0D,0x40,tempah);
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	tempah=0;
+    	if(SiS_VBInfo & SetCRT2ToTV) {
+      		if(SiS_VBInfo & SetInSlaveMode) {
+       			if(SiS_VBType & VB_SIS301BLV302BLV) {
+            			SiS_SetFlag |= RPLLDIV2XO;
+            			tempah |= 0x40;
+       			} else {
+        			if(!(SiS_SetFlag & TVSimuMode)) {
+          				if(!(SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+            					SiS_SetFlag |= RPLLDIV2XO;
+            					tempah |= 0x40;
+          				}
+        			}
+      			}
+     		} else {
+        		SiS_SetFlag |= RPLLDIV2XO;
+        		tempah |= 0x40;
+      		}
+    	}
+
+	if(SiS_LCDResInfo == Panel1280x1024 || SiS_LCDResInfo == Panel1280x960) {
+		tempah |= 0x80;
 	}
-	SiS_NewFlickerMode = 0;
-	SiS_RVBHRS = 50;
-	SiS_RY1COE = 0;
-	SiS_RY2COE = 0;
-	SiS_RY3COE = 0;
-	SiS_RY4COE = 0;
-
-	SiS_GetCRT2ResInfo (ROMAddr, ModeNo, ModeIdIndex);
-	if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-		SiS_GetRAMDAC2DATA (ROMAddr, ModeNo, ModeIdIndex,
-				    RefreshRateTableIndex);
-		return;
-	}
-
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		SiS_GetCRT2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &CRT2Index, &ResIndex);
-		switch (CRT2Index) {
-		case 2:
-			TVPtr = SiS_ExtHiTVData;
-			break;
-		case 3:
-			TVPtr = SiS_ExtPALData;
-			break;
-		case 4:
-			TVPtr = SiS_ExtNTSCData;
-			break;
-		case 7:
-			TVPtr = SiS_St1HiTVData;
-			break;
-		case 8:
-			TVPtr = SiS_StPALData;
-			break;
-		case 9:
-			TVPtr = SiS_StNTSCData;
-			break;
-		case 12:
-			TVPtr = SiS_St2HiTVData;
-			break;
-		}
 
-		SiS_RVBHCMAX = (TVPtr + ResIndex)->RVBHCMAX;
-		SiS_RVBHCFACT = (TVPtr + ResIndex)->RVBHCFACT;
-		SiS_VGAHT = (TVPtr + ResIndex)->VGAHT;
-		SiS_VGAVT = (TVPtr + ResIndex)->VGAVT;
-		SiS_HDE = (TVPtr + ResIndex)->TVHDE;
-		SiS_VDE = (TVPtr + ResIndex)->TVVDE;
-		SiS_RVBHRS = (TVPtr + ResIndex)->RVBHRS;
-		SiS_NewFlickerMode = (TVPtr + ResIndex)->FlickerMode;
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-			if (resinfo == 0x08)
-				SiS_NewFlickerMode = 0x40;
-			if (resinfo == 0x09)
-				SiS_NewFlickerMode = 0x40;
-			if (resinfo == 0x10)
-				SiS_NewFlickerMode = 0x40;
-		}
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-			if (SiS_VGAVDE == 350)
-				SiS_SetFlag = SiS_SetFlag | TVSimuMode;
-			tempax = ExtHiTVHT;
-			tempbx = ExtHiTVVT;
-			if (SiS_VBInfo & SetInSlaveMode) {
-				if (SiS_SetFlag & TVSimuMode) {
-					tempax = StHiTVHT;
-					tempbx = StHiTVVT;
-					if (!(modeflag & Charx8Dot)) {
-						tempax = StHiTextTVHT;
-						tempbx = StHiTextTVVT;
-					}
-				}
-			}
-		}
-		if (!(SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-			SiS_RY1COE = (TVPtr + ResIndex)->RY1COE;
-			SiS_RY2COE = (TVPtr + ResIndex)->RY2COE;
-			if (modeflag & HalfDCLK) {
-				SiS_RY1COE = 0x00;
-				SiS_RY2COE = 0xf4;
-			}
-			SiS_RY3COE = (TVPtr + ResIndex)->RY3COE;
-			SiS_RY4COE = (TVPtr + ResIndex)->RY4COE;
-			if (modeflag & HalfDCLK) {
-				SiS_RY3COE = 0x10;
-				SiS_RY4COE = 0x38;
-			}
-			if (!(SiS_VBInfo & SetPALTV)) {
-				tempax = NTSCHT;
-				tempbx = NTSCVT;
-			} else {
-				tempax = PALHT;
-				tempbx = PALVT;
-			}
-		}
-		SiS_HT = tempax;
-		SiS_VT = tempbx;
-		return;
-	}
-
-	if (SiS_VBInfo & SetCRT2ToLCD) {
-		SiS_GetCRT2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &CRT2Index, &ResIndex);
-		switch (CRT2Index) {
-		case 0:
-			LCDPtr = SiS_ExtLCD1024x768Data;
-			break;
-		case 1:
-			LCDPtr = SiS_ExtLCD1280x1024Data;
-			break;
-		case 5:
-			LCDPtr = SiS_StLCD1024x768Data;
-			break;
-		case 6:
-			LCDPtr = SiS_StLCD1280x1024Data;
-			break;
-		case 10:
-			LCDPtr = SiS_St2LCD1024x768Data;
-			break;
-		case 11:
-			LCDPtr = SiS_St2LCD1280x1024Data;
-			break;
-		case 13:
-			LCDPtr = SiS_NoScaleData;
-			break;
-		case 14:
-			LCDPtr = SiS_LCD1280x960Data;
-			break;
-		}
+    	SiS_SetReg1(SiS_Part4Port,0x0C,tempah);
+
+    } else {
+
+    	/* TW: 3. for LVDS */
+
+	/* TW: Inserted if-statement - Part1Port 0x2e not assigned on 300 series */
+	if(HwDeviceExtension->jChipType >= SIS_315H) {
+
+	   /* TW: Inserted this entire section (BIOS 650/LVDS); added ModeType check
+	    *     (LVDS can only be slave in 8bpp modes)
+	    */
+	   tempah = 0x80;
+	   if( (modeflag & CRT2Mode) && (SiS_ModeType > ModeVGA) ) {
+	       if (SiS_VBInfo & DriverMode) {
+	           tempah |= 0x02;
+	       }
+	   }
+
+	   if(!(SiS_VBInfo & SetInSlaveMode)) {
+               tempah |= 0x02;
+    	   }
+
+	   if(SiS_VBInfo & SetCRT2ToTV) {
+	       tempah = tempah ^ 0x01;
+	   }
+
+	   if(SiS_VBInfo & DisableCRT2Display) {
+	       tempah = 1;
+	   }
+
+    	   SiS_SetRegANDOR(SiS_Part1Port,0x2e,0xF0,tempah);
+
+	} else {
+
+	   /* TW: Inserted entire section from 630/LVDS BIOS (added ModeType check) */
+	   tempah = 0;
+	   if( (!(SiS_VBInfo & SetInSlaveMode)) && (SiS_ModeType > ModeVGA) ) {
+               	  tempah |= 0x02;
+    	   }
+	   tempah <<= 5;
+	   if(SiS_VBInfo & DisableCRT2Display)
+	       tempah = 0;
+
+	   SiS_SetReg1(SiS_Part1Port,0x01,tempah);
 
-		SiS_RVBHCMAX = (LCDPtr + ResIndex)->RVBHCMAX;
-		SiS_RVBHCFACT = (LCDPtr + ResIndex)->RVBHCFACT;
-		SiS_VGAHT = (LCDPtr + ResIndex)->VGAHT;
-		SiS_VGAVT = (LCDPtr + ResIndex)->VGAVT;
-		SiS_HT = (LCDPtr + ResIndex)->LCDHT;
-		SiS_VT = (LCDPtr + ResIndex)->LCDVT;
-		tempax = 1024;
-		if (SiS_SetFlag & LCDVESATiming) {
-			if (SiS_VGAVDE == 350)
-				tempbx = 560;
-			else if (SiS_VGAVDE == 400)
-				tempbx = 640;
-			else
-				tempbx = 768;
-		} else {
-			if (SiS_VGAVDE == 357)
-				tempbx = 527;
-			else if (SiS_VGAVDE == 420)
-				tempbx = 620;
-			else if (SiS_VGAVDE == 525)
-				tempbx = 775;
-			else if (SiS_VGAVDE == 600)
-				tempbx = 775;
-			else if (SiS_VGAVDE == 350)
-				tempbx = 560;
-			else if (SiS_VGAVDE == 400)
-				tempbx = 640;
-			else
-				tempbx = 768;
-		}
-		if (SiS_LCDResInfo == Panel1280x1024) {
-			tempax = 1280;
-			if (SiS_VGAVDE == 360)
-				tempbx = 768;
-			else if (SiS_VGAVDE == 375)
-				tempbx = 800;
-			else if (SiS_VGAVDE == 405)
-				tempbx = 864;
-			else
-				tempbx = 1024;
-		}
-		if (SiS_LCDResInfo == Panel1280x960) {
-			tempax = 1280;
-			if (SiS_VGAVDE == 350)
-				tempbx = 700;
-			else if (SiS_VGAVDE == 400)
-				tempbx = 800;
-			else if (SiS_VGAVDE == 1024)
-				tempbx = 960;
-			else
-				tempbx = 960;
-		}
-		if (SiS_LCDInfo & LCDNonExpanding) {
-			tempax = SiS_VGAHDE;
-			tempbx = SiS_VGAVDE;
-		}
-		SiS_HDE = tempax;
-		SiS_VDE = tempbx;
-		return;
 	}
+
+    }
+
+  }
+
+  /* TW: Inserted the entire following section */
+
+  if(SiS_IF_DEF_LVDS == 0) {
+
+      if(HwDeviceExtension->jChipType >= SIS_315H) {             /* TW: From 650/301 BIOS */
+
+#if 0    /* TW: This is not done in 650/301LV BIOS */
+         tempah = 0x04;
+         tempbl = 0xfb;
+         if(!(SiS_VBInfo & SetCRT2ToLCDA)) {
+            tempah = 0x00;
+	    if(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))
+	       tempbl = 0xff;
+         }
+         SiS_SetRegANDOR(SiS_Part1Port,0x13,tempbl,tempah);
+
+         SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xCF,0x30);
+#endif
+         /* This is done instead: */
+         tempah = 0x30;
+	 if(SiS_VBInfo & DisableCRT2Display) tempah = 0;
+	 SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xcf,tempah);
+
+#if 0    /* TW: This is not done in 650/301LV BIOS */
+	 SiS_SetRegANDOR(SiS_Part4Port,0x21,0x3f,0xc0);
+#endif
+	 /* This is done instead: */
+	 tempah = 0xc0;
+	 if(SiS_VBInfo & DisableCRT2Display) tempah = 0;
+	 SiS_SetRegANDOR(SiS_Part4Port,0x21,0x3f,tempah);
+
+#if 0    /* TW: This is not done in 650/301LV BIOS */
+	 tempah = 0x00;
+         tempbl = 0x7f;
+         if(!(SiS_VBInfo & SetCRT2ToLCDA)) {
+            tempbl = 0xff;
+	    if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr)))
+	       tempah = 0x80;
+         }
+         SiS_SetRegANDOR(SiS_Part4Port,0x23,tempbl,tempah);
+#endif
+	 /* This is done instead: */
+	 tempah = 0x80;
+	 if(SiS_VBInfo & DisableCRT2Display) tempah = 0;
+	 SiS_SetRegANDOR(SiS_Part4Port,0x23,0x7F,tempah);
+
+      } else if(SiS_VBType & VB_SIS301BLV302BLV) {		/* TW: From 630/301B BIOS */
+
+         SiS_SetRegAND(SiS_Part4Port,0x21,0x3f);
+
+         if(SiS_VBInfo & (SetCRT2ToLCD | DisableCRT2Display))
+	    SiS_SetRegAND(SiS_Part4Port,0x23,0x7F);
+	 else
+	    SiS_SetRegOR(SiS_Part4Port,0x23,0x80);
+
+      }
+
+  } else {  							/* TW: From 650/LVDS BIOS */
+
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
+         tempah = 0x04;
+	 tempbl = 0xfb;
+         if(!(SiS_VBInfo & SetCRT2ToLCDA)) {
+            tempah = 0x00;
+	    if(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))
+	       tempbl = 0xff;
+         }
+	 SiS_SetRegANDOR(SiS_Part1Port,0x13,tempbl,tempah);
+
+	 if(SiS_VBInfo & DisableCRT2Display)
+	    SiS_SetRegANDOR(SiS_Part1Port,0x13,0xfb,0x00);
+
+	 SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xcf,0x30);
+      }
+
+  }
+
+}
+
+void
+SiS_GetCRT2Data(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex,
+		PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  if(SiS_IF_DEF_LVDS == 0) {
+     if(SiS_VBType & VB_SIS301BLV302BLV) {
+        if(SiS_VBInfo & SetCRT2ToLCDA) {
+          SiS_GetCRT2DataLVDS(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+        } else {
+	  if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_VBInfo & SetCRT2ToLCD)){
+              SiS_GetCRT2Data301(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+	      /* TW: Need LVDS Data for LCD on 630/301B! */
+	      SiS_GetCRT2DataLVDS(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+	  } else {
+	      SiS_GetCRT2Data301(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+          }
+        }
+     } else
+     	SiS_GetCRT2Data301(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+  } else {
+     SiS_GetCRT2DataLVDS(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+  }
+}
+
+/* Checked with 650/LVDS 1.10.07 BIOS */
+void
+SiS_GetCRT2DataLVDS(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                    USHORT RefreshRateTableIndex,
+		    PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   USHORT CRT2Index, ResIndex;
+   SiS_LVDSDataStruct *LVDSData = NULL;
+
+   SiS_GetCRT2ResInfo(ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+   if((SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCDA)) {
+
+      SiS_GetCRT2PtrA(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                      &CRT2Index,&ResIndex);
+
+      switch (CRT2Index) {
+      	case  0:  LVDSData = SiS_LVDS1024x768Data_1;    break;
+      	case  1:  LVDSData = SiS_LVDS1280x1024Data_1;   break;
+        case  2:  LVDSData = SiS_LVDS1280x960Data_1;    break;
+      	case  3:  LVDSData = SiS_LVDS1024x768Data_2;    break;
+      	case  4:  LVDSData = SiS_LVDS1280x1024Data_2;   break;
+      	case  5:  LVDSData = SiS_LVDS1280x960Data_2;    break;
+      }
+
+   } else {
+
+      /* TW: SiS630/301B needs LVDS Data! */
+      if( (HwDeviceExtension->jChipType < SIS_315H) &&
+          (SiS_VBType & VB_SIS301BLV302BLV) &&
+	  (SiS_VBInfo & SetCRT2ToLCD) )
+              SiS_IF_DEF_LVDS = 1;
+
+      SiS_GetCRT2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                     &CRT2Index,&ResIndex,HwDeviceExtension);
+
+      /* TW: SiS630/301B needs LVDS Data! */
+      if( (HwDeviceExtension->jChipType < SIS_315H) &&
+          (SiS_VBType & VB_SIS301BLV302BLV) &&
+	  (SiS_VBInfo & SetCRT2ToLCD) )
+              SiS_IF_DEF_LVDS = 0;
+
+      switch (CRT2Index) {
+      	case  0:  LVDSData = SiS_LVDS800x600Data_1;    break;
+      	case  1:  LVDSData = SiS_LVDS1024x768Data_1;   break;
+      	case  2:  LVDSData = SiS_LVDS1280x1024Data_1;  break;
+      	case  3:  LVDSData = SiS_LVDS800x600Data_2;    break;
+      	case  4:  LVDSData = SiS_LVDS1024x768Data_2;   break;
+      	case  5:  LVDSData = SiS_LVDS1280x1024Data_2;  break;
+	case  6:  LVDSData = SiS_LVDS640x480Data_1;    break;
+        case  7:  LVDSData = SiS_LVDSXXXxXXXData_1;    break;  /* TW: New */
+	case  8:  LVDSData = SiS_LVDS1400x1050Data_1;  break;  /* TW: New */
+	case  9:  LVDSData = SiS_LVDS1400x1050Data_2;  break;  /* TW: New */
+      	case 10:  LVDSData = SiS_CHTVUNTSCData;        break;
+      	case 11:  LVDSData = SiS_CHTVONTSCData;        break;
+      	case 12:  LVDSData = SiS_CHTVUPALData;         break;
+      	case 13:  LVDSData = SiS_CHTVOPALData;         break;
+      	case 14:  LVDSData = SiS_LVDS320x480Data_1;    break;
+	case 15:  LVDSData = SiS_LVDS1024x600Data_1;   break;  /* TW: New */
+	case 16:  LVDSData = SiS_LVDS1152x768Data_1;   break;  /* TW: New */
+	case 17:  LVDSData = SiS_LVDS1024x600Data_2;   break;  /* TW: New */
+	case 18:  LVDSData = SiS_LVDS1152x768Data_2;   break;  /* TW: New */
+     }
+   }
+
+   SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
+   SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
+   SiS_HT = (LVDSData+ResIndex)->LCDHT;
+   SiS_VT = (LVDSData+ResIndex)->LCDVT;
+
+  if( (SiS_IF_DEF_LVDS == 0) && (SiS_VBType & VB_SIS301BLV302BLV)) {
+
+    if(!(SiS_LCDInfo & LCDNonExpanding)){
+         if(SiS_LCDResInfo == Panel1024x768){
+           SiS_HDE = 1024;
+           SiS_VDE = 768;
+         } else if(SiS_LCDResInfo == Panel1280x1024){
+           SiS_HDE = 1280;
+           SiS_VDE = 1024;
+         } else {
+	   SiS_HDE = 1280;
+	   SiS_VDE = 960;
+	 }
+    }
+
+  } else {
+
+    if(SiS_IF_DEF_TRUMPION == 0) {
+      if((SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_LCDInfo & 0x0100))) {
+        if(SiS_LCDResInfo != Panel640x480) {
+          if((!(SiS_LCDInfo & LCDNonExpanding)) || (SiS_SetFlag & CRT2IsVGA)) {
+            if(SiS_LCDResInfo == Panel800x600) {
+              SiS_HDE = 800;
+              SiS_VDE = 600;
+            } else if(SiS_LCDResInfo == Panel1024x768) {
+              SiS_HDE = 1024;
+              SiS_VDE = 768;
+            } else if(SiS_LCDResInfo == Panel1280x1024) {
+              SiS_HDE = 1280;
+              SiS_VDE = 1024;
+            } else if(SiS_LCDResInfo == Panel1024x600){
+	      SiS_HDE = 1024;
+              SiS_VDE = 600;
+	    } else if(SiS_LCDResInfo == Panel1400x1050){
+	      SiS_HDE = 1400;
+              SiS_VDE = 1050;
+	    } else {
+	      SiS_HDE = 1152;
+	      SiS_VDE = 768;
+	    }
+            if(SiS_IF_DEF_FSTN) {
+              SiS_HDE = 320;
+              SiS_VDE = 480;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+/* TW: Checked against 630/301B BIOS; does not check VDE values for LCD */
+void
+SiS_GetCRT2Data301(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                        USHORT RefreshRateTableIndex,
+			PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT tempax,tempbx,modeflag;
+  USHORT resinfo;
+  USHORT CRT2Index,ResIndex;
+  SiS_LCDDataStruct *LCDPtr=NULL;
+  SiS_TVDataStruct  *TVPtr=NULL;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+  SiS_NewFlickerMode = 0;
+  SiS_RVBHRS = 50;
+  SiS_RY1COE = 0;
+  SiS_RY2COE = 0;
+  SiS_RY3COE = 0;
+  SiS_RY4COE = 0;
+
+  SiS_GetCRT2ResInfo(ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+  /* TW: For VGA2 ("RAMDAC2") */
+
+  if(SiS_VBInfo & SetCRT2ToRAMDAC){
+     SiS_GetRAMDAC2DATA(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                        HwDeviceExtension);
+     return;
+  }
+
+  /* TW: For TV */
+
+  if(SiS_VBInfo & SetCRT2ToTV) {
+
+    SiS_GetCRT2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                   &CRT2Index,&ResIndex,HwDeviceExtension);
+
+    switch (CRT2Index) {
+      case  2:  TVPtr = SiS_ExtHiTVData;   break;
+      case  3:  TVPtr = SiS_ExtPALData;    break;
+      case  4:  TVPtr = SiS_ExtNTSCData;   break;
+      case  7:  TVPtr = SiS_St1HiTVData;   break;
+      case  8:  TVPtr = SiS_StPALData;     break;
+      case  9:  TVPtr = SiS_StNTSCData;    break;
+      case 12:  TVPtr = SiS_St2HiTVData;   break;
+      default:  TVPtr = SiS_StPALData;     break;  /* TW: Just to avoid a crash */
+    }
+
+    SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
+    SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
+    SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
+    SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
+    SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
+    SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
+    SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
+    SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
+
+    if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+
+      	if(resinfo == 0x08) SiS_NewFlickerMode = 0x40;
+      	if(resinfo == 0x09) SiS_NewFlickerMode = 0x40;
+	if(resinfo == 0x12) SiS_NewFlickerMode = 0x40;   /* TW: Was resinfo == 0x10 */
+
+        if(SiS_VGAVDE == 350) SiS_SetFlag |= TVSimuMode;
+
+        SiS_HT = ExtHiTVHT;
+        SiS_VT = ExtHiTVVT;
+        if(SiS_VBInfo & SetInSlaveMode) {
+          if(SiS_SetFlag & TVSimuMode) {
+            SiS_HT = StHiTVHT;
+            SiS_VT = StHiTVVT;
+            if(!(modeflag & Charx8Dot)){
+              SiS_HT = StHiTextTVHT;
+              SiS_VT = StHiTextTVVT;
+            }
+          }
+        }
+
+    } else {
+
+      SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
+      SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
+      SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
+      SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
+
+      if(modeflag & HalfDCLK) {
+         SiS_RY1COE = 0x00;
+         SiS_RY2COE = 0xf4;
+         SiS_RY3COE = 0x10;
+         SiS_RY4COE = 0x38;
+      }
+
+      if(!(SiS_VBInfo & SetPALTV)){
+        SiS_HT = NTSCHT;
+	if((ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_HT = NTSC2HT;
+        SiS_VT = NTSCVT;
+      } else {
+        SiS_HT = PALHT;
+        SiS_VT = PALVT;
+      }
+
+    }
+
+    return;
+  }
+
+  /* TW: For LCD */
+  /* TW: Checked against 650/301LV; CRT2Index different (but does not matter) */
+
+  if(SiS_VBInfo & SetCRT2ToLCD) {
+
+    SiS_GetCRT2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                   &CRT2Index,&ResIndex,HwDeviceExtension);
+
+    switch (CRT2Index) {
+      case  0: LCDPtr = SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
+      case  1: LCDPtr = SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
+      case  5: LCDPtr = SiS_StLCD1024x768Data;         break; /* Obviously unused */
+      case  6: LCDPtr = SiS_StLCD1280x1024Data;        break; /* Obviously unused */
+      case 10: LCDPtr = SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
+      case 11: LCDPtr = SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
+      case 13: LCDPtr = SiS_NoScaleData1024x768;       break; /* Non-expanding */
+      case 14: LCDPtr = SiS_NoScaleData1280x1024;      break; /* Non-expanding */
+      case 15: LCDPtr = SiS_LCD1280x960Data;           break; /* 1280x960 */
+      default: LCDPtr = SiS_ExtLCD1024x768Data;	       break; /* Just to avoid a crash */
+    }
+
+    SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
+    SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+    SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
+    SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
+    SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
+    SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
+
+    tempax = 1024;
+    if(SiS_SetFlag & LCDVESATiming) {
+      if     (SiS_VGAVDE == 350) tempbx = 560;
+      else if(SiS_VGAVDE == 400) tempbx = 640;
+      else                       tempbx = 768;
+    } else {
+      if     (SiS_VGAVDE == 357) tempbx = 527;
+      else if(SiS_VGAVDE == 420) tempbx = 620;
+      else if(SiS_VGAVDE == 525) tempbx = 775;
+      else if(SiS_VGAVDE == 600) tempbx = 775;
+      else if(SiS_VGAVDE == 350) tempbx = 560;
+      else if(SiS_VGAVDE == 400) tempbx = 640;
+      else                       tempbx = 768;
+    }
+    if(SiS_LCDResInfo == Panel1280x1024){
+      tempax = 1280;
+      if     (SiS_VGAVDE == 360) tempbx = 768;
+      else if(SiS_VGAVDE == 375) tempbx = 800;
+      else if(SiS_VGAVDE == 405) tempbx = 864;
+      else                       tempbx = 1024;
+    }
+    if(SiS_LCDResInfo == Panel1280x960){
+      tempax = 1280;
+      if     (SiS_VGAVDE == 350)  tempbx = 700;
+      else if(SiS_VGAVDE == 400)  tempbx = 800;
+      else if(SiS_VGAVDE == 1024) tempbx = 960;
+      else                        tempbx = 960;
+    }
+    if(SiS_LCDInfo & LCDNonExpanding) {
+       tempax = SiS_VGAHDE;
+       tempbx = SiS_VGAVDE;
+    }
+    SiS_HDE = tempax;
+    SiS_VDE = tempbx;
+    return;
+  }
 }
 
 USHORT
-SiS_GetResInfo (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_GetResInfo(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-	USHORT resindex;
+  USHORT resindex;
 
-	if (ModeNo <= 0x13) {
-		resindex = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;	/* si+St_ResInfo */
-	} else {
-		resindex = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;	/* si+Ext_ResInfo */
-	}
-	return (resindex);
+  if(ModeNo<=0x13)
+    	resindex=SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  else
+    	resindex=SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+
+  return(resindex);
+}
+
+/* TW: Checked against 650/301LV, 650/LVDS, 630/LVDS, 630/301 and 630/301B BIOS */
+void
+SiS_GetCRT2ResInfo(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT xres,yres,modeflag=0,resindex;
+
+  resindex = SiS_GetResInfo(ROMAddr,ModeNo,ModeIdIndex);
+
+  if(ModeNo <= 0x13) {
+    	xres = SiS_StResInfo[resindex].HTotal;
+    	yres = SiS_StResInfo[resindex].VTotal;
+  } else {
+	xres = SiS_ModeResInfo[resindex].HTotal;
+    	yres = SiS_ModeResInfo[resindex].VTotal;
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+
+  /* TW: Inserted entire if-section from 650/LVDS BIOS 1.10.07: */
+  if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 1)) {
+      if((ModeNo != 0x03) && (SiS_SetFlag & CRT2IsVGA)) {
+          if(yres == 350) yres = 400;
+      }
+      if(SiS_GetReg1(SiS_P3d4,0x3a) & 0x01) {
+ 	  if(SiS_GetReg1(SiS_P3d4,0x34) == 0x12)
+	      yres = 400;
+      }
+  }
+
+  if(ModeNo > 0x13) {
+      if(SiS_IF_DEF_FSTN == 1){
+            xres *= 2;
+            yres *= 2;
+      } else {
+  	    if(modeflag & HalfDCLK)       xres *= 2;
+  	    if(modeflag & DoubleScanMode) yres *= 2;
+      }
+  }
+
+  if(SiS_IF_DEF_LVDS == 0) {
+        /* TW: Inserted from 650/301LV BIOS */
+        if(SiS_VBInfo & SetCRT2ToLCDA) {
+                if(xres == 720) xres = 640;
+	} else {
+	   if(xres == 720) xres = 640;
+    	   if(SiS_LCDResInfo == Panel1280x1024) {
+      		if(yres == 400) yres = 405;
+      		if(yres == 350) yres = 360;
+      		if(SiS_SetFlag & LCDVESATiming) {
+        		if(yres == 360) yres = 375;
+      		}
+   	   }
+    	   if(SiS_LCDResInfo == Panel1024x768){
+      		if(!(SiS_SetFlag & LCDVESATiming)) {
+        		if(!(SiS_LCDInfo & LCDNonExpanding)) {
+          			if(yres == 350) yres = 357;
+          			if(yres == 400) yres = 420;
+            			if(yres == 480) yres = 525;
+        		}
+      		}
+    	   }
+	   /* TW: Inserted for 630/301B */
+	   if(HwDeviceExtension->jChipType < SIS_315H) {
+	      if(SiS_VBType & VB_SIS301BLV302BLV) {
+                  if(xres == 720) xres = 640;
+	      }
+	   }
+	}
+  } else {
+    	if(xres == 720) xres = 640;
+	/* TW: Inserted from 650/LVDS and 630/LVDS BIOS */
+	if(SiS_SetFlag & CRT2IsVGA) {
+	      yres = 400;
+	      if(HwDeviceExtension->jChipType >= SIS_315H) {
+	          if(SiS_GetReg1(SiS_P3c4,0x17) & 0x80) yres = 480;
+	      } else {
+	          if(SiS_GetReg1(SiS_P3c4,0x13) & 0x80) yres = 480;
+	      }
+	}
+  }
+  SiS_VGAHDE = SiS_HDE = xres;
+  SiS_VGAVDE = SiS_VDE = yres;
 }
 
+/* TW: Checked against 650/301 and 650/LVDS (1.10.07) BIOS; modified for new panel resolutions */
+/* TW: Done differently in 630/301B BIOS; but same effect; checked against 630/301 */
 void
-SiS_GetCRT2ResInfo (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_GetCRT2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+	       USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
+	       PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT xres, yres, modeflag, resindex;
+  USHORT tempbx=0,tempal=0;
+  USHORT Flag,resinfo=0;
 
-	resindex = SiS_GetResInfo (ROMAddr, ModeNo, ModeIdIndex);
-	if (ModeNo <= 0x13) {
-		xres = SiS_StResInfo[resindex].HTotal;
-		yres = SiS_StResInfo[resindex].VTotal;
-	} else {
-		xres = SiS_ModeResInfo[resindex].HTotal;	/* xres->ax */
-		yres = SiS_ModeResInfo[resindex].VTotal;	/* yres->bx */
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+St_ModeFlag */
-		if (modeflag & HalfDCLK) {
-			xres = xres * 2;
-		}
-		if (modeflag & DoubleScanMode) {
-			yres = yres * 2;
-		}
+  if(SiS_IF_DEF_LVDS == 0) {
+    	if(SiS_VBInfo & SetCRT2ToLCD){                            /* LCD */
+	        if(SiS_LCDResInfo == Panel1280x960)  tempbx = 14;
+		else if(SiS_LCDInfo & LCDNonExpanding) {
+			tempbx = 13;
+			if(SiS_LCDResInfo == Panel1280x1024) tempbx++;
+		} else {
+      		   tempbx = SiS_LCDResInfo - Panel1024x768;
+      		   if(!(SiS_SetFlag & LCDVESATiming)) {
+        		tempbx += 5;
+                        /* GetRevisionID();  */
+			/* TW: BIOS only adds 5 once */
+        		tempbx += 5;
+       		   }
+	        }
+     	} else {						/* TV */
+       		if(SiS_VBInfo & SetCRT2ToHiVisionTV){
+         		if(SiS_VGAVDE > 480) SiS_SetFlag &= (~TVSimuMode); /* TW: Was "(!TVSimuMode)" - WRONG */
+         		tempbx = 2;
+         		if(SiS_VBInfo & SetInSlaveMode) {
+            			if(!(SiS_SetFlag & TVSimuMode)) tempbx = 12;  /* TW: Was 10! - WRONG */
+         		}
+       		} else {
+         		if(SiS_VBInfo & SetPALTV) tempbx = 3;
+         		else tempbx = 4;
+         		if(SiS_SetFlag & TVSimuMode) tempbx += 5;
+       		}
+     	}
+
+     	if(ModeNo <= 0x13)
+       		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     	else
+       		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+     	tempal &= 0x3F;
+
+      	if((SiS_VBType & VB_SIS301BLV302BLV)
+                     && (SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))) {  /* TW: Added -Hivision (BIOS) */
+      		if(tempal == 0x06) tempal = 0x07;
+        }
+
+        if(SiS_VBInfo & SetCRT2ToTV) {
+            if((ModeNo == 0x31) || (ModeNo == 0x32)) tempal = 6;
+	}
+
+     	*CRT2Index = tempbx;
+     	*ResIndex = tempal;
+
+  } else {   /* LVDS */
+
+    	Flag = 1;
+    	tempbx = 0;
+    	if(SiS_IF_DEF_CH70xx != 0) {
+      		if(!(SiS_VBInfo & SetCRT2ToLCD)) {
+        		Flag = 0;
+        		tempbx = 10;
+        		if(SiS_VBInfo & SetPALTV)        tempbx += 2;
+        		if(SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+      		}
+    	}
+
+    	if(Flag == 1) {
+      		tempbx = SiS_LCDResInfo - PanelMinLVDS;
+		if(SiS_LCDResInfo <= Panel1280x1024) {
+   	      	    if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 3;
+		} else {
+		    if(SiS_LCDResInfo == Panel1400x1050) {
+			tempbx = 8;
+			if(SiS_LCDInfo & LCDNonExpanding)  tempbx++;
+		    }
+        	    if(SiS_LCDInfo & 0x0100) {
+			tempbx = 7;
+        	    }
+
+     		    if(SiS_LCDResInfo == Panel640x480)  tempbx = 6;
+
+		    /* TW: Inserted from 630/LVDS 2.04.5c BIOS */
+		    if(SiS_LCDResInfo == Panel1024x600) {
+			tempbx = 15;
+  		        if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 2;
+		    }
+		    if(SiS_LCDResInfo == Panel1152x768) {
+		        tempbx = 16;
+			if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 2;
+		    }
+		 }
+	}
+
+    	if(ModeNo <= 0x13)
+      		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+    	else {
+      		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
 	}
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_LCDResInfo == Panel1280x1024) {
-			if (yres == 400)
-				yres = 405;
-			if (yres == 350)
-				yres = 360;
-			if (SiS_SetFlag & LCDVESATiming) {
-				if (yres == 360)
-					yres = 375;
-			}
-		}
-		if (SiS_LCDResInfo == Panel1024x768) {
-			if (!(SiS_SetFlag & LCDVESATiming)) {
-				if (!(SiS_LCDInfo & LCDNonExpanding)) {
-					if (yres == 350)
-						yres = 357;
-					if (yres == 400)
-						yres = 420;
-/*          if(!OldBios)             */
-					if (yres == 480)
-						yres = 525;
-				}
-			}
+
+	if(SiS_IF_DEF_FSTN){
+       	 	if(SiS_LCDResInfo == Panel320x480){
+         		tempbx = 14;
+         		tempal = 6;
+        	}
+    	}
+
+	/* TW: Inserted from 650/LVDS BIOS */
+	if(SiS_SetFlag & CRT2IsVGA) {
+	        if(SiS_LCDResInfo != Panel640x480) tempal = 7;
+		if(HwDeviceExtension->jChipType < SIS_315H) {
+		    /* TW: Inserted from 630/LVDS (2.04.5c) and 630/301B (II) BIOS */
+		    if(SiS_GetReg1(SiS_P3c4,0x13) & 0x80) tempal++;
 		}
-	} else {
-		if (xres == 720)
-			xres = 640;
+
+	}
+
+	/* TW: Inserted from 630/301B BIOS */
+	if(SiS_VBType & VB_SIS301BLV302BLV) {
+	    if(ModeNo > 0x13) {
+	        if((resinfo == 0x0c) || (resinfo == 0x0d))
+		    tempal = 6;
+	    }
 	}
-	SiS_VGAHDE = xres;
-	SiS_HDE = xres;
-	SiS_VGAVDE = yres;
-	SiS_VDE = yres;
+
+    	*CRT2Index = tempbx;
+    	*ResIndex = tempal & 0x1F;
+  }
 }
 
 void
-SiS_GetCRT2Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		USHORT RefreshRateTableIndex, USHORT * CRT2Index,
-		USHORT * ResIndex)
-{
-	USHORT tempbx, tempal;
-	USHORT Flag;
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_VBInfo & SetCRT2ToLCD) {	/* LCD */
-			tempbx = SiS_LCDResInfo;
-			tempbx = tempbx - Panel1024x768;
-			if (!(SiS_SetFlag & LCDVESATiming)) {
-				tempbx += 5;
-/*      GetRevisionID();  */
-				tempbx += 5;
-			}
-		} else {
-			if (SiS_VBInfo & SetCRT2ToHiVisionTV) {	/* TV */
-				if (SiS_VGAVDE > 480)
-					SiS_SetFlag =
-					    SiS_SetFlag & (!TVSimuMode);
-				tempbx = 2;
-				if (SiS_VBInfo & SetInSlaveMode) {
-					if (!(SiS_SetFlag & TVSimuMode))
-						tempbx = 10;
-				}
-			} else {
-				if (SiS_VBInfo & SetPALTV) {
-					tempbx = 3;
-				} else {
-					tempbx = 4;
-				}
-				if (SiS_SetFlag & TVSimuMode) {
-					tempbx = tempbx + 5;
-				}
-			}
-		}
-		if (ModeNo <= 0x13) {
-			tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-		} else {
-			tempal =
-			    SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-		}
-		tempal = tempal & 0x3F;
-		/*301b */
-		if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-		    && (SiS_VBInfo & SetCRT2ToTV)) {
-			/*look */
-			if (tempal == 0x06)
-				tempal = 0x07;
+SiS_GetCRT2PtrA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+		USHORT *ResIndex)
+{
+  USHORT tempbx,tempal;
 
-		}
-		/*end 301b */
-		if ((0x31 <= ModeNo) && (ModeNo <= 0x35))
-			tempal = 6;
-		if (SiS_LCDInfo & LCDNonExpanding)
-			tempbx = 0x0D;
-		if (SiS_LCDResInfo == Panel1280x960)
-			tempbx = 0x0E;
-		*CRT2Index = tempbx;
-		*ResIndex = tempal;
-	} else {		/* LVDS */
-		Flag = 1;
-		tempbx = 0;
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (!(SiS_VBInfo & SetCRT2ToLCD)) {
-				Flag = 0;
-				tempbx = 7;
-				if (SiS_VBInfo & SetPALTV)
-					tempbx = tempbx + 2;
-				if (SiS_VBInfo & SetCHTVOverScan)
-					tempbx = tempbx + 1;
-			}
-		}
-		if (Flag == 1) {
-			tempbx = SiS_LCDResInfo - Panel800x600;
-			if (SiS_LCDInfo & LCDNonExpanding) {
-				tempbx = tempbx + 3;
-			}
-		}
-		if (ModeNo <= 0x13) {
-			tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-		} else {
-			tempal =
-			    SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-		}
-		tempal = tempal & 0x1F;
-		*CRT2Index = tempbx;
-		*ResIndex = tempal;
-	}
+  tempbx = SiS_LCDResInfo - Panel1024x768;
+
+  if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 3;
+
+  if(ModeNo <= 0x13)
+      	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  else
+      	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+  *CRT2Index = tempbx;
+  *ResIndex = tempal & 0x1F;
 }
 
+/* TW: New from 650/301LV BIOS */
 void
-SiS_GetCRT2PtrA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex, USHORT * CRT2Index,
-		 USHORT * ResIndex)
+SiS_GetCRT2Part2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		    USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+		    USHORT *ResIndex)
 {
-	USHORT tempbx, tempal;
+  USHORT tempbx,tempal;
 
-	tempbx = SiS_LCDResInfo - Panel1024x768;
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		tempbx = tempbx + 3;
-	}
-	if (ModeNo <= 0x13) {
-		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-	tempal = tempal & 0x1F;
-	*CRT2Index = tempbx;
-	*ResIndex = tempal;
-}
+  if(ModeNo <= 0x13)
+      	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  else
+      	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+  tempbx = SiS_LCDResInfo - Panel1024x768;
 
-/*end 301b*/
+  if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 2;
+  else if(SiS_SetFlag & LCDVESATiming) tempbx += 4;
+
+  *CRT2Index = tempbx;
+  *ResIndex = tempal & 0x3F;
+}
 
+/* TW: Checked against 650/LVDS (1.10.07) and 630/301B BIOS */
 USHORT
-SiS_GetRatePtrCRT2 (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_GetRatePtrCRT2(UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
 {
-	SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 };
-	SHORT LCDARefreshIndex[] = { 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01 };
-	USHORT RefreshRateTableIndex, i;
-	USHORT modeflag, index, temp;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  SHORT  LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01,
+                               0x01, 0x01, 0x01, 0x01 };
+  USHORT RefreshRateTableIndex,i,backup_i;
+  USHORT modeflag,index,temp;
+
+  if (ModeNo <= 0x13)
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  else
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+  if(SiS_IF_DEF_CH70xx != 0) {
+    	if(SiS_VBInfo & SetCRT2ToTV) {
+      		if(modeflag & HalfDCLK) return(0);
+    	}
+  }
+
+  if(ModeNo < 0x14) return(0xFFFF);
+
+ /* TW: 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
+  */
+
+  index = SiS_GetReg1(SiS_P3d4,0x33);
+  index >>= SiS_SelectCRT2Rate;
+  index &= 0x0F;
+
+  if(index > 0) index--;
+
+  /* TW: Added SetFlag and VBInfo checks; we don't care about index if we
+   *     are setting CRT1 rate!
+   */
+  if( (SiS_SetFlag & ProgrammingCRT2) &&
+      (SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) )
+  	 index = 0;
+
+  if(SiS_SetFlag & ProgrammingCRT2) {
+    	if(SiS_IF_DEF_CH70xx != 0) {
+      		if(SiS_VBInfo & SetCRT2ToTV) {
+        		index = 0;
+      		}
+    	}
+    	if(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+      		if(SiS_IF_DEF_LVDS == 0) {
+		        /* TW: This is not done in 630/301B BIOS */
+           		temp = LCDRefreshIndex[SiS_LCDResInfo];
+        		if(index > temp) index = temp;
+      		} else {
+        		index=0;
+      		}
+    	}
+  }
+
+  RefreshRateTableIndex = SiS_EModeIDTable[ModeIdIndex].REFindex;
+  ModeNo = SiS_RefIndex[RefreshRateTableIndex].ModeID;
+
+  /* TW: Inserted from 650/LVDS 1.10.07 */
+  if(SiS_IF_DEF_LVDS == 1) {
+    if(!(SiS_VBInfo & DriverMode)) {
+      if( (SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
+          (SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
+            if(SiS_LCDResInfo <= Panel800x600)
+	       RefreshRateTableIndex++;
+      }
+    }
+  }
+
+  i = 0;
+  do {
+    	if (SiS_RefIndex[RefreshRateTableIndex+i].ModeID != ModeNo) break;
+    	temp = SiS_RefIndex[RefreshRateTableIndex+i].Ext_InfoFlag;
+    	temp &= ModeInfoFlag;
+    	if(temp < SiS_ModeType) break;
+    	i++;
+    	index--;
+  } while(index != 0xFFFF);
+
+  if(!(SiS_VBInfo & SetCRT2ToRAMDAC)) {
+    	if(SiS_VBInfo & SetInSlaveMode) {
+      		temp = SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
+      			if(temp & InterlaceMode) {
+        			i++;
+      			}
+    	}
+  }
+  i--;
+
+  if((SiS_SetFlag & ProgrammingCRT2) && (!(SiS_VBInfo & DisableCRT2Display))) {
+    	backup_i = i;
+    	if (!(SiS_AdjustCRT2Rate(ROMAddr,ModeNo,ModeIdIndex,
+	                             RefreshRateTableIndex,&i))) {
+		/* TW: This is for avoiding random data to be used; i is
+		 *     in an undefined state if no matching CRT2 mode is
+		 *     found.
+		 */
+		i = backup_i;
 	}
+  }
 
-	if (SiS_IF_DEF_CH7005 == 1) {
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			if (modeflag & HalfDCLK)
-				return (0);
-		}
-	}
-	if (ModeNo < 0x14)
-		return (0xFFFF);
-	index = SiS_GetReg1 (SiS_P3d4, 0x33);
-	index = index >> SiS_SelectCRT2Rate;
-	index = index & 0x0F;
-	if (SiS_LCDInfo & LCDNonExpanding)
-		index = 0;
-	if (index > 0)
-		index--;
-
-	if (SiS_SetFlag & ProgrammingCRT2) {
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				index = 0;
-			}
-		}
-		if (SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-			if (SiS_IF_DEF_LVDS == 0) {
-				if ((SiS_VBType & VB_SIS301B)
-				    || (SiS_VBType & VB_SIS302B)) temp =
-					    LCDARefreshIndex[SiS_LCDResInfo];	/*301b */
-				else
-					temp = LCDRefreshIndex[SiS_LCDResInfo];
-				if (index > temp) {
-					index = temp;
-				}
-			} else {
-				index = 0;
-			}
-		}
-	}
+  return(RefreshRateTableIndex + i);
+}
 
-	RefreshRateTableIndex = SiS_EModeIDTable[ModeIdIndex].REFindex;
-	ModeNo = SiS_RefIndex[RefreshRateTableIndex].ModeID;
-	i = 0;
-	do {
-		if (SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo)
-			break;
-		temp = SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
-		temp = temp & ModeInfoFlag;
-		if (temp < SiS_ModeType)
-			break;
-
-		i++;
-		index--;
-	} while (index != 0xFFFF);
-
-	if (!(SiS_VBInfo & SetCRT2ToRAMDAC)) {
-		if (SiS_VBInfo & SetInSlaveMode) {
-			temp =
-			    SiS_RefIndex[RefreshRateTableIndex + i -
-					 1].Ext_InfoFlag;
-			if (temp & InterlaceMode) {
-				i++;
-			}
-		}
-	}
+/* Checked against 650/LVDS (1.10.07) BIOS */
+BOOLEAN
+SiS_AdjustCRT2Rate(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,USHORT *i)
+{
+  USHORT tempax,tempbx,resinfo;
+  USHORT modeflag,infoflag;
 
-	i--;
-	if ((SiS_SetFlag & ProgrammingCRT2)) {
-		temp =
-		    SiS_AjustCRT2Rate (ROMAddr, ModeNo, ModeIdIndex,
-				       RefreshRateTableIndex, &i);
+  if (ModeNo <= 0x13)
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  else
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+  resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  tempbx = SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+
+  tempax = 0;
+  if(SiS_IF_DEF_LVDS == 0) {
+  	/* TW: For 301, 301B, 302B, 301LV, 302LV */
+    	if(SiS_VBInfo & SetCRT2ToRAMDAC) {
+      		tempax |= SupportRAMDAC2;
+    	}
+    	if(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+      		tempax |= SupportLCD;
+      		if(SiS_LCDResInfo != Panel1280x1024) {
+        		if(SiS_LCDResInfo != Panel1280x960) {
+           			if(SiS_LCDInfo & LCDNonExpanding) {
+             				if(resinfo >= 9) {
+               					tempax = 0;
+               					return(0);
+             				}
+           			}
+        		}
+      		}
+    	}
+    	if(SiS_VBInfo & SetCRT2ToHiVisionTV) {    /* for HiTV */
+      		tempax |= SupportHiVisionTV;
+      		if(SiS_VBInfo & SetInSlaveMode){
+        		if(resinfo == 4) return(0);
+        		if(resinfo == 3) {
+          			if(SiS_SetFlag & TVSimuMode) return(0);
+        		}
+        		if(resinfo > 7) return(0);
+      		}
+    	} else {
+      		if(SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
+        		tempax |= SupportTV;
+         		if(SiS_VBType & VB_SIS301BLV302BLV) {
+             			tempax |= SupportTV1024;
+         		}
+        		if(!(SiS_VBInfo & SetPALTV)) {
+          			if(modeflag & NoSupportSimuTV) {
+            				if(SiS_VBInfo & SetInSlaveMode) {
+              					if(!(SiS_VBInfo & SetNotSimuMode)) {
+                					return 0;
+              					}
+            				}
+          			}
+        		}
+      		}
+    	}
+  } else {
+  	/* TW: for LVDS  */
+    	if(SiS_IF_DEF_CH70xx != 0) {
+      		if(SiS_VBInfo & SetCRT2ToTV) {
+        		tempax |= SupportCHTV;
+      		}
+    	}
+    	if(SiS_VBInfo & SetCRT2ToLCD) {
+      		tempax |= SupportLCD;
+		if(SiS_LCDResInfo == Panel1280x768) {
+		     /* TW: Bios code makes no sense */
+		} else if(SiS_LCDResInfo == Panel1400x1050) {
+		     if((resinfo != 0x15) && (resinfo > 0x09)) return(0);
+		} else if(SiS_LCDResInfo == Panel1280x1024) {
+                     if(resinfo > 0x09) return(0);
+                } else if(SiS_LCDResInfo == Panel1024x768) {
+		     if(resinfo > 0x08) return(0);
+		} else if(SiS_LCDResInfo == Panel800x600){
+		     if(resinfo > 0x07) return(0);
+		     if(resinfo == 0x04) return(0);
+		}
+    	}
+  }
+  /* TW: Look backwards in table for matching CRT2 mode */
+  for(; SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
+     	infoflag = SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+     	if(infoflag & tempax) {
+       		return(1);
+     	}
+     	if ((*i) == 0) break;
+  }
+  /* TW: 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)++) {
+     	infoflag = SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+     	if(SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
+       		return(0);
+     	}
+     	if(infoflag & tempax) {
+       		return(1);
+     	}
+  }
+  return(1);
+}
+
+/* Checked against 650/LVDS (1.10.07) and 650/301LV BIOS */
+void
+SiS_SaveCRT2Info(USHORT ModeNo)
+{
+  USHORT temp1,temp2;
+
+  /* TW: We store CRT1 ModeNo in CR34 */
+  SiS_SetReg1(SiS_P3d4,0x34,ModeNo);
+  temp1 = (SiS_VBInfo & SetInSlaveMode) >> 8;
+  temp2 = ~(SetInSlaveMode >> 8);
+  SiS_SetRegANDOR(SiS_P3d4,0x31,temp2,temp1);
+}
+
+/* TW: Checked against 650+301, 650/LVDS (1.10.07) and 650/301LV BIOS */
+void
+SiS_GetVBInfo301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                 USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT tempax,tempbx,temp;
+  USHORT modeflag, resinfo=0;
+  UCHAR  OutputSelect = *pSiS_OutputSelect;
+
+  if (ModeNo<=0x13)
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  else {
+   	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+
+  SiS_SetFlag = 0;
+
+  SiS_ModeType = modeflag & ModeInfoFlag;
+
+  tempbx = 0;
+  if(SiS_BridgeIsOn(BaseAddr,HwDeviceExtension) == 0) {              /* TW: "== 0" inserted from 630/301B BIOS */
+    	temp = SiS_GetReg1(SiS_P3d4,0x30);
+    	if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {               /* TW: Not in (301B) BIOS */
+       		temp &= 0xbf;   /* 301lvds disable CRT2RAMDAC */
+    	}
+    	if(SiS_IF_DEF_FSTN) {   /* fstn must set CR30=0x21 */
+       		temp = 0x21;
+       		SiS_SetReg1(SiS_P3d4,0x30,temp);
+    	}
+    	tempbx |= temp;
+    	temp = SiS_GetReg1(SiS_P3d4,0x31);
+	tempax = temp << 8;
+        tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch |        /* TW: Inserted from 650/LVDS+301LV BIOS */
+		         SetNotSimuMode | SetPALTV);                    /* TW: Inserted from 650/LVDS+301LV BIOS */
+    	tempbx |= tempax;
+    	temp = SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display;
+   	temp = 0xFFFF ^ temp;
+    	tempbx &= temp;
+#ifdef SIS315H
+	if(HwDeviceExtension->jChipType >= SIS_315H) {       /* TW: Inserted this "if" */
+	   temp = SiS_GetReg1(SiS_P3d4,0x38);
+    	   if(SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
+       		if((temp & (EnableDualEdge | SetToLCDA))
+		          == (EnableDualEdge | SetToLCDA))   /* TW: BIOS only tests these bits, added "& ..." */
+          		tempbx |= SetCRT2ToLCDA;
+    	   }
+	   /* TW: Inserted from 650/LVDS BIOS: */
+	   if(SiS_IF_DEF_LVDS == 1) {
+	        if(temp & SetToLCDA)
+		        tempbx |= SetCRT2ToLCDA;
+	        if(temp & 0x08)
+		        tempbx |= SetCRT2ToHiVisionTV;
+	   }
 	}
-	return (RefreshRateTableIndex + i);	/*return(0x01|(temp1<<1));   */
+#endif
+    	if(SiS_IF_DEF_LVDS == 0) {
+	        temp = SetCRT2ToLCDA   | SetCRT2ToSCART      | SetCRT2ToLCD |
+		       SetCRT2ToRAMDAC | SetCRT2ToSVIDEO     | SetCRT2ToAVIDEO; /* = 0x807C; */
+      		if(SiS_IF_DEF_HiVision == 1)
+                     temp |= SetCRT2ToHiVisionTV; /* = 0x80FC; */
+    	} else {
+	        /* TW: Inserted entire 315-section */
+                if(HwDeviceExtension->jChipType >= SIS_315H) {
+                    if(SiS_IF_DEF_CH70xx != 0)
+        		temp = SetCRT2ToLCDA   | SetCRT2ToSCART |
+			       SetCRT2ToLCD    | SetCRT2ToHiVisionTV |
+			       SetCRT2ToAVIDEO | SetCRT2ToSVIDEO;  /* 0x80bc */
+      		    else
+        		temp = SetCRT2ToLCDA | SetCRT2ToLCD;
+		} else {
+      		    if(SiS_IF_DEF_CH70xx != 0)
+        		temp = SetCRT2ToTV | SetCRT2ToLCD;
+      		    else
+        		temp = SetCRT2ToLCD;
+		}
+    	}
+
+    	if(!(tempbx & temp)) {
+      		tempax = DisableCRT2Display;
+      		tempbx = 0;
+    	}
+
+   	if(SiS_IF_DEF_LVDS==0) {
+      		if(tempbx & SetCRT2ToLCDA) {
+        		tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode);
+      		} else if(tempbx & SetCRT2ToRAMDAC) {
+        		tempbx &= (0xFF00|SetCRT2ToRAMDAC|SwitchToCRT2|SetSimuScanMode);
+      		} else if((tempbx & SetCRT2ToLCD) && (!(SiS_VBType & VB_NoLCD)) ){
+        		tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
+      		} else if(tempbx & SetCRT2ToSCART){
+        		tempbx &= (0xFF00|SetCRT2ToSCART|SwitchToCRT2|SetSimuScanMode);
+        		tempbx |= SetPALTV;
+      		} else if(tempbx & SetCRT2ToHiVisionTV){
+        		tempbx &= (0xFF00|SetCRT2ToHiVisionTV|SwitchToCRT2|SetSimuScanMode);
+        		tempbx |= SetPALTV;
+      		}
+   	} else { /* LVDS */
+	        /* TW: Inserted entire 315/325 section */
+	        if(HwDeviceExtension->jChipType >= SIS_315H) {
+		    if(tempbx & SetCRT2ToLCDA)
+		        tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode);
+		}
+      		if(SiS_IF_DEF_CH70xx != 0) {
+        	    if(tempbx & SetCRT2ToTV)
+          		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchToCRT2|SetSimuScanMode);
+      		}
+      		if(tempbx & SetCRT2ToLCD) {
+        		tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
+		}
+	        if(HwDeviceExtension->jChipType >= SIS_315H) {
+		    if(tempbx & SetCRT2ToLCDA)
+		        tempbx |= SetCRT2ToLCD;
+		}
+	}
+    	if(tempax & DisableCRT2Display) {
+      		if(!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) {
+        		tempbx = SetSimuScanMode | DisableCRT2Display;
+      		}
+    	}
+    	if(!(tempbx & DriverMode)){
+      		tempbx |= SetSimuScanMode;
+    	}
+
+	/* TW: LVDS (LCD/TV) and 630+301B (LCD) can only be slave in 8bpp modes */
+	if( (SiS_IF_DEF_LVDS == 1) && (SiS_ModeType <= ModeVGA) ) {
+		modeflag &= (~CRT2Mode);
+	}
+	if( (HwDeviceExtension->jChipType < SIS_315H) && (SiS_VBType & VB_SIS301BLV302BLV)) {
+	        if(SiS_ModeType <= ModeVGA) {
+			if(tempbx & SetCRT2ToLCD) {
+		    		modeflag &= (~CRT2Mode);
+			}
+	        }
+	}
+	/* TW end */
+
+    	if(!(tempbx & SetSimuScanMode)){
+      		if(tempbx & SwitchToCRT2) {
+        		if(!(modeflag & CRT2Mode)) {
+			     if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+			         (SiS_VBType & VB_SIS301BLV302BLV) ) {
+			        if(resinfo != 0x0a)
+                                   tempbx |= SetSimuScanMode;
+			     } else {
+            			tempbx |= SetSimuScanMode;
+	                     }
+
+        		}
+      		} else {
+        		if(!(SiS_BridgeIsEnable(BaseAddr,HwDeviceExtension))) {
+          			if(!(tempbx & DriverMode)) {
+            				if(SiS_BridgeInSlave()) {
+						tempbx |= SetSimuScanMode; /* TW: from BIOS 650/301/301LV/LVDS */
+            				}
+          			}
+        		}
+      		}
+    	}
+
+    	if(!(tempbx & DisableCRT2Display)) {
+     		 if(tempbx & DriverMode) {
+        		if(tempbx & SetSimuScanMode) {
+          			if(!(modeflag & CRT2Mode)) {
+				        if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+					    (SiS_VBType & VB_SIS301BLV302BLV) ) {
+					        if(resinfo != 0x0a) {  /* TW: Inserted from 650/301 BIOS */
+						    tempbx |= SetInSlaveMode;
+            					    if(SiS_IF_DEF_LVDS == 0) {
+              						if(tempbx & SetCRT2ToTV) {
+                						if(!(tempbx & SetNotSimuMode))
+									SiS_SetFlag |= TVSimuMode;
+              						}
+            					    }
+					        }                      /* TW: Inserted from 650/301 BIOS */
+					} else {
+            					tempbx |= SetInSlaveMode;
+            					if(SiS_IF_DEF_LVDS == 0) {
+              						if(tempbx & SetCRT2ToTV) {
+                						if(!(tempbx & SetNotSimuMode))
+									SiS_SetFlag |= TVSimuMode;
+              						}
+            					}
+         				}
+				}
+        		}
+      		} else {
+        		tempbx |= SetInSlaveMode;
+        		if(SiS_IF_DEF_LVDS == 0) {
+          			if(tempbx & SetCRT2ToTV) {
+            				if(!(tempbx & SetNotSimuMode))
+						SiS_SetFlag |= TVSimuMode;
+          			}
+        		}
+      		}
+    	}
+    	if(SiS_IF_DEF_CH70xx == 1) {
+      		temp = SiS_GetReg1(SiS_P3d4,0x35);
+      		if(temp & TVOverScan) tempbx |= SetCHTVOverScan;
+    	}
+	if(SiS_IF_DEF_CH70xx == 2) {
+      		temp = SiS_GetReg1(SiS_P3d4,0x79);
+      		if(temp & 0x80) tempbx |= SetCHTVOverScan;
+    	}
+  }
+
+  if(SiS_IF_DEF_LVDS==0) {
+#ifdef SIS300
+     	if((HwDeviceExtension->jChipType==SIS_630)||
+           (HwDeviceExtension->jChipType==SIS_730)) {
+           	if(!(OutputSelect & EnablePALMN))
+             		SiS_SetRegAND(SiS_P3d4,0x35,0x3F);
+           	if(tempbx & SetCRT2ToTV) {
+              		if(tempbx & SetPALTV) {
+                  		temp=SiS_GetReg1(SiS_P3d4,0x35);
+                  		temp &= 0xC0;
+                  		if(temp == 0x40)
+                    			tempbx &= (~SetPALTV);
+             		}
+          	}
+      	}
+#endif
+#ifdef SIS315H
+     	if(HwDeviceExtension->jChipType >= SIS_315H) {
+		if(!(OutputSelect & EnablePALMN))
+        		SiS_SetRegAND(SiS_P3d4,0x38,0x3F);
+   		if(tempbx & SetCRT2ToTV) {
+    			if(tempbx & SetPALTV) {
+               			temp = SiS_GetReg1(SiS_P3d4,0x38);
+               			/* temp &= 0xC0;  */ /* TW: BIOS only tests 0x40, not 0x80 */
+               			if(temp & 0x40)
+               				tempbx &= (~SetPALTV);
+              		}
+        	}
+  	}
+#endif
+  }
+
+  SiS_VBInfo=tempbx;
+
+  /* TW: DevSwitch not supported here */
+
+#ifdef TWDEBUG
+#ifdef LINUX_KERNEL
+  printk(KERN_INFO "sisfb: (VBInfo = %x, SetFlag = %x)\n", SiS_VBInfo, SiS_SetFlag);
+#endif
+#ifdef LINUX_XF86
+  xf86DrvMsg(0, X_INFO, "(init301: VBInfo = %x, SetFlag = %x)\n", SiS_VBInfo, SiS_SetFlag);
+#endif
+#endif
+
+#if 0
+  /* From 650/301LV BIOS: */
+  if(ModeNo == 0x13) bp+4 = 0x03
+  else bp+4 = ModeNo;
+#endif
+
+  /* TW: 630/301B and 650/301 (not 301LV!) BIOS do more here, but this seems for DOS mode */
+
 }
 
-BOOLEAN
-SiS_AjustCRT2Rate (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex, USHORT * i)
+void
+SiS_GetRAMDAC2DATA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,
+		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT tempax, tempbx, resinfo;
-	USHORT modeflag, infoflag;
+  USHORT tempax,tempbx,temp;
+  USHORT temp1,temp2,modeflag=0,tempcx;
+  USHORT StandTableIndex,CRT1Index;
+  USHORT ResInfo,DisplayType;
+  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+
+  SiS_RVBHCMAX=1;
+  SiS_RVBHCFACT=1;
+
+  if(ModeNo <= 0x13){
+
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	StandTableIndex = SiS_GetModePtr(ROMAddr,ModeNo,ModeIdIndex);
+    	tempax = SiS_StandTable[StandTableIndex].CRTC[0];
+    	tempbx = SiS_StandTable[StandTableIndex].CRTC[6];
+    	temp1 = SiS_StandTable[StandTableIndex].CRTC[7];
+
+  } else {
+
+     if( (SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo&SetCRT2ToLCDA) ) {
+
+    	temp=SiS_GetLVDSCRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,
+			RefreshRateTableIndex,&ResInfo,&DisplayType);
+
+    	if(temp==0)  return;
+
+    	switch(DisplayType) {
+    		case 0 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;		break;
+    		case 1 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;          break;
+    		case 2 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;         break;
+    		case 3 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;         break;
+    		case 4 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;        break;
+    		case 5 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;       break;
+    		case 6 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;           break;
+    		case 7 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;          break;
+    		case 8 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;         break;
+    		case 9 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;         break;
+    		case 10: LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;        break;
+    		case 11: LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;       break;
+		case 12: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1;           break;
+		case 13: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1_H;         break;
+		case 14: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1;         break;
+		case 15: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1_H;       break;
+		case 16: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2;         break;
+		case 17: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2_H;       break;
+    		case 18: LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
+    		case 19: LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
+    		case 20: LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;                break;
+    		case 21: LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;                break;
+    		case 22: LVDSCRT1Ptr = SiS_LVDSCRT1320x480_1;           break;
+
+    	}
+    	temp1=(LVDSCRT1Ptr+ResInfo)->CR[0];
+    	temp2=(LVDSCRT1Ptr+ResInfo)->CR[14];
+    	tempax=(temp1&0xFF)|((temp2&0x03)<<8);
+    	tempbx=(LVDSCRT1Ptr+ResInfo)->CR[6];
+    	tempcx=(LVDSCRT1Ptr+ResInfo)->CR[13]<<8;
+    	tempcx = tempcx&0x0100;
+    	tempcx = tempcx << 2;
+    	tempbx = tempbx | tempcx;
+    	temp1=(LVDSCRT1Ptr+ResInfo)->CR[7];
+
+    } else {
+
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+	if(HwDeviceExtension->jChipType < SIS_315H) {
+    	   CRT1Index &= 0x3F;
+	}
+    	temp1 = (USHORT)SiS_CRT1Table[CRT1Index].CR[0];
+    	temp2 = (USHORT)SiS_CRT1Table[CRT1Index].CR[14];
+    	tempax=(temp1&0xFF)|((temp2&0x03)<<8);
+    	tempbx = (USHORT)SiS_CRT1Table[CRT1Index].CR[6];
+    	tempcx = (USHORT)SiS_CRT1Table[CRT1Index].CR[13]<<8;
+    	tempcx = tempcx&0x0100;
+    	tempcx = tempcx << 2;
+    	tempbx = tempbx | tempcx;
+    	temp1 = (USHORT)SiS_CRT1Table[CRT1Index].CR[7];
+
+    }
+
+  }
+
+  if(temp1&0x01) tempbx |= 0x0100;
+  if(temp1&0x20) tempbx |= 0x0200;
+  tempax += 5;
+  if(modeflag & Charx8Dot) tempax *= 8;
+  else tempax *= 9;
+
+  SiS_VGAHT = SiS_HT = tempax;
+  tempbx++;
+  SiS_VGAVT = SiS_VT = tempbx;
+}
+
+void
+SiS_UnLockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+  if(HwDeviceExtension->jChipType >= SIS_315H)
+    	SiS_SetRegOR(SiS_Part1Port,0x2f,0x01);
+  else
+    	SiS_SetRegOR(SiS_Part1Port,0x24,0x01);
+}
+
+void
+SiS_LockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+  if(HwDeviceExtension->jChipType >= SIS_315H)
+    	SiS_SetRegAND(SiS_Part1Port,0x2F,0xFE);
+  else
+     	SiS_SetRegAND(SiS_Part1Port,0x24,0xFE);
+}
+
+void
+SiS_EnableCRT2()
+{
+  SiS_SetRegOR(SiS_P3c4,0x1E,0x20);
+}
+
+/* Checked against 650/LVDS(1.10.07)/301 and 630/301B BIOS */
+void
+SiS_DisableBridge(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+  USHORT tempah,temp;
+  UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+
+  if (SiS_IF_DEF_LVDS == 0) {
+
+      if(SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== TW: For 30xB/LV ===== */
+
+        if(HwDeviceExtension->jChipType < SIS_315H) {
+
+	   /* 300 series */
+
+	   if(!(SiS_CR36BIOSWord23b(HwDeviceExtension))) {
+	      SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x08);
+	      SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 3);
+	   }
+	   if(SiS_Is301B(BaseAddr)) {
+	      SiS_SetRegAND(SiS_Part4Port,0x1f,0x3f);
+	      SiS_ShortDelay(1);
+	   }
+	   SiS_SetRegAND(SiS_Part2Port,0x00,0xDF);
+	   SiS_DisplayOff();
+	   SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
+	   SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);
+	   SiS_UnLockCRT2(HwDeviceExtension,BaseAddr);
+	   SiS_SetRegOR(SiS_Part1Port,0x01,0x80);
+	   SiS_SetRegOR(SiS_Part1Port,0x02,0x40);
+/*	   SiS_DoSomeThingPCI();    */  /* TW: Is this really required ? */
+	   if( (!(SiS_CRT2IsLCD(BaseAddr))) || (!(SiS_CR36BIOSWord23d(HwDeviceExtension))) ) {
+	      SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
+              SiS_SetRegANDOR(SiS_P3c4,0x11,0xFB,0x04);
+	   }
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ModeFlag */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
+        } else {
 
-	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	tempbx = SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
-	tempax = 0;
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-			tempax = tempax | SupportRAMDAC2;
-		}
-		if (SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {	/*301b */
-			tempax = tempax | SupportLCD;
-			if (SiS_LCDResInfo != Panel1280x1024) {
-				if (SiS_LCDResInfo != Panel1280x960) {
-					if (SiS_LCDInfo & LCDNonExpanding) {
-						if (resinfo >= 9) {
-							tempax = 0;
-							return (0);
-						}
-					}
-				}
-			}
-		}
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV) {	/* for HiTV */
-			tempax = tempax | SupportHiVisionTV;
-			if (SiS_VBInfo & SetInSlaveMode) {
-				if (resinfo == 4)
-					return (0);
-				if (resinfo == 3) {
-					if (SiS_SetFlag & TVSimuMode)
-						return (0);
-				}
-				if (resinfo > 7)
-					return (0);
-			}
-		} else {
-			if (SiS_VBInfo &
-			    (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO |
-			     SetCRT2ToSCART)) {
-				tempax = tempax | SupportTV;
-				/*301b */
-				if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {	/*301b */
+	   /* 310 series */
+
+#if 0
+           if(SiS_Is301B(BaseAddr)) {
+#endif
+             /* TW: Inserted from 650/301LV BIOS */
+	     if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+	     	   SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFE,0x00);
+		   SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 3);
+	     } else if (SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+		   SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFE,0x00);
+		   SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 3);
+             }
+	     /* TW end */
+           /* TW: 301B dependent code starts here in 650/301LV BIOS */
+	   if(SiS_Is301B(BaseAddr)) {
+	     tempah = 0x3f;
+#if 0        /* TW: This is not done in 650/301LV BIOS, instead 0x3f is used in any case */
+             if(SiS_IsDualEdge(HwDeviceExtension, BaseAddr)) {
+	        tempah = 0x7f;
+	        if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
+		   tempah = 0xbf;
+                }
+	     }
+#endif
+             SiS_SetRegAND(SiS_Part4Port,0x1F,tempah);
+           } /* 301B dependent code ends here in 650/301V BIOS */
+#if 0        /* TW: This is not done in 650/301LV BIOS */
+	     if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+                SiS_SetRegAND(SiS_Part1Port,0x1E,0xDF);
+	        SiS_DisplayOff();
+	        SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
+	        return;
+	     } else {
+	        if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+                    SiS_SetRegAND(SiS_Part2Port,0x00,0xDF);
+		    SiS_DisplayOff();
+	        }
+	     }
+           } else {
+#endif
+                 SiS_SetRegAND(SiS_Part2Port,0x00,0xDF);
+		 SiS_DisplayOff();
+#if 0
+	   }
+#endif
 
-					tempax = tempax | SupportTV1024;
+           SiS_SetRegOR(SiS_Part1Port,0x00,0x80);
 
-				}
-				/*end 301b */
+           SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
+
+	   temp = SiS_GetReg1(SiS_Part1Port,0x00);
+           SiS_SetRegOR(SiS_Part1Port,0x00,0x10);
+	   SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);
+	   SiS_SetReg1(SiS_Part1Port,0x00,temp);
+
+	   /* TW: Inserted from 650/301LV BIOS */
+	   if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+	       if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {
+	           if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+		          SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
+			  SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFD,0x00);
+			  SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 4);
+                   } else if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+                          SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
+			  SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFD,0x00);
+			  SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 4);
+		   }
+	       }
+	    } else if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+	       if (!(SiS_CRT2IsLCD(BaseAddr))) {
+	            SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
+		    SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFD,0x00);
+		    SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 4);
+               } else if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {
+	           if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+		          SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
+			  SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFD,0x00);
+			  SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 4);
+                   } else if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+                          SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
+			  SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFD,0x00);
+			  SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 4);
+		   }
+	       }
+	   }
+	   /* TW: 650/301LV end */
 
-				if (!(SiS_VBInfo & SetPALTV)) {
-					if (modeflag & NoSupportSimuTV) {
-						if (SiS_VBInfo & SetInSlaveMode) {
-							if (!
-							    (SiS_VBInfo &
-							     SetNotSimuMode)) {
-								return 0;
-							}
-						}
-					}
-				}
-			}
-		}
-	} else {		/* for LVDS */
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				tempax = tempax | SupportCHTV;
-			}
-		}
-		if (SiS_VBInfo & SetCRT2ToLCD) {
-			tempax = tempax | SupportLCD;
-			if (resinfo > 0x08)
-				return (0);	/*1024x768  */
-			if (SiS_LCDResInfo < Panel1024x768) {
-				if (resinfo > 0x07)
-					return (0);	/*800x600  */
-				if (resinfo == 0x04)
-					return (0);	/*512x384  */
-			}
-		}
 	}
 
-	for (; SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx;
-	     (*i)--) {
-		infoflag =
-		    SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
-		if (infoflag & tempax) {
-			return (1);
-		}
-		if ((*i) == 0)
-			break;
+      } else {     /* ============ TW: For 301 ================ */
+
+        if(HwDeviceExtension->jChipType < SIS_315H)
+             SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x08);
+
+        SiS_SetRegAND(SiS_Part2Port,0x00,0xDF);           /* disable VB */
+        SiS_DisplayOff();
+
+        if(HwDeviceExtension->jChipType >= SIS_315H)
+            SiS_SetRegOR(SiS_Part1Port,0x00,0x80);
+
+        SiS_SetRegAND(SiS_P3c4,0x32,0xDF);                /* disable lock mode */
+
+        temp = SiS_GetReg1(SiS_Part1Port,0x00);
+        SiS_SetRegOR(SiS_Part1Port,0x00,0x10);
+
+        SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);                /* disable CRT2 */
+        SiS_SetReg1(SiS_Part1Port,0x00,temp);
+
+	if(HwDeviceExtension->jChipType < SIS_315H)
+	     SiS_SetRegANDOR(SiS_P3c4,0x11,0xFB,0x04);
+
+      }
+
+  } else {     /* ============ TW: For LVDS =============*/
+
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+
+	/* 300 series */
+
+	if(SiS_IF_DEF_CH70xx == 1) {
+	    if(SiS_Backup70xx == 0xff) {
+		SiS_Backup70xx = SiS_GetCH700x(0x0e);
+	    }
+	    SiS_SetCH700x(0x090E);
 	}
 
-	for ((*i) = 0;; (*i)++) {
-		infoflag =
-		    SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
-		if (SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
-			return (0);
-		}
-		if (infoflag & tempax) {
-			return (1);
-		}
+	if(!(SiS_GetReg1(SiS_P3c4,0x11) & 0x08)) {
+
+	    if(!(SiS_GetReg1(SiS_P3c4,0x13) & 0x40)) {
+
+	        if(!(SiS_CR36BIOSWord23b(HwDeviceExtension))) {
+
+                     SiS_WaitVBRetrace(HwDeviceExtension);
+
+		     if(!(SiS_GetReg1(SiS_P3c4,0x06) & 0x1c)) {
+		         SiS_DisplayOff();
+	             }
+
+	             SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x08);
+	             SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 3);
+                }
+            }
 	}
-	return (1);
-}
 
-void
-SiS_SaveCRT2Info (USHORT ModeNo)
-{
-	USHORT temp1, temp2;
+	SiS_DisplayOff();
 
-	SiS_SetReg1 (SiS_P3d4, 0x34, ModeNo);	/* reserve CR34 for CRT1 Mode No */
-	temp1 = (SiS_VBInfo & SetInSlaveMode) >> 8;
-	temp2 = ~(SetInSlaveMode >> 8);
-	SiS_SetRegANDOR (SiS_P3d4, 0x31, temp2, temp1);
-}
+	SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
 
-void
-SiS_GetVBInfo301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		  USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT tempax, tempbx, temp;
-	USHORT modeflag;
-	UCHAR OutputSelect = *pSiS_OutputSelect;
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);
+	SiS_UnLockCRT2(HwDeviceExtension,BaseAddr);
+	SiS_SetRegOR(SiS_Part1Port,0x01,0x80);
+	SiS_SetRegOR(SiS_Part1Port,0x02,0x40);
+
+	if( (!(SiS_CRT2IsLCD(BaseAddr))) ||
+	              (!(SiS_CR36BIOSWord23d(HwDeviceExtension))) ) {
+		SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
+		SiS_SetRegANDOR(SiS_P3c4,0x11,0xFB,0x04);
 	}
-	SiS_SetFlag = 0;
 
-	SiS_ModeType = modeflag & ModeInfoFlag;
-	tempbx = 0;
-	if (SiS_BridgeIsOn (BaseAddr)) {
-		temp = SiS_GetReg1 (SiS_P3d4, 0x30);
-		tempbx = tempbx | temp;
-		temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-		tempax = temp << 8;
-		tempbx = tempbx | tempax;
-		temp = SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display;	/* ynlai */
-		temp = 0xFFFF ^ temp;
-		tempbx = tempbx & temp;
-#ifdef CONFIG_FB_SIS_315
-		/*301b */
-		if ((SiS_VBType & VB_SIS302B)) {
-			temp = SiS_GetReg1 (SiS_P3d4, 0x38);
-			if (temp == 0x03)
-				tempbx = tempbx | (SetCRT2ToLCDA);
-		}
-		/*end301b */
-#endif
-		if (SiS_IF_DEF_LVDS == 0) {
-			if (SiS_IF_DEF_HiVision)
-				temp = 0x80FC;
-			else
-				temp = 0x807C;
-		} else {
-			if (SiS_IF_DEF_CH7005 == 1) {
-				temp = SetCRT2ToTV | SetCRT2ToLCD;
-			} else {
-				temp = SetCRT2ToLCD;
-			}
-		}
-		if (!(tempbx & temp)) {
-			tempax = tempax | DisableCRT2Display;
-			tempbx = 0;
-		}
+    } else {
 
-		if (SiS_IF_DEF_LVDS == 0) {
-			if (tempbx & SetCRT2ToLCDA) {	/*301b */
-				tempbx =
-				    tempbx & (0xFF00 | SwitchToCRT2 |
-					      SetSimuScanMode);
-			} else if (tempbx & SetCRT2ToRAMDAC) {
-				tempbx =
-				    tempbx & (0xFF00 | SetCRT2ToRAMDAC |
-					      SwitchToCRT2 | SetSimuScanMode);
-			} else if ((tempbx & SetCRT2ToLCD) && (!(SiS_VBType & VB_NoLCD))) {	/*301dlvds */
-				tempbx =
-				    tempbx & (0xFF00 | SetCRT2ToLCD |
-					      SwitchToCRT2 | SetSimuScanMode);
-			} else if (tempbx & SetCRT2ToSCART) {
-				tempbx =
-				    tempbx & (0xFF00 | SetCRT2ToSCART |
-					      SwitchToCRT2 | SetSimuScanMode);
-				tempbx = tempbx | SetPALTV;
-			} else if (tempbx & SetCRT2ToHiVisionTV) {
-				tempbx =
-				    tempbx & (0xFF00 | SetCRT2ToHiVisionTV |
-					      SwitchToCRT2 | SetSimuScanMode);
-				/* ynlai begin */
-				tempbx = tempbx | SetPALTV;
-				/* ynlai end */
-			}
-		} else {
-			if (SiS_IF_DEF_CH7005 == 1) {
-				if (tempbx & SetCRT2ToTV)
-					tempbx =
-					    tempbx & (0xFF00 | SetCRT2ToTV |
-						      SwitchToCRT2 |
-						      SetSimuScanMode);
-			}
-			if (tempbx & SetCRT2ToLCD)
-				tempbx =
-				    tempbx & (0xFF00 | SetCRT2ToLCD |
-					      SwitchToCRT2 | SetSimuScanMode);
-		}
-		if (tempax & DisableCRT2Display) {
-			if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) {
-				tempbx = SetSimuScanMode | DisableCRT2Display;
-			}
-		}
-		if (!(tempbx & DriverMode)) {
-			tempbx = tempbx | SetSimuScanMode;
-		}
-		if (!(tempbx & SetSimuScanMode)) {
-			if (tempbx & SwitchToCRT2) {
-				if (!(modeflag & CRT2Mode)) {
-					tempbx = tempbx | SetSimuScanMode;
-				}
-			} else {
-				if (!
-				    (SiS_BridgeIsEnable
-				     (BaseAddr, HwDeviceExtension))) {
-					if (!(tempbx & DriverMode)) {
-						if (SiS_BridgeInSlave ()) {
-							tempbx =
-							    tempbx |
-							    SetInSlaveMode;
-						}
-					}
-				}
-			}
-		}
-		if (!(tempbx & DisableCRT2Display)) {
-			if (tempbx & DriverMode) {
-				if (tempbx & SetSimuScanMode) {
-					if (!(modeflag & CRT2Mode)) {
-						tempbx =
-						    tempbx | SetInSlaveMode;
-						if (SiS_IF_DEF_LVDS == 0) {
-							if (tempbx &
-							    SetCRT2ToTV) {
-								if (!
-								    (tempbx &
-								     SetNotSimuMode))
-								   SiS_SetFlag =
-									    SiS_SetFlag
-									    |
-									    TVSimuMode;
-							}
-						}
-					}
-				}
-			} else {
-				tempbx = tempbx | SetInSlaveMode;
-				if (SiS_IF_DEF_LVDS == 0) {
-					if (tempbx & SetCRT2ToTV) {
-						if (!(tempbx & SetNotSimuMode))
-							SiS_SetFlag =
-							    SiS_SetFlag |
-							    TVSimuMode;
-					}
-				}
-			}
+	/* 310 series */
+
+	if(SiS_IF_DEF_CH70xx == 2) {
+		if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+			SiS_Chrontel701xOff();
+			SiS_Chrontel701xOff2();
+		} else if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+			SiS_Chrontel701xOff();
+			SiS_Chrontel701xOff2();
 		}
-		if (SiS_IF_DEF_CH7005 == 1) {
-			temp = SiS_GetReg1 (SiS_P3d4, 0x35);
-			if (temp & TVOverScan)
-				tempbx = tempbx | SetCHTVOverScan;
+
+		if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+			SiS_SetCH701x(0x0149);
+		} else if(SiS_IsTVOrSomething(HwDeviceExtension, BaseAddr))  {
+			SiS_SetCH701x(0x0149);
 		}
 	}
-#ifdef CONFIG_FB_SIS_300
-	/*add PALMN */
-	if (SiS_IF_DEF_LVDS == 0) {
-		if ((HwDeviceExtension->jChipType == SIS_630) ||
-		    (HwDeviceExtension->jChipType == SIS_730)) {
-			if (!(OutputSelect & EnablePALMN))
-				SiS_SetRegAND (SiS_P3d4, 0x35, 0x3F);
-			if (tempbx & SetCRT2ToTV) {
-				if (tempbx & SetPALTV) {
-					temp = SiS_GetReg1 (SiS_P3d4, 0x35);
-					temp = temp & 0xC0;
-					if (temp == 0x40)
-						tempbx = tempbx & (~SetPALTV);
-				}
-			}
-		}
+
+	if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+		SiS_DisplayOff();
+	} else if(!(SiS_IsTVOrSomething(HwDeviceExtension, BaseAddr))) {
+		SiS_DisplayOff();
 	}
-	/*end add */
-#endif
-#ifdef CONFIG_FB_SIS_315
-	/*add PALMN */
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (!(OutputSelect & EnablePALMN))
-			SiS_SetRegAND (SiS_P3d4, 0x38, 0x3F);
-		if (tempbx & SetCRT2ToTV) {
-			if (tempbx & SetPALTV) {
-				temp = SiS_GetReg1 (SiS_P3d4, 0x38);
-				temp = temp & 0xC0;
-				if (temp == 0x40)
-					tempbx = tempbx & (~SetPALTV);
-			}
-		}
+
+	if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegOR(SiS_Part1Port,0x00,0x80);
+	} else if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegOR(SiS_Part1Port,0x00,0x80);
 	}
-	/*end add */
-#endif
-	SiS_VBInfo = tempbx;
-}
 
-void
-SiS_GetRAMDAC2DATA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex)
-{
-	USHORT tempax, tempbx, temp;
-	USHORT temp1, temp2, modeflag = 0, tempcx;
+	SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
 
-	USHORT StandTableIndex, CRT1Index;
-	USHORT ResInfo, DisplayType;
-	SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
+	if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);
+	} else if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);
+	}
 
-	SiS_RVBHCMAX = 1;
-	SiS_RVBHCFACT = 1;
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-		StandTableIndex = SiS_GetModePtr (ROMAddr, ModeNo, ModeIdIndex);
-		tempax = SiS_StandTable[StandTableIndex].CRTC[0];
-		tempbx = SiS_StandTable[StandTableIndex].CRTC[6];
-		temp1 = SiS_StandTable[StandTableIndex].CRTC[7];
-	} else {
-		if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-		    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-			/*add crt1ptr */
-			temp =
-			    SiS_GetLVDSCRT1Ptr (ROMAddr, ModeNo, ModeIdIndex,
-						RefreshRateTableIndex, &ResInfo,
-						&DisplayType);
-			if (temp == 0) {
-				return;
-			}
-			switch (DisplayType) {
-			case 0:
-				LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;
-				break;
-			case 1:
-				LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;
-				break;
-			case 2:
-				LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;
-				break;
-			case 3:
-				LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;
-				break;
-			case 4:
-				LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;
-				break;
-			case 5:
-				LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;
-				break;
-			case 6:
-				LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;
-				break;
-			case 7:
-				LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;
-				break;
-			case 8:
-				LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;
-				break;
-			case 9:
-				LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;
-				break;
-			case 10:
-				LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;
-				break;
-			case 11:
-				LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;
-				break;
-			case 12:
-				LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;
-				break;
-			case 13:
-				LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;
-				break;
-			case 14:
-				LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;
-				break;
-			case 15:
-				LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;
-				break;
-			}
-			temp1 = (LVDSCRT1Ptr + ResInfo)->CR[0];
-			temp2 = (LVDSCRT1Ptr + ResInfo)->CR[14];
-			tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
-			tempbx = (LVDSCRT1Ptr + ResInfo)->CR[6];
-			tempcx = (LVDSCRT1Ptr + ResInfo)->CR[13] << 8;
-			tempcx = tempcx & 0x0100;
-			tempcx = tempcx << 2;
-			tempbx = tempbx | tempcx;
-			temp1 = (LVDSCRT1Ptr + ResInfo)->CR[7];
-		} /*add 301b */
-		else {
-			modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-			CRT1Index =
-			    SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-			CRT1Index = CRT1Index & 0x3F;
-			temp1 = (USHORT) SiS_CRT1Table[CRT1Index].CR[0];
-			temp2 = (USHORT) SiS_CRT1Table[CRT1Index].CR[14];
-			tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
-			tempbx = (USHORT) SiS_CRT1Table[CRT1Index].CR[6];
-			tempcx = (USHORT) SiS_CRT1Table[CRT1Index].CR[13] << 8;
-			tempcx = tempcx & 0x0100;
-			tempcx = tempcx << 2;
-			tempbx = tempbx | tempcx;
-			temp1 = (USHORT) SiS_CRT1Table[CRT1Index].CR[7];
-		}
+	if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+		SiS_SetRegAND(SiS_Part1Port,0x1e,0xdf);
 	}
-	if (temp1 & 0x01)
-		tempbx = tempbx | 0x0100;
-	if (temp1 & 0x20)
-		tempbx = tempbx | 0x0200;
-	tempax = tempax + 5;
-	if (modeflag & Charx8Dot)
-		tempax = tempax * 8;
-	else
-		tempax = tempax * 9;
-
-	SiS_VGAHT = tempax;
-	SiS_HT = tempax;
-	tempbx++;
-	SiS_VGAVT = tempbx;
-	SiS_VT = tempbx;
-}
 
-void
-SiS_UnLockCRT2 (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-	if (HwDeviceExtension->jChipType >= SIS_315H) {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x2f, 0xFF, 0x01);
+	if(SiS_IsDualEdge(HwDeviceExtension, BaseAddr)) {
+		SiS_SetRegAND(SiS_Part1Port,0x13,0xff);
 	} else {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x24, 0xFF, 0x01);
+		SiS_SetRegAND(SiS_Part1Port,0x13,0xfb);
 	}
-}
 
-void
-SiS_LockCRT2 (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-	if (HwDeviceExtension->jChipType >= SIS_315H) {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x2F, 0xFE, 0x00);
-	} else {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x24, 0xFE, 0x00);
+	SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+
+	if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegAND(SiS_Part1Port,0x2e,0xf7);
+	} else if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegAND(SiS_Part1Port,0x2e,0xf7);
 	}
-}
 
-void
-SiS_EnableCRT2 ()
-{
-	SiS_SetRegANDOR (SiS_P3c4, 0x1E, 0xFF, 0x20);
+#if 0  /* TW: BIOS code makes no sense */
+       if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+           if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
+	        if(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr)) {
+		  /* Nothing there! */
+		}
+           }
+       }
+#endif
+
+    }  /* 310 series */
+
+  }  /* LVDS */
+
 }
 
+/* TW: Checked against 650/LVDS(1.10.07)/301 and 630/301B BIOS */
 void
-SiS_DisableBridge (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
+SiS_EnableBridge(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT  BaseAddr)
+{
+  USHORT temp=0,tempah,temp1;
+  UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+
+  if(SiS_IF_DEF_LVDS == 0) {
+
+    if(SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: ====== For 301B ====== */
+
+      if(HwDeviceExtension->jChipType < SIS_315H) {
+
+         /* 300 series */
+
+	 if(SiS_CRT2IsLCD(BaseAddr)) {
+	    SiS_SetRegAND(SiS_P3c4,0x11,0xFB);
+	    if(!(SiS_CR36BIOSWord23d(HwDeviceExtension))) {
+	       SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 0);
+	    }
+	    SiS_SetRegOR(SiS_P3c4,0x1E,0x20);   /* Enable CRT2 */
+/*	    DoSomeThingPCI_On() */
+            SiS_DisplayOn();
+	    SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+	    SiS_SetRegAND(SiS_Part1Port,0x02,0xBF);
+	    if(SiS_BridgeInSlave()) {
+      		SiS_SetRegAND(SiS_Part1Port,0x01,0x1F);
+      	    } else {
+      		SiS_SetRegANDOR(SiS_Part1Port,0x01,0x1F,0x40);
+            }
+	    if(!(SiS_GetReg1(SiS_P3c4,0x13) & 0x40)) {
+	        if(!(SiS_GetReg1(SiS_P3c4,0x16) & 0x10)) {
+		    if(!(SiS_CR36BIOSWord23b(HwDeviceExtension))) {
+		        SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 1);
+                    }
+		    SiS_WaitVBRetrace(HwDeviceExtension);
+                    SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x00);
+                }
+	    }
+         } else {
+	   temp = SiS_GetReg1(SiS_P3c4,0x32) & 0xDF;             /* lock mode */
+           if(SiS_BridgeInSlave()) {
+              tempah = SiS_GetReg1(SiS_P3d4,0x30);
+              if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+           }
+           SiS_SetReg1(SiS_P3c4,0x32,temp);
+	   SiS_SetRegOR(SiS_P3c4,0x1E,0x20);
+	   SiS_SetRegANDOR(SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
+	   if(SiS_Is301B(BaseAddr)) {
+              SiS_SetRegOR(SiS_Part4Port,0x1F,0xC0);
+	      SiS_DisplayOn();
+	   } else {
+	      SiS_VBLongWait();
+	      SiS_DisplayOn();
+	      SiS_VBLongWait();
+	   }
+	 }
+
+      } else {
+
+         /* 310 series */
+
+	 /* TW: Inserted from 650/301LV BIOS */
+	 if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+	     SiS_SetRegANDOR(SiS_Part4Port,0x26,0xfd,0x02);
+	     SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 0);
+	 } else if(SiS_CRT2IsLCD(BaseAddr)) {
+	     SiS_SetRegANDOR(SiS_Part4Port,0x26,0xfd,0x02);
+	     SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 0);
+	 }
+	 /* TW: --- end --- */
+
+         if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
+            temp = SiS_GetReg1(SiS_P3c4,0x32) & 0xDF;
+	    if(SiS_BridgeInSlave()) {
+               tempah = SiS_GetReg1(SiS_P3d4,0x30);
+               if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+            }
+            SiS_SetReg1(SiS_P3c4,0x32,temp);
+
+	    SiS_SetRegOR(SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+
+/*          SiS_SetRegAND(SiS_Part1Port,0x2E,0x7F);   */ 	/* TW: Not done in 650/301LV BIOS */
+            temp=SiS_GetReg1(SiS_Part1Port,0x2E);
+            if (!(temp & 0x80))
+                   SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);
+          }
+
+          SiS_SetRegANDOR(SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
+
+          if(SiS_Is301B(BaseAddr)) {
+#if 0	     /* TW: This is not done in 630/301LV BIOS */
+	     if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+                SiS_SetRegOR(SiS_P3c4,0x1E,0x20);               /* enable CRT2 */
+	     }
+#endif
+             /* TW: This is done instead: */
+             SiS_SetRegOR(SiS_Part4Port,0x1F,0xc0);
 
-	USHORT temp1, tempah, temp;
-	SiS_SetRegANDOR (SiS_P3c4, 0x11, 0xF7, 0x08);
-/*SetPanelDelay(1);  */
-	temp1 = 0x01;
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {	/*301b */
-		if ((SiS_IsVAMode (BaseAddr)))
-			temp1 = 0x00;	/*no disable vb */
-	}
+#if 0	     /* TW: This is not done in 630/301LV BIOS */
+	     temp=SiS_GetReg1(SiS_Part1Port,0x2E);
+             if (!(temp & 0x80))
+                SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);
+
+	     tempah = 0xC0;
+	     if(SiS_IsDualEdge(HwDeviceExtension, BaseAddr)) {
+	         tempah = 0x80;
+	         if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
+	             tempah = 0x40;
+                 }
+	     }
+             SiS_SetRegOR(SiS_Part4Port,0x1F,tempah);
+#endif
+             if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr)))   /* TW: "if" new from 650/301LV BIOS */
+	        SiS_SetRegAND(SiS_Part1Port,0x00,0x7F);
 
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (!temp1) {	/*301b */
-			SiS_SetRegANDOR (SiS_Part2Port, 0x00, 0x0DF, 0x00);	/* disable VB */
-			SiS_DisplayOff ();
-			if (HwDeviceExtension->jChipType >= SIS_315H) {	/* 310 series */
-				SiS_SetRegOR (SiS_Part1Port, 0x00, 0x80);	/* alan,BScreenOff */
-			}
-			SiS_SetRegANDOR (SiS_P3c4, 0x32, 0xDF, 0x00);
+          } else {
 
-			temp = SiS_GetReg1 (SiS_Part1Port, 0);
-			SiS_SetRegOR (SiS_Part1Port, 0x00, 0x10);	/* alan,BScreenOff */
-/*
-     if(HwDeviceExtension->jChipType >= SIS_315H) 
-     {
-      SiS_SetRegAND(SiS_Part1Port,0x2E,0x7F);  
-     }
-     */
-			SiS_SetRegANDOR (SiS_P3c4, 0x1E, 0xDF, 0x00);
-			SiS_SetReg1 (SiS_Part1Port, 0, temp);
-		} else {
-			if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {	/*301b */
-				if (!(SiS_Is301B (BaseAddr))) {
-					SiS_SetRegAND (SiS_P3c4, 0x32, 0xDF);
-					if ((!(SiS_IsDualEdge (BaseAddr)))
-					    && (!(SiS_IsVAMode (BaseAddr))))
-						tempah = 0x7F;
-					else if ((!(SiS_IsDualEdge (BaseAddr)))
-						 && (SiS_IsVAMode (BaseAddr)))
-						tempah = 0xBF;
-					else
-						tempah = 0x3F;
-					SiS_SetRegAND (SiS_Part4Port, 0x1F,
-						       tempah);
-				}
-			}
-		}
-	} else {
-		if (SiS_IF_DEF_CH7005) {
-			SiS_SetCH7005 (0x090E);
-		}
-		SiS_DisplayOff ();
-		SiS_SetRegANDOR (SiS_P3c4, 0x32, 0xDF, 0x00);
-		SiS_SetRegANDOR (SiS_P3c4, 0x1E, 0xDF, 0x00);
-		SiS_UnLockCRT2 (HwDeviceExtension, BaseAddr);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x01, 0xFF, 0x80);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x02, 0xFF, 0x40);
-	}
-/*SetPanelDelay(0);  */
-	SiS_SetRegANDOR (SiS_P3c4, 0x11, 0xFB, 0x04);
-}
+             SiS_VBLongWait();
+             SiS_DisplayOn();
+	     if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr)))  {  /* TW: "if" new from 650/301LV BIOS */
+	        SiS_SetRegAND(SiS_Part1Port,0x00,0x7F);
+                SiS_VBLongWait();
+	     }
+
+          }
+
+	  /* TW: Entire section from 650/301LV BIOS */
+	  if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {
+	     if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+/*	        if (!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {  */ /* TW: BIOS code makes no sense */
+		   SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 1);
+		   SiS_WaitVBRetrace(HwDeviceExtension);
+		   SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFE,0x01);
+/*              }   */
+             } else if(SiS_CRT2IsLCD(BaseAddr)) {
+/*	        if (!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {  */ /* TW: BIOS code makes no sense */
+		   SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 1);
+		   SiS_WaitVBRetrace(HwDeviceExtension);
+		   SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFE,0x01);
+/*              }   */
+	     }
+	  }
+	  /* TW: --- end --- */
+
+      }
+
+    } else {	/* ============  TW: For 301 ================ */
+
+       if(HwDeviceExtension->jChipType < SIS_315H)
+            SiS_SetRegANDOR(SiS_P3c4,0x11,0xFB,0x00);
+
+       temp = SiS_GetReg1(SiS_P3c4,0x32) & 0xDF;             /* lock mode */
+       if(SiS_BridgeInSlave()) {
+         tempah = SiS_GetReg1(SiS_P3d4,0x30);
+         if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+       }
+       SiS_SetReg1(SiS_P3c4,0x32,temp);
+
+       SiS_SetRegANDOR(SiS_P3c4,0x1E,0xFF,0x20);             /* enable CRT2 */
+
+       if(HwDeviceExtension->jChipType >= SIS_315H) {        /* 310 series */
+         temp=SiS_GetReg1(SiS_Part1Port,0x2E);
+         if (!(temp & 0x80))
+           SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);            /* by alan,BVBDOENABLE=1 */
+       }
+
+       SiS_SetRegANDOR(SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
+
+       SiS_VBLongWait();
+       SiS_DisplayOn();
+       SiS_VBLongWait();
+
+       if(HwDeviceExtension->jChipType < SIS_315H)
+            SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x00);
+
+    }
+
+  } else {   /* =================== TW: For LVDS ================== */
+
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+
+      /* 300 series */
+
+      if(SiS_CRT2IsLCD(BaseAddr)) {
+         SiS_SetRegAND(SiS_P3c4,0x11,0xFB);
+	 if(!(SiS_CR36BIOSWord23d(HwDeviceExtension))) {
+	    SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 0);
+	 }
+      }
+
+      SiS_EnableCRT2();
+      SiS_DisplayOn();
+      SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+      SiS_SetRegAND(SiS_Part1Port,0x02,0xBF);
+      if(SiS_BridgeInSlave()) {
+      	SiS_SetRegAND(SiS_Part1Port,0x01,0x1F);
+      } else {
+      	SiS_SetRegANDOR(SiS_Part1Port,0x01,0x1F,0x40);
+      }
+
+      if(SiS_IF_DEF_CH70xx == 1) {
+        if(!(SiS_CRT2IsLCD(BaseAddr))) {
+           if (SiS_Backup70xx != 0xff) {
+		SiS_SetCH700x(((SiS_Backup70xx<<8)|0x0E));
+		SiS_Backup70xx = 0xff;
+	   } else SiS_SetCH700x(0x0B0E);
+        }
+      }
+
+      if(SiS_CRT2IsLCD(BaseAddr)) {
+          if(!(SiS_GetReg1(SiS_P3c4,0x13) & 0x40)) {
+              if(!(SiS_GetReg1(SiS_P3c4,0x16) & 0x10)) {
+	          if(!(SiS_CR36BIOSWord23b(HwDeviceExtension))) {
+			SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 1);
+        		SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 1);
+		  }
+		  SiS_WaitVBRetrace(HwDeviceExtension);
+                  SiS_SetRegAND(SiS_P3c4,0x11,0xF7);
+              }
+	  }
+      }
+
+    } else {
+
+       /* 310 series */
+
+#if 0  /* BIOS code makes no sense */
+       if(SiS_IsVAMode()) {
+          if(SiS_IsLCDOrLCDA()) {
+	  }
+       }
+#endif
 
-void
-SiS_EnableBridge (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-	USHORT temp, tempah;
+       SiS_EnableCRT2();
+       SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
 
-	SiS_SetRegANDOR (SiS_P3c4, 0x11, 0xFB, 0x00);
-/*SetPanelDelay(0);        */
-	if (SiS_IF_DEF_LVDS == 0) {
-		if ((!(SiS_IsVAMode (BaseAddr)))
-		    && ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-			SiS_SetRegANDOR (SiS_Part2Port, 0x00, 0x1F, 0x20);
-		} else {
-			temp = SiS_GetReg1 (SiS_P3c4, 0x32);
-			temp = temp & 0xDF;
-			if (SiS_BridgeInSlave ()) {
-				tempah = SiS_GetReg1 (SiS_P3d4, 0x30);
-				if (!(tempah & SetCRT2ToRAMDAC)) {
-					temp = temp | 0x20;
-				}
-			}
-			SiS_SetReg1 (SiS_P3c4, 0x32, temp);
-			SiS_SetRegANDOR (SiS_P3c4, 0x1E, 0xFF, 0x20);
-			if (HwDeviceExtension->jChipType >= SIS_315H) {	/* 310 series */
-				temp = SiS_GetReg1 (SiS_Part1Port, 0x2E);
-				if (!(temp & 0x80))
-					SiS_SetRegOR (SiS_Part1Port, 0x2E, 0x80);	/* by alan,BVBDOENABLE=1 */
+       SiS_SetRegAND(SiS_Part1Port,0x2e,0xf7);
 
-			}
-			SiS_SetRegANDOR (SiS_Part2Port, 0x00, 0x1F, 0x20);
+       if(SiS_IF_DEF_CH70xx == 2) {
+          temp = SiS_GetCH701x(0x66);
+	  temp &= 0x20;
+	  SiS_Chrontel701xOff();
+       }
+
+       SiS_SetRegAND(SiS_Part1Port,0x2e,0x7f);
+
+       temp1 = SiS_GetReg1(SiS_Part1Port,0x2E);
+       if (!(temp1 & 0x80))
+           SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);
+
+       if(SiS_IF_DEF_CH70xx == 2) {
+           if(temp) {
+	       SiS_Chrontel701xOn();
+	   }
+       }
+
+       if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+           SiS_SetRegOR(SiS_Part1Port,0x1E,0x20);
+       }
+
+       if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {
+           SiS_SetRegAND(SiS_Part1Port,0x00,0x7f);
+       }
+
+       if(SiS_IF_DEF_CH70xx == 2) {
+
+       		if(SiS_IsTVOrSomething(HwDeviceExtension, BaseAddr)) {
+           		SiS_Chrontel701xOn2(HwDeviceExtension, BaseAddr);
+         	}
+
+         	if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+           		SiS_ChrontelDoSomething1(HwDeviceExtension, BaseAddr);
+         	} else if(SiS_IsLCDOrLCDA(HwDeviceExtension, BaseAddr)) {
+           		SiS_ChrontelDoSomething1(HwDeviceExtension, BaseAddr);
+        	}
+
+       }
+
+       if(SiS_IF_DEF_CH70xx == 2) {
+       	 	if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {
+ 	   		if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
+	            		SiS_Chrontel701xOn();
+	            		SiS_ChrontelDoSomething4(HwDeviceExtension, BaseAddr);
+           		} else if(SiS_IsLCDOrLCDA(HwDeviceExtension, BaseAddr))  {
+/*	      			if(!SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr)) {  */ /* TW: makes no sense */
+            				SiS_Chrontel701xOn();
+            				SiS_ChrontelDoSomething4(HwDeviceExtension, BaseAddr);
+/*            			}   */
+	   		}
+       		}
+       }
 
-			if (HwDeviceExtension->jChipType >= SIS_315H) {	/* 310 series */
-				temp = SiS_GetReg1 (SiS_Part1Port, 0x2E);
-				if (!(temp & 0x80))
-					SiS_SetRegOR (SiS_Part1Port, 0x2E, 0x80);	/* by alan,BVBDOENABLE=1 */
-			}
+    } /* 310 series */
+
+  }  /* LVDS */
 
-			SiS_SetRegANDOR (SiS_Part2Port, 0x00, 0x1F, 0x20);
-			SiS_VBLongWait ();
-			SiS_DisplayOn ();
-			SiS_VBLongWait ();
-		}
-		/*add301b */
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-			if (!(SiS_Is301B (BaseAddr))) {
-				temp = SiS_GetReg1 (SiS_Part1Port, 0x2E);
-				if (!(temp & 0x80))
-					SiS_SetRegOR (SiS_Part1Port, 0x2E,
-						      0x80);
-				if ((!(SiS_IsDualEdge (BaseAddr)))
-				    && (!(SiS_IsVAMode (BaseAddr))))
-					tempah = 0x80;
-				else if ((!(SiS_IsDualEdge (BaseAddr)))
-					 && (SiS_IsVAMode (BaseAddr)))
-					tempah = 0x40;
-				else
-					tempah = 0xC0;
-				SiS_SetRegOR (SiS_Part4Port, 0x1F, tempah);
-			}
-		}
-		/*end 301b */
-	} else {
-		/*LVDS*/ SiS_EnableCRT2 ();
-		SiS_DisplayOn ();
-		SiS_UnLockCRT2 (HwDeviceExtension, BaseAddr);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x02, 0xBF, 0x00);
-		if (SiS_BridgeInSlave ()) {
-			SiS_SetRegANDOR (SiS_Part1Port, 0x01, 0x1F, 0x00);
-		} else {
-			SiS_SetRegANDOR (SiS_Part1Port, 0x01, 0x1F, 0x40);
-		}
-		if (SiS_IF_DEF_CH7005) {
-			SiS_SetCH7005 (0x0B0E);
-		}
-	}
-/*SetPanelDelay(1);  */
-	SiS_SetRegANDOR (SiS_P3c4, 0x11, 0xF7, 0x00);
 }
 
-void
-SiS_SetPanelDelay (USHORT DelayTime)
+BOOLEAN
+SiS_CR36BIOSWord23b(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT PanelID;
-
-	PanelID = SiS_GetReg1 (SiS_P3d4, 0x36);
-	PanelID = PanelID >> 4;
+  USHORT temp,temp1;
+  UCHAR *ROMAddr;
 
-	if (DelayTime == 0)
-		SiS_LCD_Wait_Time (SiS_PanelDelayTbl[PanelID].timer[0]);
-	else
-		SiS_LCD_Wait_Time (SiS_PanelDelayTbl[PanelID].timer[1]);
+  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase)) {
+     temp = SiS_GetReg1(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);
+  }
 }
 
-void
-SiS_LCD_Wait_Time (UCHAR DelayTime)
+BOOLEAN
+SiS_CR36BIOSWord23d(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT i, j;
-	ULONG temp, flag;
+  USHORT temp,temp1;
+  UCHAR *ROMAddr;
 
-	flag = 0;
-	for (i = 0; i < DelayTime; i++) {
-		for (j = 0; j < 66; j++) {
-			temp = SiS_GetReg3 (0x61);
-			temp = temp & 0x10;
-			if (temp == flag)
-				continue;
-			flag = temp;
-		}
-	}
+  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase)) {
+     temp = SiS_GetReg1(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);
+  }
 }
 
-/*301b*/
+void
+SiS_SetPanelDelay(UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                  USHORT DelayTime)
+{
+  USHORT PanelID, DelayIndex, Delay, temp;
+
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+     if(SiS_VBType & VB_SIS301BLV302BLV) {
+         if(ROMAddr) {
+	     if(!(ROMAddr[0x235] & 0x40)) return;
+	 }
+     }
+  }
+
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+      temp = SiS_GetReg1(SiS_P3c4,0x18);
+  } else {
+      temp = SiS_GetReg1(SiS_P3c4,0x1b);
+  }
+
+  if( (SiS_VBType & VB_SIS301BLV302BLV) && (!(temp & 0x10)) ) {
+       PanelID = 0x12;
+  } else {
+       PanelID = SiS_GetReg1(SiS_P3d4,0x36);
+  }
+
+  DelayIndex = PanelID >> 4;
+
+  if((DelayTime >= 2) && (PanelID & 0x0f) == 1) {
+    Delay = 3;
+  } else {
+    if(DelayTime >= 2) DelayTime -= 2;
+    if(SiS_IF_DEF_LVDS == 0) {
+       if(!(DelayTime & 0x01)) {
+       		Delay = SiS_PanelDelayTbl[DelayIndex].timer[0];
+       } else {
+       		Delay = SiS_PanelDelayTbl[DelayIndex].timer[1];
+		if(HwDeviceExtension->jChipType >= SIS_315H) {
+                    if(DelayTime & 0x04) Delay = 0x190;
+                }
+       }
+    } else {
+       if(!(DelayTime & 0x01)) {
+       		Delay = SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
+       } else {
+       		Delay = SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
+       }
+    }
+    if(ROMAddr) {
+        if(HwDeviceExtension->jChipType < SIS_315H) {
+          if(ROMAddr[0x220] & 0x40) {
+            if(!(DelayTime & 0x01)) {
+	    	Delay = (USHORT)ROMAddr[0x225];
+            } else {
+	    	Delay = (USHORT)ROMAddr[0x226];
+            }
+          }
+        } else {
+	  if(ROMAddr[0x13c] & 0x40) {
+	    if(!(DelayTime & 0x01)) {
+	    	Delay = (USHORT)ROMAddr[0x141];
+            } else {
+	    	Delay = (USHORT)ROMAddr[0x142];
+		if(DelayTime & 0x04) Delay = 0x190;
+            }
+	  }
+	}
+    }
+  }
+  SiS_ShortDelay(Delay);
+}
+
+void
+SiS_LongDelay(USHORT delay)
+{
+  while(delay--) {
+    SiS_GenericDelay(0x19df);   /* 6623 */
+  }
+}
+
+void
+SiS_ShortDelay(USHORT delay)
+{
+  while(delay--) {
+      SiS_GenericDelay(0x42);   /* 66 */
+  }
+}
+
+void
+SiS_GenericDelay(USHORT delay)
+{
+  USHORT temp,flag;
+
+  flag = SiS_GetReg3(0x61) & 0x10;
+
+  while(delay) {
+      temp = SiS_GetReg3(0x61) & 0x10;
+      if(temp == flag) continue;
+      flag = temp;
+      delay--;
+  }
+}
 
 BOOLEAN
-SiS_Is301B (USHORT BaseAddr)
+SiS_Is301B(USHORT BaseAddr)
 {
-	USHORT flag;
-	flag = SiS_GetReg1 (SiS_Part4Port, 0x01);
-	if (flag > (0x0B0))
-		return (0);	/*301b */
-	else
-		return (1);
+  USHORT flag;
+
+  flag = SiS_GetReg1(SiS_Part4Port,0x01);
+  if(flag >= 0x0B0) return(1);
+  else return(0);
 }
 
 BOOLEAN
-SiS_IsDualEdge (USHORT BaseAddr)
+SiS_CRT2IsLCD(USHORT BaseAddr)
 {
-#ifdef CONFIG_FB_SIS_315
-	USHORT flag;
-	flag = SiS_GetReg1 (SiS_P3d4, 0x38);
-	if (flag & EnableDualEdge)
-		return (0);
-	else
-		return (1);
-#endif
-	return (1);
+  USHORT flag;
+
+  flag = SiS_GetReg1(SiS_P3d4,0x30);
+  if(flag & 0x20) return(1);
+  else return(0);
 }
 
 BOOLEAN
-SiS_IsVAMode (USHORT BaseAddr)
+SiS_IsDualEdge(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
-	USHORT flag;
-	flag = SiS_GetReg1 (SiS_P3d4, 0x38);
-#ifdef CONFIG_FB_SIS_315
-	if ((flag & EnableDualEdge) && (flag & SetToLCDA))
-		return (0);
-	else
-		return (1);
+#ifdef SIS315H
+  USHORT flag;
+
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     flag = SiS_GetReg1(SiS_P3d4,0x38);
+     if(flag & EnableDualEdge)  return(1);    /* TW: Inverted result */
+     else  return(0);
+  } else
 #endif
-	return (1);
+     return(0);
 }
 
+/* TW: Inverted result! */
 BOOLEAN
-SiS_IsDisableCRT2 (USHORT BaseAddr)
+SiS_IsVAMode(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
-	USHORT flag;
-	flag = SiS_GetReg1 (SiS_P3d4, 0x30);
-	if (flag & 0x20)
-		return (0);	/*301b */
-	else
-		return (1);
-}
+#ifdef SIS315H
+  USHORT flag;
 
-/*end 301b*/
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     flag = SiS_GetReg1(SiS_P3d4,0x38);
+     if((flag & EnableDualEdge) && (flag & SetToLCDA))
+        return(1);
+     else if(SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: Inserted from 650/301LV BIOS */
+       if(flag) return(1);   			  /* TW: Inserted from 650/301LV BIOS */
+       else     return(0);   			  /* TW: Inserted from 650/301LV BIOS */
+     } else  return(0);
+  } else
+#endif
+     return(0);
+ }
 
 BOOLEAN
-SiS_BridgeIsOn (USHORT BaseAddr)
+SiS_WeHaveBacklightCtrl(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
-	USHORT flag;
+#ifdef SIS315H
+  USHORT flag;
 
-	if (SiS_IF_DEF_LVDS == 1) {
-		return (1);
-	} else {
-		flag = SiS_GetReg1 (SiS_Part4Port, 0x00);
-		if ((flag == 1) || (flag == 2))
-			return (1);	/*301b */
-		else
-			return (0);
-	}
-}
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     flag = SiS_GetReg1(SiS_P3d4,0x79);
+     if(flag & 0x10)  return(1);
+     else             return(0);
+  } else
+#endif
+     return(0);
+ }
 
+#if 0
 BOOLEAN
-SiS_BridgeIsEnable (USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_Is315E(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
-	USHORT flag;
+#ifdef SIS315H
+  USHORT flag;
 
-	if (SiS_BridgeIsOn (BaseAddr) == 0) {
-		flag = SiS_GetReg1 (SiS_Part1Port, 0x0);
-		if (HwDeviceExtension->jChipType < SIS_315H) {	/* 300 series */
-			if (flag & 0x0a0) {
-				return 1;
-			} else {
-				return 0;
-			}
-		} else {	/* 310 series */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     flag = SiS_GetReg1(SiS_P3d4,0x5f);
+     if(flag & 0x10)  return(1);
+     else      	      return(0);
+  } else
+#endif
+     return(0);
+}
+#endif
 
-			if (flag & 0x050) {
-				return 1;
-			} else {
-				return 0;
-			}
+BOOLEAN
+SiS_IsYPbPr(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+#ifdef SIS315H
+  USHORT flag;
 
-		}
-	}
-	return 0;
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     flag = SiS_GetReg1(SiS_P3d4,0x38);
+     if(flag & 0x08)  return(1);
+     else      	      return(0);
+  } else
+#endif
+     return(0);
 }
 
 BOOLEAN
-SiS_BridgeInSlave ()
+SiS_IsTVOrSomething(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
-	USHORT flag1;
+  USHORT flag;
 
-	flag1 = SiS_GetReg1 (SiS_P3d4, 0x31);
-	if (flag1 & (SetInSlaveMode >> 8)) {
-		return 1;
-	} else {
-		return 0;
-	}
+#ifdef SIS315H
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     flag = SiS_GetReg1(SiS_P3d4,0x30);
+     if(flag & SetCRT2ToTV) return(1);
+     flag = SiS_GetReg1(SiS_P3d4,0x38);
+     if(flag & 0x08)        return(1);
+     else                   return(0);
+  } else
+#endif
+  {
+     flag = SiS_GetReg1(SiS_P3d4,0x30);
+     if(flag & SetCRT2ToTV) return(1);
+  }
+  return(0);
 }
 
 BOOLEAN
-SiS_GetLCDResInfo301 (ULONG ROMAddr, USHORT SiS_P3d4, USHORT ModeNo,
-		      USHORT ModeIdIndex)
+SiS_IsLCDOrLCDA(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
-	USHORT temp, modeflag, resinfo = 0;
+  USHORT flag;
 
-	SiS_LCDResInfo = 0;
-	SiS_LCDTypeInfo = 0;
-	SiS_LCDInfo = 0;
+#ifdef SIS315H
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     flag = SiS_GetReg1(SiS_P3d4,0x30);
+     if(flag & SetCRT2ToLCD) return(1);
+     flag = SiS_GetReg1(SiS_P3d4,0x38);
+     if(flag & SetToLCDA)    return(1);
+     else                    return(0);
+  } else
+#endif
+  {
+   flag = SiS_GetReg1(SiS_P3d4,0x30);
+   if(flag & SetCRT2ToLCD)   return(1);
+  }
+  return(0);
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ModeFlag  */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;	/*si+Ext_ResInfo */
-	}
+}
 
-	if (!(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
-		return 0;
-	}
-	if (!(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) {
-		return 0;
-	}
-	temp = SiS_GetReg1 (SiS_P3d4, 0x36);
-	SiS_LCDTypeInfo = temp >> 4;
-	SiS_LCDResInfo = temp & 0x0F;
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_LCDResInfo < Panel1024x768)
-			SiS_LCDResInfo = Panel1024x768;
-	} else {
-		if (SiS_LCDResInfo < Panel800x600)
-			SiS_LCDResInfo = Panel800x600;
-	}
-	if (SiS_LCDResInfo > Panel640x480)
-		SiS_LCDResInfo = Panel1024x768;
+BOOLEAN
+SiS_IsDisableCRT2(USHORT BaseAddr)
+{
+  USHORT flag;
 
-	temp = SiS_GetReg1 (SiS_P3d4, 0x37);
-	SiS_LCDInfo = temp;
+  flag = SiS_GetReg1(SiS_P3d4,0x30);
+  if(flag & 0x20) return(0);
+  else            return(1);
+}
 
-	if (SiS_IF_DEF_LVDS == 1) {
-		if (modeflag & HalfDCLK) {
-			if (SiS_IF_DEF_TRUMPION == 0) {
-				if (!(SiS_LCDInfo & LCDNonExpanding)) {
-					if (ModeNo > 0x13) {
-						if (SiS_LCDResInfo ==
-						    Panel1024x768) {
-							if (resinfo == 4) {	/* 512x384  */
-								SiS_SetFlag =
-								    SiS_SetFlag
-								    |
-								    EnableLVDSDDA;
-							}
-						} else {
-							if (SiS_LCDResInfo ==
-							    Panel800x600) {
-								if (resinfo == 3) {	/*400x300  */
-									SiS_SetFlag
-									    =
-									    SiS_SetFlag
-									    |
-									    EnableLVDSDDA;
-								}
-							}
-						}
-					}
-				} else {
-					SiS_SetFlag =
-					    SiS_SetFlag | EnableLVDSDDA;
-				}
-			} else {
-				SiS_SetFlag = SiS_SetFlag | EnableLVDSDDA;
-			}
-		}
-	}
+BOOLEAN
+SiS_BridgeIsOn(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT flag;
 
-	if (SiS_VBInfo & SetInSlaveMode) {
-		if (SiS_VBInfo & SetNotSimuMode) {
-			SiS_SetFlag = SiS_SetFlag | LCDVESATiming;
-		}
-	} else {
-		SiS_SetFlag = SiS_SetFlag | LCDVESATiming;
-	}
-	return 1;
+  if(SiS_IF_DEF_LVDS == 1) {
+     return(0);   					/* TW: Changed from 1 to 0! */
+  } else {
+#if 0   /* TW: Commented for test on bridge-less systems */
+     if(HwDeviceExtension->jChipType >= SIS_315H) {    	/* TW: New (from 630/301B BIOS - not done there) */
+#endif
+        flag = SiS_GetReg1(SiS_Part4Port,0x00);
+        if((flag == 1) || (flag == 2)) return(0);       /* TW: Changed from 1 to 0! */
+        else return(1);                                 /* TW: Changed from 0 to 1! */
+#if 0
+     } else  return(0);					/* TW: New (from 630/301B BIOS - always return 0) */
+#endif
+  }
 }
 
-void
-SiS_PresetScratchregister (USHORT SiS_P3d4,
-			   PSIS_HW_DEVICE_INFO HwDeviceExtension)
+
+BOOLEAN
+SiS_BridgeIsEnable(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	/*SiS_SetReg1(SiS_P3d4,0x30,0x21);  */
-	/*SiS_SetReg1(SiS_P3d4,0x31,0x41);  */
-	/*SiS_SetReg1(SiS_P3d4,0x32,0x28);  */
-	/*SiS_SetReg1(SiS_P3d4,0x33,0x22);  */
-	/*SiS_SetReg1(SiS_P3d4,0x35,0x43);  */
-	/*SiS_SetReg1(SiS_P3d4,0x36,0x01);  */
-	/*SiS_SetReg1(SiS_P3d4,0x37,0x00);  */
+  USHORT flag;
+
+  if(SiS_BridgeIsOn(BaseAddr,HwDeviceExtension) == 0) {
+    flag=SiS_GetReg1(SiS_Part1Port,0x00);
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+      /* 300 series */
+      if(flag & 0x0a0) return 1;
+      else	       return 0;
+    } else {
+      /* 310 series */
+      if(flag & 0x050) return 1;
+      else             return 0;
+    }
+  }
+  return 0;
 }
 
-void
-SiS_LongWait ()
+BOOLEAN
+SiS_BridgeInSlave()
 {
-	USHORT i;
-
-	i = SiS_GetReg1 (SiS_P3c4, 0x1F);
-	if (!(i & 0xC0)) {
+  USHORT flag1;
 
-		for (i = 0; i < 0xFFFF; i++) {
-			if (!(SiS_GetReg2 (SiS_P3da) & 0x08))
-				break;
-		}
-		for (i = 0; i < 0xFFFF; i++) {
-			if ((SiS_GetReg2 (SiS_P3da) & 0x08))
-				break;
-		}
-	}
+  flag1 = SiS_GetReg1(SiS_P3d4,0x31);
+  if(flag1 & (SetInSlaveMode >> 8)) return 1;
+  else return 0;
 }
 
+/* TW: New from 650/301LV BIOS */
 void
-SiS_VBLongWait ()
+SiS_SetHiVision(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT tempal, temp, i, j;
-
-	if (!(SiS_VBInfo & SetCRT2ToTV)) {
-		temp = 0;
-		for (i = 0; i < 3; i++) {
-			for (j = 0; j < 100; j++) {
-				tempal = SiS_GetReg2 (SiS_P3da);
-				if (temp & 0x01) {	/* VBWaitMode2  */
-					if ((tempal & 0x08)) {
-						continue;
-					}
-					if (!(tempal & 0x08)) {
-						break;
-					}
-				} else {	/* VBWaitMode1  */
-					if (!(tempal & 0x08)) {
-						continue;
-					}
-					if ((tempal & 0x08)) {
-						break;
-					}
-				}
-			}
-			temp = temp ^ 0x01;
-		}
-	} else {
-		SiS_LongWait ();
-	}
-	return;
+  SiS_HiVision = 0;
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     if(SiS_VBType & VB_SIS301BLV302BLV) {
+        if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+           SiS_HiVision = SiS_GetReg1(SiS_P3d4,0x38);
+	   SiS_HiVision &= 0x38;
+	   SiS_HiVision >>= 3;
+        }
+     }
+  }
 }
 
+/* TW: Checked against 650/LVDS and 650/301LV BIOS */
 BOOLEAN
-SiS_WaitVBRetrace (USHORT BaseAddr)
+SiS_GetLCDResInfo301(UCHAR *ROMAddr,USHORT SiS_P3d4,USHORT ModeNo,
+               USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT temp;
+  USHORT temp,modeflag,resinfo=0;
 
-	return 0;
+  SiS_LCDResInfo = 0;
+  SiS_LCDTypeInfo = 0;
+  SiS_LCDInfo = 0;
+
+  if (ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+
+  if(!(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return 0;
+
+  if(!(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return 0;
+
+  temp = SiS_GetReg1(SiS_P3d4,0x36);
+
+  /*fstn*: Fake CR36 (TypeInfo 2, ResInfo Panel320x480) */
+  if(SiS_IF_DEF_FSTN){
+   	temp = 0x20 | Panel320x480;
+   	SiS_SetReg1(SiS_P3d4,0x36,temp);
+  }
+
+  SiS_LCDTypeInfo = temp >> 4;   /* BIOS uses entire CR36 - 1 */
+  SiS_LCDResInfo = temp & 0x0F;
+
+  if(SiS_IF_DEF_FSTN){
+       	SiS_LCDResInfo = Panel320x480;
+  }
+
+  if(SiS_IF_DEF_LVDS == 0) {
+    	if(SiS_LCDResInfo < PanelMin301) SiS_LCDResInfo = PanelMin301;
+  } else {
+    	if(SiS_LCDResInfo < PanelMinLVDS) SiS_LCDResInfo = PanelMinLVDS;
+  }
+
+  if(SiS_LCDResInfo > PanelMax) SiS_LCDResInfo = Panel1024x768;
+
+  temp=SiS_GetReg1(SiS_P3d4,0x37);
+  if(SiS_IF_DEF_FSTN){
+        /* TW: Fake LVDS bridge for FSTN */
+      	temp = 0x04;
+      	SiS_SetReg1(SiS_P3d4,0x37,temp);
+  }
+  SiS_LCDInfo = temp;
+  /* TW: Inserted entire 315-block from 650/LVDS BIOS */
+  if(SiS_IF_DEF_LVDS == 1) {
+     if (HwDeviceExtension->jChipType >= SIS_315H) {
+        temp = SiS_GetReg1(SiS_P3d4,0x39);
+        if(temp & 0x01) {
+	   SiS_LCDInfo &= 0xFFEF;     /* TW: What is this? */
+	   SiS_LCDInfo |= 0x0100;     /* TW: What is this? */
+        }
+     }
+  }
 
-	temp = SiS_GetReg1 (SiS_Part1Port, 0x00);
-	if (!(temp & 0x80)) {
-		return 0;
-	}
+#ifdef LINUX_KERNEL
+  printk(KERN_INFO "sisfb: (LCDInfo = 0x%x LCDResInfo = 0x%x LCDTypeInfo = 0x%x)\n",
+                   SiS_LCDInfo, SiS_LCDResInfo, SiS_LCDTypeInfo);
+#endif
+#ifdef LINUX_XF86
+  xf86DrvMsg(0, X_INFO, "(init301: LCDInfo = 0x%x LCDResInfo = 0x%x LCDTypeInfo = 0x%x)\n",
+			SiS_LCDInfo, SiS_LCDResInfo, SiS_LCDTypeInfo);
+#endif
 
-	for (temp = 0; temp == 0;) {
-		temp = SiS_GetReg1 (SiS_Part1Port, 0x25);
-		temp = temp & 0x01;
-	}
-	for (; temp > 0;) {
-		temp = SiS_GetReg1 (SiS_Part1Port, 0x25);
-		temp = temp & 0x01;
-	}
-	return 1;
+  /* TW: With Trumpion, always Expanding */
+  if(SiS_IF_DEF_TRUMPION != 0){
+       SiS_LCDInfo &= (~LCDNonExpanding);
+  }
+
+  /* TW: Removed LVDS==1 check here; done foe 301B BIOSes as well */
+  if(modeflag & HalfDCLK){
+        if(SiS_IF_DEF_TRUMPION == 0){
+	    if((!(SiS_LCDInfo & 0x0100)) || (SiS_IF_DEF_LVDS == 0)) {  /* TW: Inserted from 650/LVDS BIOS */
+               if(!(SiS_LCDInfo & LCDNonExpanding)){
+	          if(!((SiS_IF_DEF_LVDS == 1) && (SiS_LCDResInfo == Panel640x480))){  /* TW: Inserted from 650/LVDS BIOS */
+                     if(ModeNo > 0x13) {
+                        if(SiS_LCDResInfo == Panel1024x768){
+                           if(resinfo == 4){                              /* 512x384  */
+                              SiS_SetFlag |= EnableLVDSDDA;
+                           }
+                        } else {
+                           if(SiS_LCDResInfo == Panel800x600){
+                              if(resinfo == 3){                           /* 400x300  */
+                                 SiS_SetFlag |= EnableLVDSDDA;
+                              }
+                           }
+                        }
+                     }
+		   } else {
+		     SiS_SetFlag |= EnableLVDSDDA;
+		   }
+               } else { /* NonExpanding */
+                 SiS_SetFlag |= EnableLVDSDDA;
+               }
+           } else {                          /* TW: Inserted from 650/LVDS BIOS */
+	     SiS_SetFlag |= EnableLVDSDDA;   /* TW: Inserted from 650/LVDS BIOS */
+	   }                                 /* TW: Inserted from 650/LVDS BIOS */
+        } else { /* TRUMPION */
+          SiS_SetFlag |= EnableLVDSDDA;
+        }
+  }
+
+  /* TW: wdr: if (VBInfo & LCD) && (VBInfo & (SetSimuScanMode | SwitchToCRT2)) { */
+  if(SiS_VBInfo & SetInSlaveMode){
+    	if(SiS_VBInfo & SetNotSimuMode){
+      		SiS_SetFlag |= LCDVESATiming;
+    	}
+  } else {
+    	SiS_SetFlag |= LCDVESATiming;
+  }
+
+  return 1;
+}
+
+void
+SiS_PresetScratchregister(USHORT SiS_P3d4,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  /*SiS_SetReg1(SiS_P3d4,0x30,0x21);  */
+  /*SiS_SetReg1(SiS_P3d4,0x31,0x41);  */
+  /*SiS_SetReg1(SiS_P3d4,0x32,0x28);  */
+  /*SiS_SetReg1(SiS_P3d4,0x33,0x22);  */
+  /*SiS_SetReg1(SiS_P3d4,0x35,0x43);  */
+  /*SiS_SetReg1(SiS_P3d4,0x36,0x01);  */
+  /*SiS_SetReg1(SiS_P3d4,0x37,0x00);  */
+}
+
+void
+SiS_LongWait()
+{
+  USHORT i;
+
+  i=SiS_GetReg1(SiS_P3c4,0x1F);
+  if(!(i&0xC0)) {
+
+    for(i=0; i<0xFFFF; i++) {
+       if(!(SiS_GetReg2(SiS_P3da) & 0x08))
+         break;
+    }
+    for(i=0; i<0xFFFF; i++) {
+       if((SiS_GetReg2(SiS_P3da) & 0x08))
+         break;
+    }
+  }
+}
+
+void
+SiS_VBLongWait()
+{
+  if(!(SiS_VBInfo & SetCRT2ToTV)) {
+    SiS_VBWait();
+  } else {
+    SiS_LongWait();
+  }
+  return;
+}
+
+void
+SiS_VBWait(void)
+{
+  USHORT tempal,temp,i,j;
+
+  temp=0;
+  for(i=0;i<3;i++) {
+    for(j=0;j<100;j++) {
+       tempal=SiS_GetReg2(SiS_P3da);
+       if(temp&0x01) {
+          if((tempal&0x08))  continue;
+          if(!(tempal&0x08)) break;
+       } else {
+          if(!(tempal&0x08)) continue;
+          if((tempal&0x08))  break;
+       }
+    }
+    temp=temp^0x01;
+  }
+}
+
+void
+SiS_WaitVBRetrace(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+     if(SiS_VBType & VB_SIS301BLV302BLV) {
+        if(!(SiS_GetReg1(SiS_Part1Port,0x00) & 0x20)) return;
+     }
+     if(!(SiS_GetReg1(SiS_Part1Port,0x00) & 0x80)) {
+        SiS_WaitRetrace1(HwDeviceExtension);
+     } else {
+        SiS_WaitRetrace2(HwDeviceExtension);
+     }
+  } else {
+     if(!(SiS_GetReg1(SiS_Part1Port,0x00) & 0x40)) {
+        SiS_WaitRetrace1(HwDeviceExtension);
+     } else {
+        SiS_WaitRetrace2(HwDeviceExtension);
+     }
+  }
+}
+
+void
+SiS_WaitRetrace1(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT i,watchdog;
+  
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     if(SiS_GetReg1(SiS_P3c4,0x1f) & 0xc0) return;
+     watchdog = 65535;
+     while( (SiS_GetReg2(SiS_P3da) & 0x08) && --watchdog);
+     watchdog = 65535;
+     while( (!(SiS_GetReg2(SiS_P3da) & 0x08)) && --watchdog);
+  } else {
+#if 0  /* TW: Not done in A901 BIOS */
+     if(SiS_VBType & VB_SIS301BLV302BLV) {
+        if(SiS_GetReg1(SiS_P3c4,0x1f) & 0xc0) return;
+     }
+#endif
+     for(i=0; i<10; i++) {
+        watchdog = 65535;
+        while( (SiS_GetReg2(SiS_P3da) & 0x08) && --watchdog);
+	if(watchdog) break;
+     }
+     for(i=0; i<10; i++) {
+        watchdog = 65535;
+        while( (!(SiS_GetReg2(SiS_P3da) & 0x08)) && --watchdog);
+	if(watchdog) break;
+     }
+  }
 }
 
 void
-SiS_SetRegANDOR (USHORT Port, USHORT Index, USHORT DataAND, USHORT DataOR)
+SiS_WaitRetrace2(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT temp;
+  USHORT i,watchdog,temp;
 
-	temp = SiS_GetReg1 (Port, Index);	/* SiS_Part1Port index 02 */
-	temp = (temp & (DataAND)) | DataOR;
-	SiS_SetReg1 (Port, Index, temp);
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     watchdog = 65535;
+     while( (SiS_GetReg1(SiS_Part1Port,0x30) & 0x02) && --watchdog);
+     watchdog = 65535;
+     while( (!(SiS_GetReg1(SiS_Part1Port,0x30) & 0x02)) && --watchdog);
+  } else {
+     for(i=0; i<10; i++) {
+        watchdog = 65535;
+	while( (temp = SiS_GetReg1(SiS_Part1Port,0x25) & 0x02) && --watchdog);
+	if(watchdog) break;
+     }
+     for(i=0; i<10; i++) {
+        watchdog = 65535;
+	while( (!(temp = SiS_GetReg1(SiS_Part1Port,0x25) & 0x02)) && --watchdog);
+	if(watchdog) break;
+     }
+  }
 }
 
+/* =========== Set and Get register routines ========== */
+
 void
-SiS_SetRegAND (USHORT Port, USHORT Index, USHORT DataAND)
+SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR)
 {
-	USHORT temp;
+  USHORT temp;
 
-	temp = SiS_GetReg1 (Port, Index);	/* SiS_Part1Port index 02 */
-	temp = temp & DataAND;
-	SiS_SetReg1 (Port, Index, temp);
+  temp=SiS_GetReg1(Port,Index);     /* SiS_Part1Port index 02 */
+  temp=(temp&(DataAND))|DataOR;
+  SiS_SetReg1(Port,Index,temp);
 }
 
 void
-SiS_SetRegOR (USHORT Port, USHORT Index, USHORT DataOR)
+SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND)
 {
-	USHORT temp;
+  USHORT temp;
 
-	temp = SiS_GetReg1 (Port, Index);	/* SiS_Part1Port index 02 */
-	temp = temp | DataOR;
-	SiS_SetReg1 (Port, Index, temp);
+  temp=SiS_GetReg1(Port,Index);     /* SiS_Part1Port index 02 */
+  temp=temp&DataAND;
+  SiS_SetReg1(Port,Index,temp);
 }
 
+void SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR)
+{
+  USHORT temp;
+
+  temp=SiS_GetReg1(Port,Index);     /* SiS_Part1Port index 02 */
+  temp=temp|DataOR;
+  SiS_SetReg1(Port,Index,temp);
+}
+
+/* ========================================================= */
+
+/* TW: Set 301 TV Encoder (and some LCD relevant) registers */
+/* TW: Checked against 650/301LV and 630/301B (I+II) */
 void
-SiS_SetGroup2 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-	       USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-	       PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetGroup2(USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo,
+                   USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT i, j, tempax, tempbx, tempcx, temp, temp3;
-	USHORT push1, push2, temp1;
-	UCHAR *PhasePoint;
-	UCHAR *TimingPoint;
-	USHORT modeflag, resinfo, crt2crtc, resindex, xres;
-	ULONG longtemp, tempeax, tempebx, temp2, tempecx;
-	USHORT SiS_RY1COE = 0, SiS_RY2COE = 0, SiS_RY3COE = 0, SiS_RY4COE =
-	    0, SiS_RY5COE = 0, SiS_RY6COE = 0, SiS_RY7COE = 0;
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-		crt2crtc = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		crt2crtc = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
+  USHORT i,j,tempax,tempbx,tempcx,temp,temp3;
+  USHORT push1,push2,temp1;
+  UCHAR *PhasePoint;
+  UCHAR *TimingPoint;
+  SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+  USHORT  modeflag,resinfo,crt2crtc,resindex,CRT2Index;
+  ULONG longtemp,tempeax,tempebx,temp2,tempecx;
+  USHORT  SiS_RY1COE=0,SiS_RY2COE=0,SiS_RY3COE=0,SiS_RY4COE=0;
+  UCHAR atable[] = {
+           0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
+	   0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
+  };
+
+  /* TW: Inserted from 650/301LV BIOS */
+  if(SiS_VBInfo & SetCRT2ToLCDA) return;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+    	crt2crtc = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	crt2crtc = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+
+  tempcx = SiS_VBInfo;
+  tempax = (tempcx & 0x00FF) << 8;
+  tempbx = (tempcx & 0x00FF) | ((tempcx & 0x00FF) << 8);
+  tempbx &= 0x0410;
+  temp = (tempax & 0x0800) >> 8;
+  temp >>= 1;
+  temp |= (((tempbx & 0xFF00) >> 8) << 1);
+  temp |= ((tempbx & 0x00FF) >> 3);
+  temp = temp ^ 0x0C;
+
+  PhasePoint = SiS_PALPhase;
+#ifdef oldHV
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {          /* PALPhase */
+    temp = temp ^ 0x01;
+    if(SiS_VBInfo & SetInSlaveMode) {
+      TimingPoint = SiS_HiTVSt2Timing;
+      if(SiS_SetFlag & TVSimuMode) {
+        if(modeflag & Charx8Dot) TimingPoint = SiS_HiTVSt1Timing;
+        else TimingPoint = SiS_HiTVTextTiming;
+      }
+    } else TimingPoint = SiS_HiTVExtTiming;
+  } else {
+#endif
+    if(SiS_VBInfo & SetPALTV){
+      if( (SiS_VBType & VB_SIS301BLV302BLV) &&    /* TW: @@@ 650+301LV BIOS only tests 301B, 302B */
+          ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
+         PhasePoint = SiS_PALPhase2;
+      else
+         PhasePoint = SiS_PALPhase;
+
+         TimingPoint = SiS_PALTiming;
+    } else {
+        temp |= 0x10;
+        if( (SiS_VBType & VB_SIS301BLV302BLV) &&  /* TW: @@@ 650+301LV BIOS only tests 301B, 302B */
+	    ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
+        	PhasePoint = SiS_NTSCPhase2;
+        else
+        	PhasePoint = SiS_NTSCPhase;
+      
+        TimingPoint = SiS_NTSCTiming;
+    }
+#ifdef oldHV
+  }
+#endif
+  SiS_SetReg1(SiS_Part2Port,0x00,temp);
 
-	tempcx = SiS_VBInfo;
-	tempax = (tempcx & 0x00FF) << 8;
-	tempbx = (tempcx & 0x00FF) | ((tempcx & 0x00FF) << 8);
-	tempbx = tempbx & 0x0410;
-	temp = (tempax & 0x0800) >> 8;
-	temp = temp >> 1;
-	temp = temp | (((tempbx & 0xFF00) >> 8) << 1);
-	temp = temp | ((tempbx & 0x00FF) >> 3);
-	temp = temp ^ 0x0C;
-
-	PhasePoint = SiS_PALPhase;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {	/* PALPhase */
-		temp = temp ^ 0x01;
-		if (SiS_VBInfo & SetInSlaveMode) {
-			TimingPoint = SiS_HiTVSt2Timing;
-			if (SiS_SetFlag & TVSimuMode) {
-				if (modeflag & Charx8Dot)
-					TimingPoint = SiS_HiTVSt1Timing;
-				else
-					TimingPoint = SiS_HiTVTextTiming;
-			}
-		} else
-			TimingPoint = SiS_HiTVExtTiming;
-	} else {
-		if (SiS_VBInfo & SetPALTV) {
-			if ((SiS_VBType & VB_SIS301B)
-			    || (SiS_VBType & VB_SIS302B)) PhasePoint = SiS_PALPhase2;	/* PALPhase */
-			else
-				PhasePoint = SiS_PALPhase;
+#ifdef SIS300
+  if((HwDeviceExtension->jChipType==SIS_630)||
+     (HwDeviceExtension->jChipType==SIS_730)) {
+     	if(SiS_VBInfo & SetCRT2ToTV) {
+             if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
+                  temp1 = SiS_GetReg1(SiS_P3d4,0x35);
+                  if(temp1 & 0x40)
+                     	PhasePoint = SiS_PALMPhase;
+			if( (SiS_VBType & VB_SIS301BLV302BLV) &&  /* TW: From 650/301LV BIOS (see note above) */
+			    ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
+		           PhasePoint = SiS_PALMPhase2;
+                  if(temp1 & 0x80)
+                     	PhasePoint = SiS_PALNPhase;
+			if( (SiS_VBType & VB_SIS301BLV302BLV) &&  /* TW: From 650/301LV BIOS (see note above) */
+			    ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
+		           PhasePoint = SiS_PALNPhase2;
+             }
+        }
+  }
+#endif
 
-			TimingPoint = SiS_PALTiming;
-		} else {
-			temp = temp | 0x10;
-			if ((SiS_VBType & VB_SIS301B)
-			    || (SiS_VBType & VB_SIS302B)) PhasePoint = SiS_NTSCPhase2;	/* PALPhase */
-			else
-				PhasePoint = SiS_NTSCPhase;
+#ifdef SIS315H
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+           if(SiS_VBInfo & SetCRT2ToTV) {
+              if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
+                  temp1 = SiS_GetReg1(SiS_P3d4,0x38);
+                  if(temp1 & 0x40) {
+                     PhasePoint = SiS_PALMPhase;
+		     if( (SiS_VBType & VB_SIS301BLV302BLV) &&  /* TW: @@@ From 650/301LV BIOS (see above) */
+		         ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
+		        PhasePoint = SiS_PALMPhase2;           /* TW: From 650/301LV BIOS */
+		  }
+                  if(temp1 & 0x80) {
+                     PhasePoint = SiS_PALNPhase;
+		     if( (SiS_VBType & VB_SIS301BLV302BLV) && /* TW: @@@ From 650/301LV BIOS (see above) */
+		         ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
+		        PhasePoint = SiS_PALNPhase2;          /* TW: From 650/301LV BIOS */
+		  }
+              }
+           }
+  }
+#endif
 
-			TimingPoint = SiS_NTSCTiming;
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x0, temp);
+  for(i=0x31, j=0; i<=0x34; i++, j++){
+     SiS_SetReg1(SiS_Part2Port,i,PhasePoint[j]);
+  }
+
+  /* TW: Inserted from 650/301LV BIOS */
+  if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {
+     if(SiS_VBInfo & SetCRT2ToTV) {
+        if(!(SiS_VBInfo & SetPALTV)) {
+           if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+               SiS_SetReg1(SiS_Part2Port,0x31,0x1e);
+	       SiS_SetReg1(SiS_Part2Port,0x32,0x8c);
+	       SiS_SetReg1(SiS_Part2Port,0x33,0x5c);
+	       SiS_SetReg1(SiS_Part2Port,0x34,0x7a);
+	   }
+        }
+     }
+  }
 
-#ifdef CONFIG_FB_SIS_300
-	/*add PALMN */
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-			temp = temp & 0x01;
-			if (temp) {
-				temp1 = SiS_GetReg1 (SiS_P3d4, 0x35);
-				temp1 = temp1 & 0x40;
-				if (temp1)
-					PhasePoint = SiS_PALMPhase;
-				temp1 = SiS_GetReg1 (SiS_P3d4, 0x35);
-				temp1 = temp1 & 0x80;
-				if (temp1)
-					PhasePoint = SiS_PALNPhase;
-			}
-		}
-	}
-/*end add*/
+  for(i=0x01, j=0; i<=0x2D; i++, j++){
+     SiS_SetReg1(SiS_Part2Port,i,TimingPoint[j]);
+  }
+  for(i=0x39; i<=0x45; i++, j++){
+     SiS_SetReg1(SiS_Part2Port,i,TimingPoint[j]);
+  }
+  if(SiS_VBInfo & SetCRT2ToTV) {
+    if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if (!(SiS_ModeType & 0x07))
+        SiS_SetRegAND(SiS_Part2Port,0x3A,0x1F);
+    } else {
+      SiS_SetRegAND(SiS_Part2Port,0x3A,0x1F);
+    }
+  }
+
+  SiS_SetRegOR(SiS_Part2Port,0x0A,SiS_NewFlickerMode);
+
+#if 0  /* TW: No BIOS does this */
+     SiS_SetReg1(SiS_Part2Port,0x35,0x00); /*301b*/
+     SiS_SetReg1(SiS_Part2Port,0x36,0x00);
+     SiS_SetReg1(SiS_Part2Port,0x37,0x00);
+     SiS_SetReg1(SiS_Part2Port,0x38,SiS_RY1COE);
+     SiS_SetReg1(SiS_Part2Port,0x48,SiS_RY2COE);
+     SiS_SetReg1(SiS_Part2Port,0x49,SiS_RY3COE);
+     SiS_SetReg1(SiS_Part2Port,0x4a,SiS_RY4COE);
+
+     /*add to change 630+301b filter*/
+     resindex=SiS_GetResInfo(ROMAddr,ModeNo,ModeIdIndex);
+     if(ModeNo<=0x13)
+        xres = SiS_StResInfo[resindex].HTotal;
+     else
+        xres = SiS_ModeResInfo[resindex].HTotal;
+
+     if(xres == 640) {  SiS_RY1COE=0xFF; SiS_RY2COE=0x03; SiS_RY3COE=0x02; SiS_RY4COE=0xF6;
+                        SiS_RY5COE=0xFC; SiS_RY6COE=0x27; SiS_RY7COE=0x46;}
+     if(xres == 800) {  SiS_RY1COE=0x01; SiS_RY2COE=0x01; SiS_RY3COE=0xFC; SiS_RY4COE=0xF8;
+                        SiS_RY5COE=0x08; SiS_RY6COE=0x26; SiS_RY7COE=0x38;}
+     if(xres == 1024){  SiS_RY1COE=0xFF; SiS_RY2COE=0xFF; SiS_RY3COE=0xFC; SiS_RY4COE=0x00;
+                        SiS_RY5COE=0x0F; SiS_RY6COE=0x22; SiS_RY7COE=0x28;}
+     if(xres == 720) {  SiS_RY1COE=0x01; SiS_RY2COE=0x02; SiS_RY3COE=0xFE; SiS_RY4COE=0xF7;
+                        SiS_RY5COE=0x03; SiS_RY6COE=0x27; SiS_RY7COE=0x3c;}
+     SiS_SetReg1(SiS_Part2Port,0x35,SiS_RY1COE); /*301b*/
+     SiS_SetReg1(SiS_Part2Port,0x36,SiS_RY2COE);
+     SiS_SetReg1(SiS_Part2Port,0x37,SiS_RY3COE);
+     SiS_SetReg1(SiS_Part2Port,0x38,SiS_RY4COE);
+     SiS_SetReg1(SiS_Part2Port,0x48,SiS_RY5COE);
+     SiS_SetReg1(SiS_Part2Port,0x49,SiS_RY6COE);
+     SiS_SetReg1(SiS_Part2Port,0x4a,SiS_RY7COE);
+     /*end add*/
 #endif
-#ifdef CONFIG_FB_SIS_315
-	/*add PALMN */
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-		temp = temp & 0x01;
-		if (temp) {
-			temp1 = SiS_GetReg1 (SiS_P3d4, 0x38);
-			temp1 = temp1 & 0x40;
-			if (temp1)
-				PhasePoint = SiS_PALMPhase;
-			temp1 = SiS_GetReg1 (SiS_P3d4, 0x38);
-			temp1 = temp1 & 0x80;
-			if (temp1)
-				PhasePoint = SiS_PALNPhase;
-		}
-	}
-	/*end add */
+
+  /* TW: From 650/301LV and 630/301B BIOS: */
+  SiS_SetReg1(SiS_Part2Port,0x35,SiS_RY1COE);
+  SiS_SetReg1(SiS_Part2Port,0x36,SiS_RY2COE);
+  SiS_SetReg1(SiS_Part2Port,0x37,SiS_RY3COE);
+  SiS_SetReg1(SiS_Part2Port,0x38,SiS_RY4COE);
+
+#ifdef oldHV
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) tempax = 950;
+  else {
+#endif
+    if(SiS_VBInfo & SetPALTV) tempax = 520;
+    else tempax = 440;
+#ifdef oldHV
+  }
 #endif
-	for (i = 0x31, j = 0; i <= 0x34; i++, j++) {
-		SiS_SetReg1 (SiS_Part2Port, i, PhasePoint[j]);
-	}
-	for (i = 0x01, j = 0; i <= 0x2D; i++, j++) {
-		SiS_SetReg1 (SiS_Part2Port, i, TimingPoint[j]);
-	}
-	for (i = 0x39; i <= 0x45; i++, j++) {
-		SiS_SetReg1 (SiS_Part2Port, i, TimingPoint[j]);	/* di->temp2[j] */
-	}
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		SiS_SetRegANDOR (SiS_Part2Port, 0x3A, 0x1F, 0x00);
-	}
-	temp = SiS_NewFlickerMode;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x0A, 0xFF, temp);
-
-	SiS_SetReg1 (SiS_Part2Port, 0x35, 0x00);	/*301b */
-	SiS_SetReg1 (SiS_Part2Port, 0x36, 0x00);
-	SiS_SetReg1 (SiS_Part2Port, 0x37, 0x00);
-	SiS_SetReg1 (SiS_Part2Port, 0x38, SiS_RY1COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x48, SiS_RY2COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x49, SiS_RY3COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x4a, SiS_RY4COE);
-/*add to change 630+301b filter*/
-
-	resindex = SiS_GetResInfo (ROMAddr, ModeNo, ModeIdIndex);
-	if (ModeNo <= 0x13) {
-		xres = SiS_StResInfo[resindex].HTotal;
-	} else {
-		xres = SiS_ModeResInfo[resindex].HTotal;	/* xres->ax */
-	}
-	if (xres == 640) {
-		SiS_RY1COE = 0xFF;
-		SiS_RY2COE = 0x03;
-		SiS_RY3COE = 0x02;
-		SiS_RY4COE = 0xF6;
-		SiS_RY5COE = 0xFC;
-		SiS_RY6COE = 0x27;
-		SiS_RY7COE = 0x46;
-	}
-	if (xres == 800) {
-		SiS_RY1COE = 0x01;
-		SiS_RY2COE = 0x01;
-		SiS_RY3COE = 0xFC;
-		SiS_RY4COE = 0xF8;
-		SiS_RY5COE = 0x08;
-		SiS_RY6COE = 0x26;
-		SiS_RY7COE = 0x38;
-	}
-	if (xres == 1024) {
-		SiS_RY1COE = 0xFF;
-		SiS_RY2COE = 0xFF;
-		SiS_RY3COE = 0xFC;
-		SiS_RY4COE = 0x00;
-		SiS_RY5COE = 0x0F;
-		SiS_RY6COE = 0x22;
-		SiS_RY7COE = 0x28;
-	}
-	if (xres == 720) {
-		SiS_RY1COE = 0x01;
-		SiS_RY2COE = 0x02;
-		SiS_RY3COE = 0xFE;
-		SiS_RY4COE = 0xF7;
-		SiS_RY5COE = 0x03;
-		SiS_RY6COE = 0x27;
-		SiS_RY7COE = 0x3c;
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x35, SiS_RY1COE);	/*301b */
-	SiS_SetReg1 (SiS_Part2Port, 0x36, SiS_RY2COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x37, SiS_RY3COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x38, SiS_RY4COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x48, SiS_RY5COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x49, SiS_RY6COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x4a, SiS_RY7COE);
-
-/*end add*/
-
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV)
-		tempax = 950;
-	else {
-		if (SiS_VBInfo & SetPALTV)
-			tempax = 520;
-		else
-			tempax = 440;
-	}
-	if (SiS_VDE <= tempax) {
-		tempax = tempax - SiS_VDE;
-		tempax = tempax >> 2;
-		tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
-		push1 = tempax;
-		temp = (tempax & 0xFF00) >> 8;
-		temp = temp + (USHORT) TimingPoint[0];
-		SiS_SetReg1 (SiS_Part2Port, 0x01, temp);
-		tempax = push1;
-		temp = (tempax & 0xFF00) >> 8;
-		temp = temp + TimingPoint[1];
-		SiS_SetReg1 (SiS_Part2Port, 0x02, temp);
-	}
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToTV) && (SiS_VGAHDE == 1024)) {
-		if (SiS_VBInfo & SetPALTV) {
-			SiS_SetReg1 (SiS_Part2Port, 0x01, 0x19);
-			SiS_SetReg1 (SiS_Part2Port, 0x02, 0x52);
-		} else {
-			SiS_SetReg1 (SiS_Part2Port, 0x01, 0x0B);
-			SiS_SetReg1 (SiS_Part2Port, 0x02, 0x11);
-		}
-	}
 
-	tempcx = SiS_HT - 1;
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		tempcx = tempcx - 1;
-	}
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x1B, temp);
-	temp = (tempcx & 0xFF00) >> 8;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x1D, ~0x0F, temp);
-
-	tempcx = SiS_HT >> 1;
-	push1 = tempcx;		/* push cx */
-	tempcx = tempcx + 7;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		tempcx = tempcx - 4;
-	}
-	temp = (tempcx & 0x00FF);
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x22, 0x0F, temp);
-
-	tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
-	tempbx = tempbx + tempcx;
-	push2 = tempbx;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x24, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x25, 0x0F, temp);
-
-	tempbx = push2;
-	tempbx = tempbx + 8;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		tempbx = tempbx - 4;
-		tempcx = tempbx;
-	}
-	temp = (tempbx & 0x00FF) << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x29, 0x0F, temp);
-
-	j = j + 2;
-	tempcx = tempcx + (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x27, temp);
-	temp = ((tempcx & 0xFF00) >> 8) << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x28, 0x0F, temp);
-
-	tempcx = tempcx + 8;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		tempcx = tempcx - 4;
-	}
-	temp = tempcx & 0xFF;
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x2A, 0x0F, temp);
-
-	tempcx = push1;		/* pop cx */
-	j = j + 2;
-	temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
-	tempcx = tempcx - temp;
-	temp = tempcx & 0x00FF;
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x2D, 0x0F, temp);
-
-	tempcx = tempcx - 11;
-	if (!(SiS_VBInfo & SetCRT2ToTV)) {
-		tempax = SiS_GetVGAHT2 ();
-		tempcx = tempax - 1;
-	}
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x2E, temp);
-
-	tempbx = SiS_VDE;
-	if (SiS_VGAVDE == 360)
-		tempbx = 746;
-	if (SiS_VGAVDE == 375)
-		tempbx = 746;
-	if (SiS_VGAVDE == 405)
-		tempbx = 853;
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		tempbx = tempbx >> 1;
-	}
-	tempbx = tempbx - 2;
-	temp = tempbx & 0x00FF;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		if (SiS_VBInfo & SetInSlaveMode) {
-			if (ModeNo == 0x2f)
-				temp = temp + 1;
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x2F, temp);
+  if(SiS_VDE <= tempax) {
+    tempax -= SiS_VDE;
+    tempax >>= 2;
+    tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
+    push1 = tempax;
+    temp = (tempax & 0xFF00) >> 8;
+    temp += (USHORT)TimingPoint[0];
+    SiS_SetReg1(SiS_Part2Port,0x01,temp);
+
+    tempax = push1;
+    temp = (tempax & 0xFF00) >> 8;
+    temp += TimingPoint[1];
+    SiS_SetReg1(SiS_Part2Port,0x02,temp);
+  }
+
+  if( (SiS_VBType & VB_SIS301BLV302BLV) &&
+      (SiS_VBInfo & SetCRT2ToTV) &&
+      (SiS_VGAHDE >= 1024) &&
+      (SiS_HiVision != 3) ) {
+      if(SiS_VBInfo & SetPALTV) {
+         SiS_SetReg1(SiS_Part2Port,0x01,0x19);
+         SiS_SetReg1(SiS_Part2Port,0x02,0x52);
+      } else {
+         if(HwDeviceExtension->jChipType >= SIS_315H) {
+            SiS_SetReg1(SiS_Part2Port,0x01,0x17);
+            SiS_SetReg1(SiS_Part2Port,0x02,0x1d);
+	 } else {
+            SiS_SetReg1(SiS_Part2Port,0x01,0x0b);
+            SiS_SetReg1(SiS_Part2Port,0x02,0x11);
+	 }
+      } 
+    }
+    
+  tempcx = SiS_HT - 1;
+  if(SiS_VBType & VB_SIS301BLV302BLV) {
+        tempcx--;
+  }
+  temp = tempcx & 0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x1B,temp);
+  temp = (tempcx & 0xFF00) >> 8;
+  SiS_SetRegANDOR(SiS_Part2Port,0x1D,0xF0,temp);
+
+  tempcx = SiS_HT >> 1;
+  push1 = tempcx;                           /* push cx */
+  tempcx += 7;
+#ifdef oldHV
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV)  tempcx -= 4;   /* TW: @@@ not done in 301LV/630+301B BIOS */
+#endif
+  temp = (tempcx & 0x00FF) << 4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x22,0x0F,temp);
 
-	temp = (tempcx & 0xFF00) >> 8;
-	temp = temp | (((tempbx & 0xFF00) >> 8) << 6);
-	if (!(SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-		temp = temp | 0x10;
-		if (!(SiS_VBInfo & SetCRT2ToSVIDEO)) {
-			temp = temp | 0x20;
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x30, temp);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {	/*tv gatingno */
-		tempbx = SiS_VDE;
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			tempbx = tempbx >> 1;
-		}
-		temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
-		SiS_SetReg1 (SiS_Part2Port, 0x46, temp);
-		temp = (tempbx - 3) & 0x00FF;
-		SiS_SetReg1 (SiS_Part2Port, 0x47, temp);
-	}
-/*end 301b*/
-
-	tempbx = tempbx & 0x00FF;
-	if (!(modeflag & HalfDCLK)) {
-		tempcx = SiS_VGAHDE;
-		if (tempcx >= SiS_HDE) {
-			tempbx = tempbx | 0x2000;
-			tempax = tempax & 0x00FF;
-		}
-	}
-	tempcx = 0x0101;
+  tempbx = TimingPoint[j] | ((TimingPoint[j+1]) << 8);
+  tempbx += tempcx;
+  push2 = tempbx;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x24,temp);
+  temp = ((tempbx & 0xFF00) >> 8) << 4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x25,0x0F,temp);
+
+  tempbx = push2;
+
+  tempbx += 8;
+#ifdef oldHV
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {	/* TW: @@@ not done in 301LV/630+301B BIOS */
+    tempbx -= 4;				/* TW: @@@ not done in 301LV/630+301B BIOS */
+    tempcx = tempbx;				/* TW: @@@ not done in 301LV/630+301B BIOS */
+  }						/* TW: @@@ not done in 301LV/630+301B BIOS */
+#endif
+  temp = (tempbx & 0x00FF) << 4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x29,0x0F,temp);
 
-	if (SiS_VBInfo & (SetCRT2ToHiVisionTV | SetCRT2ToTV)) {	/*301b */
-		if (SiS_VGAHDE >= 1024) {
-			tempcx = 0x1920;
-			if (SiS_VGAHDE >= 1280) {
-				tempcx = 0x1420;
-				tempbx = tempbx & 0xDFFF;
-			}
-		}
-	}
-	if (!(tempbx & 0x2000)) {
-		if (modeflag & HalfDCLK) {
-			tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
-		}
-		push1 = tempbx;
-		tempeax = SiS_VGAHDE;
-		tempebx = (tempcx & 0xFF00) >> 8;
-		longtemp = tempeax * tempebx;
-		tempecx = tempcx & 0x00FF;
-		longtemp = longtemp / tempecx;
-		/*301b */
-		tempecx = 8 * 1024;
-		if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-			tempecx = tempecx * 8;
-		}
-		longtemp = longtemp * tempecx;
-		tempecx = SiS_HDE;
-		temp2 = longtemp % tempecx;
-		tempeax = longtemp / tempecx;
-		if (temp2 != 0) {
-			tempeax = tempeax + 1;
-		}
-		tempax = (USHORT) tempeax;
-		/*301b */
-		if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-			tempcx = ((tempax & 0xFF00) >> 5) >> 8;
-		}
-		/*end 301b */
-		tempbx = push1;
-		tempbx =
-		    (USHORT) (((tempeax & 0x0000FF00) & 0x1F00) |
-			      (tempbx & 0x00FF));
-		tempax =
-		    (USHORT) (((tempeax & 0x000000FF) << 8) |
-			      (tempax & 0x00FF));
-		temp = (tempax & 0xFF00) >> 8;
-	} else {
-		temp = (tempax & 0x00FF) >> 8;
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x44, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x45, ~0x03F, temp);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		if ((tempcx & 0x00FF) == 0x01)
-			tempcx = 0x00;
-		SiS_SetRegANDOR (SiS_Part2Port, 0x46, ~0x007, tempcx);
-		SiS_SetRegOR (SiS_Part2Port, 0x46, 0x18);
-		if (SiS_VBInfo & SetPALTV) {
-			tempbx = 0x0364;
-			tempcx = 0x009c;
-		} else {
-			tempbx = 0x0346;
-			tempcx = 0x0078;
-		}
-		temp = (tempbx & 0x00FF);
-		SiS_SetReg1 (SiS_Part2Port, 0x4B, temp);
-		temp = (tempcx & 0x00FF);
-		SiS_SetReg1 (SiS_Part2Port, 0x4C, temp);
-		tempbx = (tempbx & 0x0300);
-		temp = (tempcx & 0xFF00) >> 8;
-		temp = (temp & 0x0003) << 2;
-		temp = temp | (tempbx >> 8);
-		SiS_SetReg1 (SiS_Part2Port, 0x4D, temp);
-		temp = SiS_GetReg1 (SiS_Part2Port, 0x43);
-		SiS_SetReg1 (SiS_Part2Port, 0x43, temp - 3);
-	}
-/*end 301b*/
-
-#ifdef CONFIG_FB_SIS_300
-/*add PALMN*/
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-			temp = temp & 0x01;
-			if (temp) {
-				temp1 = SiS_GetReg1 (SiS_P3d4, 0x35);
-				temp1 = temp1 & 0x40;
-				if (temp1) {
-					SiS_SetRegANDOR (SiS_Part2Port, 0x00,
-							 0xEF, 0x00);
-					temp3 =
-					    SiS_GetReg1 (SiS_Part2Port, 0x01);
-					temp3 = temp3 - 1;
-					SiS_SetReg1 (SiS_Part2Port, 0x01,
-						     temp3);
-				}
-			}
-		}
-	}
-	/*end add */
+  j += 2;
+  tempcx += ((TimingPoint[j] | ((TimingPoint[j+1]) << 8)));
+  temp = tempcx & 0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x27,temp);
+  temp = ((tempcx & 0xFF00) >> 8) << 4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x28,0x0F,temp);
+
+  tempcx += 8;
+#ifdef oldHV
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV)  tempcx -= 4; /* TW: @@@ not done in 301LV BIOS */
 #endif
+  temp = (tempcx & 0xFF) << 4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x2A,0x0F,temp);
 
-#ifdef CONFIG_FB_SIS_315
-/*add PALMN*/
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-		temp = temp & 0x01;
-		if (temp) {
-			temp1 = SiS_GetReg1 (SiS_P3d4, 0x38);
-			temp1 = temp1 & 0x40;
-			if (temp1) {
-				SiS_SetRegANDOR (SiS_Part2Port, 0x00, 0xEF,
-						 0x00);
-				temp3 = SiS_GetReg1 (SiS_Part2Port, 0x01);
-				temp3 = temp3 - 1;
-				SiS_SetReg1 (SiS_Part2Port, 0x01, temp3);
-			}
-		}
-	}
-	/*end add */
+  tempcx = push1;
+  j += 2;
+  tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
+  temp = (tempcx & 0x00FF) << 4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x2D,0x0F,temp);
+
+  tempcx -= 11;
+  if(!(SiS_VBInfo & SetCRT2ToTV)){
+    tempax = SiS_GetVGAHT2() - 1;
+    tempcx = tempax;
+  }
+  temp = tempcx & 0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x2E,temp);	  
+
+  tempbx = SiS_VDE;
+  if(SiS_VGAVDE == 360) tempbx = 746;
+  if(SiS_VGAVDE == 375) tempbx = 746;
+  if(SiS_VGAVDE == 405) tempbx = 853;
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+  	if(SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
+  } else {
+	if((SiS_VBInfo & SetCRT2ToTV) && (!(SiS_HiVision & 0x03))) {
+	   tempbx >>= 1;
+	   if(SiS_SetFlag & TVSimuMode) {
+	      if(ModeNo <= 0x13) {
+	         if(crt2crtc == 1) {
+	            tempbx++;
+                 }
+	      }
+	   } else {
+              if(SiS_VBInfo & SetInSlaveMode) {
+	         if(crt2crtc == 4)   /* TW: BIOS calls GetRatePtrCRT2 here - does not make sense */
+                    if(SiS_ModeType <= 3) tempbx++;
+	      }
+	   }
+        }
+  }
+  tempbx -= 2;
+  temp = tempbx & 0x00FF;
+#ifdef oldHV
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+    if(SiS_VBInfo & SetInSlaveMode) {
+      if(ModeNo == 0x2f) temp++;
+    }
+  }
 #endif
+  SiS_SetReg1(SiS_Part2Port,0x2F,temp);
 
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		if (!(SiS_VBInfo & SetInSlaveMode)) {
-			SiS_SetReg1 (SiS_Part2Port, 0x0B, 0x00);
-		}
-	}
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		return;
-	}
+  temp = (tempcx & 0xFF00) >> 8;
+  temp |= (((tempbx & 0xFF00) >> 8) << 6);
+#ifdef oldHV
+  if(!(SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+#endif
+    if(!(SiS_VBInfo & SetCRT2ToSCART)) {		/* TW: New from 630/301B (II) BIOS */
+       temp |= 0x10;
+       if(!(SiS_VBInfo & SetCRT2ToSVIDEO))  temp |= 0x20;
+    }
+#ifdef oldHV
+  }
+#endif
+  SiS_SetReg1(SiS_Part2Port,0x30,temp);
 
-	tempbx = SiS_HDE - 1;	/* RHACTE=HDE-1 */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x2C, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x2B, 0x0F, temp);
-	temp = 0x01;
-	if (SiS_LCDResInfo == Panel1280x1024) {
-		if (SiS_ModeType == ModeEGA) {
-			if (SiS_VGAHDE >= 1024) {
-				temp = 0x02;
-				if (SiS_SetFlag & LCDVESATiming)
-					temp = 0x01;
-			}
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x0B, temp);
+  if(SiS_VBType & VB_SIS301BLV302BLV) {      /* tv gatingno */
+    tempbx = SiS_VDE;
+    if((SiS_VBInfo & SetCRT2ToTV) && (!(SiS_HiVision & 0x03))) {
+         tempbx >>= 1;
+    }
+    temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
+    temp |= 0x18;                                    /* TW: Inserted from 650/301/301LV BIOS */
+    SiS_SetReg1(SiS_Part2Port,0x46,temp);
+    temp = (tempbx - 3) & 0x00FF;
+    SiS_SetReg1(SiS_Part2Port,0x47,temp);
+    if(SiS_HiVision & 0x03) {
+        if(SiS_HiVision & 0x01) temp = 0x30;
+	else temp = 0x50;
+	SiS_SetReg1(SiS_Part2Port,0x4d,temp);
+    }
+  }
+
+  tempbx &= 0x00FF;
+  if(!(modeflag & HalfDCLK)){
+    tempcx = SiS_VGAHDE;
+    if(tempcx >= SiS_HDE){
+      tempbx |= 0x2000;
+      tempax &= 0x00FF;
+    }
+  }
+
+  tempcx = 0x0101;
+  if( (SiS_VBInfo & SetCRT2ToTV) && (!(SiS_HiVision & 0x03)) ) {  /*301b- TW: BIOS BUG! */
+    if(SiS_VGAHDE >= 1024) {
+      if(!(modeflag & HalfDCLK)) {   	/* TW: "if" inserted from 650/301LV and 630/301B BIOS */
+        tempcx = 0x1920;
+        if(SiS_VGAHDE >= 1280) {
+          tempcx = 0x1420;
+          tempbx &= 0xDFFF;
+        }
+      }
+    }
+  }
+
+  if(!(tempbx & 0x2000)){
+
+    if(modeflag & HalfDCLK){
+      tempcx = (tempcx & 0xFF00) | (((tempcx & 0x00FF) << 1) & 0xff);
+    }
+    push1 = tempbx;
+    tempeax = SiS_VGAHDE;
+    tempebx = (tempcx & 0xFF00) >> 8;
+    longtemp = tempeax * tempebx;
+    tempecx = tempcx & 0x00FF;
+    longtemp /= tempecx;
+    longtemp <<= 0x0d;
+    if(SiS_VBType & VB_SIS301BLV302BLV) {
+     	longtemp <<= 3;
+    }
+    tempecx = SiS_HDE;
+    temp2 = longtemp % tempecx;
+    tempeax = longtemp / tempecx;
+    if(temp2 != 0) tempeax++;
+    tempax = (USHORT)tempeax;
+    tempbx = push1;
+    if(SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: Done anyway in BIOS, but does not matter */
+     	tempcx = ((tempax & 0xFF00) >> 5) >> 8;
+    }
+    tempbx |= (tempax & 0x1F00);
+    tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
+  }
+
+  temp = (tempax & 0xFF00) >> 8;
+  SiS_SetReg1(SiS_Part2Port,0x44,temp);
+  temp = (tempbx & 0xFF00) >> 8;
+  SiS_SetRegANDOR(SiS_Part2Port,0x45,0xC0,temp);
+
+  if(SiS_VBType & VB_SIS301BLV302BLV) {
+       if(tempbx & 0x2000)
+    		tempcx=0x00;
+       temp = tempcx;
+       temp |= 0x18;
+       SiS_SetRegANDOR(SiS_Part2Port,0x46,0xE0,temp);
+       if(SiS_VBInfo & SetPALTV) {
+             tempbx = 0x0382;    /* TW: BIOS; Was 0x0364; */
+             tempcx = 0x007e;    /* TW: BIOS; Was 0x009c; */
+       } else {
+             tempbx = 0x0369;    /* TW: BIOS; Was 0x0346; */
+             tempcx = 0x0061;    /* TW: BIOS; Was 0x0078; */
+       }
+       temp = (tempbx & 0x00FF) ;
+       SiS_SetReg1(SiS_Part2Port,0x4B,temp);
+       temp = (tempcx & 0x00FF) ;
+       SiS_SetReg1(SiS_Part2Port,0x4C,temp);
+       tempbx &= 0x0300;
+       temp = (tempcx & 0xFF00) >> 8;
+       temp = (temp & 0x0003) << 2;
+       temp |= (tempbx >> 8);
+       SiS_SetRegOR(SiS_Part2Port,0x4D,temp);   /* TW: 650/LV - was SetReg1() (not 630/301B) */
+
+       temp = SiS_GetReg1(SiS_Part2Port,0x43);
+       SiS_SetReg1(SiS_Part2Port,0x43,(USHORT)(temp - 3));
+  }
+
+#ifdef SIS300
+  if((HwDeviceExtension->jChipType==SIS_630)||
+     (HwDeviceExtension->jChipType==SIS_730)) {
+          if(SiS_VBInfo & SetCRT2ToTV) {
+             if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
+                  if(SiS_GetReg1(SiS_P3d4,0x35) & 0x40) {
+                           SiS_SetRegAND(SiS_Part2Port,0x00,0xEF);
+                           temp3=SiS_GetReg1(SiS_Part2Port,0x01);
+                           SiS_SetReg1(SiS_Part2Port,0x01,temp3-1);
+                  }
+             }
+          }
+  }
+#endif
 
-	tempbx = SiS_VDE;	/* RTVACTEO=(VDE-1)&0xFF */
-	push1 = tempbx;
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x03, temp);
-	temp = ((tempbx & 0xFF00) >> 8) & 0x07;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x0C, ~0x07, temp);
-
-	tempcx = SiS_VT - 1;
-	push2 = tempcx + 1;
-	temp = tempcx & 0x00FF;	/* RVTVT=VT-1 */
-	SiS_SetReg1 (SiS_Part2Port, 0x19, temp);
-	temp = (tempcx & 0xFF00) >> 8;
-	temp = temp << 5;
-	if (SiS_LCDInfo & LCDRGB18Bit) {
-		temp = temp | 0x10;
-	}
-	if (SiS_VBInfo & SetCRT2ToLCD) {
-		tempbx = (tempbx & 0xFF00) | (SiS_LCDInfo & 0x0FF);
-		if (tempbx & LCDSync) {
-			tempbx = tempbx & LCDSyncBit;
-			tempbx =
-			    (tempbx & 0xFF00) | ((tempbx & 0x00FF) >>
-						 LCDSyncShift);
-			temp = temp | (tempbx & 0x00FF);
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x1A, temp);
+#ifdef SIS315H
+  if (HwDeviceExtension->jChipType >= SIS_315H) {
+            if(SiS_VBInfo & SetCRT2ToTV) {
+               if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
+                    if(SiS_GetReg1(SiS_P3d4,0x38) & 0x40) {
+                             SiS_SetRegAND(SiS_Part2Port,0x00,0xEF);
+                             temp3=SiS_GetReg1(SiS_Part2Port,0x01);
+                             SiS_SetReg1(SiS_Part2Port,0x01,temp3-1);
+                    }
+               }
+            }
+  }
+  /*end add*/
+#endif
 
-	tempcx++;
-	tempbx = 768;
-	if (SiS_LCDResInfo != Panel1024x768) {
-		tempbx = 1024;
-		if (SiS_LCDResInfo != Panel1280x1024) {
-			tempbx = 1200;	/*301b */
-			if (SiS_LCDResInfo != Panel1600x1200) {
-				if (tempbx != SiS_VDE) {
-					tempbx = 960;
-				}
-			}
-		}
-	}
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		tempbx = SiS_VDE;
-		tempbx--;
-		tempcx--;
-	}
-	tempax = 1;
-	if (!(SiS_LCDInfo & LCDNonExpanding)) {
-		if (tempbx != SiS_VDE) {
-			tempax = tempbx;
-			if (tempax < SiS_VDE) {
-				tempax = 0;
-				tempcx = 0;
-			} else {
-				tempax = tempax - SiS_VDE;
-			}
-			tempax = tempax >> 1;
-		}
-		tempcx = tempcx - tempax;	/* lcdvdes */
-		tempbx = tempbx - tempax;	/* lcdvdee */
-	} else {
-		tempax = tempax >> 1;
-		tempcx = tempcx - tempax;	/* lcdvdes */
-		tempbx = tempbx - tempax;	/* lcdvdee */
-	}
-
-	temp = tempcx & 0x00FF;	/* RVEQ1EQ=lcdvdes */
-	SiS_SetReg1 (SiS_Part2Port, 0x05, temp);
-	temp = tempbx & 0x00FF;	/* RVEQ2EQ=lcdvdee */
-	SiS_SetReg1 (SiS_Part2Port, 0x06, temp);
-
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 3;
-	temp = temp | ((tempcx & 0xFF00) >> 8);
-	SiS_SetReg1 (SiS_Part2Port, 0x02, temp);
-
-	tempbx = push2;
-	tempax = push1;
-	tempcx = tempbx;
-	tempcx = tempcx - tempax;
-	tempcx = tempcx >> 4;
-	tempbx = tempbx + tempax;
-	tempbx = tempbx >> 1;
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		tempbx = tempbx - 10;
-	}
-	temp = tempbx & 0x00FF;	/* RTVACTEE=lcdvrs */
-	SiS_SetReg1 (SiS_Part2Port, 0x04, temp);
-
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	tempbx = tempbx + tempcx + 1;
-	temp = temp | (tempbx & 0x000F);
-	SiS_SetReg1 (SiS_Part2Port, 0x01, temp);
-
-	if (SiS_LCDResInfo == Panel1024x768) {
-		if (!(SiS_SetFlag & LCDVESATiming)) {
-			if (!(SiS_LCDInfo & LCDNonExpanding)) {
-				if (ModeNo == 0x13) {
-					SiS_SetReg1 (SiS_Part2Port, 0x04, 0xB9);
-					SiS_SetReg1 (SiS_Part2Port, 0x05, 0xCC);
-					SiS_SetReg1 (SiS_Part2Port, 0x06, 0xA6);
-				} else {
-					temp = crt2crtc & 0x3F;
-					if (temp == 4) {
-						SiS_SetReg1 (SiS_Part2Port,
-							     0x01, 0x2B);
-						SiS_SetReg1 (SiS_Part2Port,
-							     0x02, 0x13);
-						SiS_SetReg1 (SiS_Part2Port,
-							     0x04, 0xE5);
-						SiS_SetReg1 (SiS_Part2Port,
-							     0x05, 0x08);
-						SiS_SetReg1 (SiS_Part2Port,
-							     0x06, 0xE2);
-					}
-				}
-			}
-		}
-	}
+#ifdef oldHV
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+    if(!(SiS_VBInfo & SetInSlaveMode)) {
+      SiS_SetReg1(SiS_Part2Port,0x0B,0x00);
+    }
+  }
+#endif
 
-	SiS_SetRegANDOR (SiS_Part2Port, 0x09, 0xF0, 0x00);
-	SiS_SetRegANDOR (SiS_Part2Port, 0x0A, 0xF0, 0x00);
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+     if(SiS_VBInfo & SetCRT2ToTV)  return;
+  } else {
+     if(SiS_VBInfo & SetCRT2ToTV) {
+       if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {
+         if(SiS_VBInfo & SetCRT2ToTV) {
+           if(!(SiS_VBInfo & SetPALTV)) {
+             if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+               SiS_SetReg1(SiS_Part2Port,0x1c,0xa7);
+	       SiS_SetReg1(SiS_Part2Port,0x1d,0x07);
+	       SiS_SetReg1(SiS_Part2Port,0x1e,0xf2);
+	       SiS_SetReg1(SiS_Part2Port,0x1f,0x6e);
+	       SiS_SetReg1(SiS_Part2Port,0x20,0x17);
+	       SiS_SetReg1(SiS_Part2Port,0x21,0x8b);
+	       SiS_SetReg1(SiS_Part2Port,0x22,0x73);
+	       SiS_SetReg1(SiS_Part2Port,0x23,0x53);
+	       SiS_SetReg1(SiS_Part2Port,0x24,0x13);
+	       SiS_SetReg1(SiS_Part2Port,0x25,0x40);
+	       SiS_SetReg1(SiS_Part2Port,0x26,0x34);
+	       SiS_SetReg1(SiS_Part2Port,0x27,0xf4);
+	       SiS_SetReg1(SiS_Part2Port,0x28,0x63);
+	       SiS_SetReg1(SiS_Part2Port,0x29,0xbb);
+	       SiS_SetReg1(SiS_Part2Port,0x2a,0xcc);
+	       SiS_SetReg1(SiS_Part2Port,0x2b,0x7a);
+	       SiS_SetReg1(SiS_Part2Port,0x2c,0x58);
+	       SiS_SetReg1(SiS_Part2Port,0x2d,0xe4);
+	       SiS_SetReg1(SiS_Part2Port,0x2e,0x73);
+	       SiS_SetReg1(SiS_Part2Port,0x2f,0xda);
+	       SiS_SetReg1(SiS_Part2Port,0x30,0x13);
+	       SiS_SetReg1(SiS_Part2Port,0x43,0x72);
+	     }
+           }
+         }
+       }
+       return;
+     }
+  }
 
-	tempcx = (SiS_HT - SiS_HDE) >> 2;	/* (HT-HDE)>>2     */
-	tempbx = (SiS_HDE + 7);	/* lcdhdee         */
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		tempbx = tempbx + 2;
-	}
-	push1 = tempbx;
-	temp = tempbx & 0x00FF;	/* RHEQPLE=lcdhdee */
-	SiS_SetReg1 (SiS_Part2Port, 0x23, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x25, ~0x0F, temp);
-	/*301b */
-	temp = 7;
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		temp = temp + 2;
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x1F, temp);	/* RHBLKE=lcdhdes */
-	SiS_SetRegANDOR (SiS_Part2Port, 0x20, 0x0F, 0x00);
-
-	tempbx = tempbx + tempcx;
-	push2 = tempbx;
-	temp = tempbx & 0xFF;	/* RHBURSTS=lcdhrs */
-	if (SiS_LCDResInfo == Panel1280x1024) {
-		if (!(SiS_LCDInfo & LCDNonExpanding)) {
-			if (SiS_HDE == 1280) {
-				temp = 0x47;
-			}
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x1C, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x1D, ~0x0F0, temp);
-
-	tempbx = push2;
-	tempcx = tempcx << 1;
-	tempbx = tempbx + tempcx;
-	temp = tempbx & 0x00FF;	/* RHSYEXP2S=lcdhre */
-	SiS_SetReg1 (SiS_Part2Port, 0x21, temp);
-
-	SiS_SetRegANDOR (SiS_Part2Port, 0x17, 0xFB, 0x00);
-	SiS_SetRegANDOR (SiS_Part2Port, 0x18, 0xDF, 0x00);
-
-	if (!(SiS_SetFlag & LCDVESATiming)) {
-		if (SiS_VGAVDE == 525) {
-			if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {	/*301b */
-				temp = 0xC6;
-			} else
-				temp = 0xC4;
-			SiS_SetReg1 (SiS_Part2Port, 0x2f, temp);
-			SiS_SetReg1 (SiS_Part2Port, 0x30, 0xB3);
-		}
-		if (SiS_VGAVDE == 420) {
-			if (
-			    ((SiS_VBType & VB_SIS301B)
-			     || (SiS_VBType & VB_SIS302B))) {
-				temp = 0x4F;
-			} else
-				temp = 0x4E;
-			SiS_SetReg1 (SiS_Part2Port, 0x2f, temp);
-		}
-	}
+  /* TW: From here: LCD Part2 group */
+
+  tempbx = SiS_HDE - 1;         /* RHACTE=HDE-1 */
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x2C,temp);
+  temp = (tempbx & 0xFF00) >> 8;
+  temp <<= 4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x2B,0x0F,temp);
+
+  temp = 0x01;
+  if(SiS_LCDResInfo == Panel1280x1024) {
+    if(SiS_ModeType == ModeEGA) {
+      if(SiS_VGAHDE >= 1024) {
+        temp = 0x02;
+	if(HwDeviceExtension->jChipType >= SIS_315H) {
+           if (SiS_SetFlag & LCDVESATiming) {
+             temp = 0x01;
+	   }
+	}
+      }
+    }
+  }
+  SiS_SetReg1(SiS_Part2Port,0x0B,temp);
+
+  tempbx = SiS_VDE;         /* RTVACTEO=(VDE-1)&0xFF */
+  push1 = tempbx;
+  tempbx--;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x03,temp);
+  temp = ((tempbx & 0xFF00) >> 8) & 0x07;
+  SiS_SetRegANDOR(SiS_Part2Port,0x0C,0xF8,temp);
+
+  tempcx = SiS_VT;
+  push2 = tempcx;
+  tempcx--;
+  temp = tempcx & 0x00FF;   /* RVTVT=VT-1 */
+  SiS_SetReg1(SiS_Part2Port,0x19,temp);
+
+  temp = (tempcx & 0xFF00) >> 8;
+  temp <<= 5;
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+    if(SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
+    else {
+#if 0
+      if(SiS_LCDInfo & LCDRGB18Bit)   /* TW: 630/301B (II) BIOS does not check this!!! */
+#endif
+      if(SiS_LCDInfo & LCDSync)       /* TW: 630/301 BIOS checks this */
+         temp |= 0x10;
+    }
+  } else temp |= 0x10;
+
+  /* 630/301 does not do all this */
+  if((SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCD)) {
+      tempbx = (tempbx & 0xFF00) | (SiS_LCDInfo & 0x0FF);
+      if(tempbx & LCDSync) {
+        tempbx &= (0xFF00 | LCDSyncBit);
+        tempbx = (tempbx & 0xFF00) | ((tempbx & 0x00FF) >> LCDSyncShift);
+        temp |= (tempbx & 0x00FF);
+      }
+  }
+  SiS_SetReg1(SiS_Part2Port,0x1A,temp);
+
+  SiS_SetRegAND(SiS_Part2Port,0x09,0xF0);
+  SiS_SetRegAND(SiS_Part2Port,0x0A,0xF0);
+
+  SiS_SetRegAND(SiS_Part2Port,0x17,0xFB);
+  SiS_SetRegAND(SiS_Part2Port,0x18,0xDF);
+
+  if(HwDeviceExtension->jChipType >= SIS_315H) {   /* 310 series */
+
+      /* TW: Inserted this entire section from 650/301LV BIOS */
+
+      SiS_GetCRT2Part2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                         &CRT2Index,&resindex);
+
+      switch(CRT2Index) {
+        case 0: CRT2Part2Ptr = SiS_CRT2Part2_1024x768_1;  break;  /* "Normal" */
+        case 1: CRT2Part2Ptr = SiS_CRT2Part2_1280x1024_1; break;
+        case 2: CRT2Part2Ptr = SiS_CRT2Part2_1024x768_2;  break;  /* Non-Expanding */
+        case 3: CRT2Part2Ptr = SiS_CRT2Part2_1280x1024_2; break;
+        case 4: CRT2Part2Ptr = SiS_CRT2Part2_1024x768_3;  break;  /* VESA Timing */
+        case 5: CRT2Part2Ptr = SiS_CRT2Part2_1280x1024_3; break;
+      }
+
+      SiS_SetRegANDOR(SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
+      SiS_SetRegANDOR(SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
+      for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
+        SiS_SetReg1(SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+      }
+      for(j = 0x1c; j <= 0x1d; i++, j++ ) {
+        SiS_SetReg1(SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+      }
+      for(j = 0x1f; j <= 0x21; i++, j++ ) {
+        SiS_SetReg1(SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+      }
+      SiS_SetReg1(SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
+      SiS_SetRegANDOR(SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
+
+      if(!(SiS_SetFlag & LCDVESATiming)) {
+        if(SiS_VGAVDE == 0x20d) {
+	  temp = 0xc3;
+	  if(SiS_ModeType <= ModeVGA) {
+	     temp++;
+	     if(SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
+	  }
+	  SiS_SetReg1(SiS_Part2Port,0x2f,temp);
+	  SiS_SetReg1(SiS_Part2Port,0x30,0xb3);
+	}
+	if(SiS_VGAVDE == 0x1a4) {
+	  temp = 0x4d;
+	  if(SiS_ModeType <= ModeVGA) {
+	     temp++;
+	     if(SiS_VBType & VB_SIS301BLV302BLV) temp++;
+	  }
+	  SiS_SetReg1(SiS_Part2Port,0x2f,temp);
+	}
+     } /* 2f5d */
+
+  } else {   /* 300 series */
+
+    tempcx++;
+    tempbx = 768;
+    if(SiS_LCDResInfo != Panel1024x768) {
+      tempbx = 1024;
+      if(SiS_LCDResInfo != Panel1280x1024) {
+         tempbx = 1200;
+         if(SiS_LCDResInfo != Panel1600x1200) {
+            if(tempbx != SiS_VDE) {
+               tempbx = 960;
+            }
+         }
+      }
+    }
+    if(SiS_LCDInfo & LCDNonExpanding) {
+      tempbx = SiS_VDE - 1;
+      tempcx--;
+    }
+    tempax = 1;
+    if(!(SiS_LCDInfo & LCDNonExpanding)) {
+      if(tempbx != SiS_VDE){
+        tempax = tempbx;
+        if(tempax < SiS_VDE) {
+          tempax = 0;
+          tempcx = 0;
+        } else {
+          tempax -= SiS_VDE;
+        }
+        tempax >>= 1;
+      }
+      tempcx -= tempax; /* lcdvdes */
+      tempbx -= tempax; /* lcdvdee */
+    } else {
+      tempax >>= 1;
+      tempcx -= tempax; /* lcdvdes */
+      tempbx -= tempax; /* lcdvdee */
+    }
+
+    temp = tempcx & 0x00FF;   /* RVEQ1EQ=lcdvdes */
+    SiS_SetReg1(SiS_Part2Port,0x05,temp);
+    temp = tempbx & 0x00FF;   /* RVEQ2EQ=lcdvdee */
+    SiS_SetReg1(SiS_Part2Port,0x06,temp);
+
+    temp = ((tempbx & 0xFF00) >> 8 ) << 3;
+    temp |= ((tempcx & 0xFF00) >> 8);
+    SiS_SetReg1(SiS_Part2Port,0x02,temp);
+
+    tempbx = push2;
+    tempax = push1;
+    tempcx = tempbx;
+    tempcx -= tempax;
+    tempcx >>= 4;
+    tempbx += tempax;
+    tempbx >>= 1;
+    if(SiS_LCDInfo & LCDNonExpanding)  tempbx -= 10;
+
+    temp = tempbx & 0x00FF;   		/* RTVACTEE=lcdvrs */
+    SiS_SetReg1(SiS_Part2Port,0x04,temp);
+
+    temp = ((tempbx & 0xFF00) >> 8) << 4;
+    tempbx += (tempcx + 1);
+    temp |= (tempbx & 0x000F);
+    SiS_SetReg1(SiS_Part2Port,0x01,temp);
+
+    /* TW: Code from 630/301B (I+II) BIOS */
+
+    if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
+            (HwDeviceExtension->jChipType == SIS_730) ) &&
+          (HwDeviceExtension->jChipRevision > 2) )  &&
+        (SiS_LCDResInfo == Panel1024x768) &&
+        (!(SiS_SetFlag & LCDVESATiming))  &&
+        (!(SiS_LCDInfo & LCDNonExpanding)) ) {
+            if(ModeNo == 0x13) {
+              SiS_SetReg1(SiS_Part2Port,0x04,0xB9);
+              SiS_SetReg1(SiS_Part2Port,0x05,0xCC);
+              SiS_SetReg1(SiS_Part2Port,0x06,0xA6);
+            } else {
+              if((crt2crtc & 0x3F) == 4) {
+                SiS_SetReg1(SiS_Part2Port,0x01,0x2B);
+                SiS_SetReg1(SiS_Part2Port,0x02,0x13);
+                SiS_SetReg1(SiS_Part2Port,0x04,0xE5);
+                SiS_SetReg1(SiS_Part2Port,0x05,0x08);
+                SiS_SetReg1(SiS_Part2Port,0x06,0xE2);
+              }
+            }
+    }
+
+    /* TW: Inserted missing code from 630/301B BIOS: (II: 3258) */
+
+    if(SiS_LCDTypeInfo == 0x0c) {
+         crt2crtc &= 0x1f;
+         tempcx = 0;
+         if(!(SiS_VBInfo & SetNotSimuMode)) {
+           if (SiS_VBInfo & SetInSlaveMode) {
+              tempcx += 7;
+           }
+         }
+         tempcx += crt2crtc;
+         if (crt2crtc >= 4) {
+           SiS_SetReg1(SiS_Part2Port,0x06,0xff);
+         }
+
+         if(!(SiS_VBInfo & SetNotSimuMode)) {
+           if (SiS_VBInfo & SetInSlaveMode) {
+             if (crt2crtc == 4) {
+                SiS_SetReg1(SiS_Part2Port,0x01,0x28);
+             }
+           }
+         }
+         SiS_SetReg1(SiS_Part2Port,0x02,0x18);
+         SiS_SetReg1(SiS_Part2Port,0x04,atable[tempcx]);
+    }
+
+    tempcx = (SiS_HT - SiS_HDE) >> 2;    	/* (HT-HDE)>>2     */
+    tempbx = SiS_HDE + 7;            		/* lcdhdee         */
+    if(SiS_VBType & VB_SIS301BLV302BLV) {
+         tempbx += 2;
+    }
+    push1 = tempbx;
+    temp = tempbx & 0x00FF;    			/* RHEQPLE=lcdhdee */
+    SiS_SetReg1(SiS_Part2Port,0x23,temp);
+    temp = (tempbx & 0xFF00) >> 8;
+    SiS_SetRegANDOR(SiS_Part2Port,0x25,0xF0,temp);
+
+    temp = 7;
+    if(SiS_VBType & VB_SIS301BLV302BLV) {
+         temp += 2;
+    }
+    SiS_SetReg1(SiS_Part2Port,0x1F,temp);  	/* RHBLKE=lcdhdes */
+
+    SiS_SetRegAND(SiS_Part2Port,0x20,0x0F);
+
+    tempbx += tempcx;
+    push2 = tempbx;
+    temp = tempbx & 0xFF;            		/* RHBURSTS=lcdhrs */
+    if(SiS_LCDResInfo == Panel1280x1024) {
+      if(SiS_LCDInfo & LCDNonExpanding) {
+        if(SiS_HDE == 1280)  temp = 0x47;
+      }
+    }
+    SiS_SetReg1(SiS_Part2Port,0x1C,temp);
+    temp = ((tempbx & 0xFF00) >> 8) << 4;
+    SiS_SetRegANDOR(SiS_Part2Port,0x1D,0x0F,temp);
+
+    tempbx = push2;
+    tempcx <<= 1;
+    tempbx += tempcx;
+    temp = tempbx & 0x00FF;            		/* RHSYEXP2S=lcdhre */
+    SiS_SetReg1(SiS_Part2Port,0x21,temp);
+
+    if(!(SiS_SetFlag & LCDVESATiming)) {
+      if(SiS_VGAVDE == 525) {
+/*      if(SiS_VBType & VB_SIS301BLV302BLV)  */ /* TW: 630/301B (I+II) */
+        if(SiS_ModeType <= ModeVGA)
+    	   temp=0xC6;
+        else
+       	   temp=0xC3;   /* 650: c4 */
+        SiS_SetReg1(SiS_Part2Port,0x2f,temp);
+        SiS_SetReg1(SiS_Part2Port,0x30,0xB3);
+      } else if(SiS_VGAVDE==420) {
+/*      if(SiS_VBType & VB_SIS301BLV302BLV)  */ /* TW: 630/301B (I+II) */
+        if(SiS_ModeType <= ModeVGA)
+	   temp=0x4F;
+        else
+       	   temp=0x4D;   /* 650: 4e */
+        SiS_SetReg1(SiS_Part2Port,0x2f,temp);
+      }
+    }
+
+  } /* HwDeviceExtension */
 }
 
 USHORT
-SiS_GetVGAHT2 ()
+SiS_GetVGAHT2()
 {
-	ULONG tempax, tempbx;
+  ULONG tempax,tempbx;
+
+  tempbx = ((SiS_VGAVT - SiS_VGAVDE) * SiS_RVBHCMAX) & 0xFFFF;
+  tempax = (SiS_VT - SiS_VDE) * SiS_RVBHCFACT;
+  tempax = (tempax * SiS_HT) / tempbx;
+  return((USHORT) tempax);
+}
+
+/* TW: Set 301 Macrovision(tm) registers */
+/* TW: Double-Checked against 650/301LV and 630/301B BIOS */
+void
+SiS_SetGroup3(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT i;
+  UCHAR  *tempdi;
+  USHORT modeflag;
+
+  if(SiS_VBInfo & SetCRT2ToLCDA) return;   /* TW: Inserted from BIOS */
+
+  if(ModeNo<=0x13)
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  else
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+  SiS_SetReg1(SiS_Part3Port,0x00,0x00);
+
+  if(SiS_VBInfo & SetPALTV) {
+    SiS_SetReg1(SiS_Part3Port,0x13,0xFA);
+    SiS_SetReg1(SiS_Part3Port,0x14,0xC8);
+  } else {
+    if(HwDeviceExtension->jChipType >= SIS_315H) {
+      SiS_SetReg1(SiS_Part3Port,0x13,0xF5);
+      SiS_SetReg1(SiS_Part3Port,0x14,0xB7);
+    } else {
+      SiS_SetReg1(SiS_Part3Port,0x13,0xF6);
+      SiS_SetReg1(SiS_Part3Port,0x14,0xBf);
+    }
+  }
+
+#ifdef SIS300
+  if((HwDeviceExtension->jChipType==SIS_630)||
+     (HwDeviceExtension->jChipType==SIS_730)) {
+           if(SiS_VBInfo & SetCRT2ToTV) {
+              if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
+                  if(SiS_GetReg1(SiS_P3d4,0x35) & 0x40){
+                          SiS_SetReg1(SiS_Part3Port,0x13,0xFA);
+                          SiS_SetReg1(SiS_Part3Port,0x14,0xC8);
+                          SiS_SetReg1(SiS_Part3Port,0x3D,0xA8);
+                  }
+              }
+          }
+  }
+#endif
 
-	tempbx = ((SiS_VGAVT - SiS_VGAVDE) * SiS_RVBHCMAX) & 0xFFFF;
-	tempax = (SiS_VT - SiS_VDE) * SiS_RVBHCFACT;
-	tempax = (tempax * SiS_HT) / tempbx;
-	return ((USHORT) tempax);
+#ifdef SIS315H
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+         if(SiS_VBInfo & SetCRT2ToTV) {
+             if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
+                   if(SiS_GetReg1(SiS_P3d4,0x38) & 0x40){
+                          SiS_SetReg1(SiS_Part3Port,0x13,0xFA);
+                          SiS_SetReg1(SiS_Part3Port,0x14,0xC8);
+                          SiS_SetReg1(SiS_Part3Port,0x3D,0xA8);
+                   }
+             }
+         }
+  }
+#endif
+
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+    tempdi = SiS_HiTVGroup3Data;
+    if(SiS_SetFlag & TVSimuMode) {
+      tempdi = SiS_HiTVGroup3Simu;
+      if(!(modeflag & Charx8Dot)) {
+        tempdi = SiS_HiTVGroup3Text;
+      }
+    }
+    for(i=0; i<=0x3E; i++){
+       SiS_SetReg1(SiS_Part3Port,i,tempdi[i]);
+    }
+  }
+  return;
+}
+
+/* TW: Set 301 VGA2 registers */
+/* TW: Double-Checked against 650/301LV and 630/301B BIOS */
+void
+SiS_SetGroup4(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+              USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+	      PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,push1;
+  ULONG tempebx,tempeax,templong;
+
+  if(ModeNo<=0x13)
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  else
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+  /* TW: From 650/301LV BIOS (done above as well, but does not matter) */
+  if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {
+      if(SiS_VBInfo & SetCRT2ToLCDA)
+          SiS_SetReg1(SiS_Part4Port,0x24,0x0e);
+  }
+
+  /* TW: From 650/301LV BIOS */
+  if(SiS_VBInfo & SetCRT2ToLCDA) return;
+
+  temp = SiS_RVBHCFACT;
+  SiS_SetReg1(SiS_Part4Port,0x13,temp);
+
+  tempbx = SiS_RVBHCMAX;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Part4Port,0x14,temp);
+
+  temp2 = (((tempbx & 0xFF00) >> 8) << 7) & 0x00ff;
+
+  tempcx = SiS_VGAHT - 1;
+  temp = tempcx & 0x00FF;
+  SiS_SetReg1(SiS_Part4Port,0x16,temp);
+
+  temp = (((tempcx & 0xFF00) >> 8) << 3) & 0x00ff;
+  temp2 |= temp;
+
+  tempcx = SiS_VGAVT - 1;
+  if(!(SiS_VBInfo & SetCRT2ToTV))  tempcx -= 5;
+
+  temp = tempcx & 0x00FF;
+  SiS_SetReg1(SiS_Part4Port,0x17,temp);
+
+  temp = temp2 | ((tempcx & 0xFF00) >> 8);
+  SiS_SetReg1(SiS_Part4Port,0x15,temp);
+
+  tempcx = SiS_VBInfo;
+  tempbx = SiS_VGAHDE;
+  if(modeflag & HalfDCLK)  tempbx >>= 1;
+
+  /* TW: New for 650/301LV and 630/301B */
+  temp = 0xA0;
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+       temp = 0xA0;
+       if(tempbx != 1024) {
+           temp = 0xC0;
+           if(tempbx != 1280) temp = 0;
+       }
+  } else if(SiS_VBInfo & SetCRT2ToTV) {
+      if(tempbx <= 800) {
+         temp = 0x80;
+	 if(SiS_VBInfo & SetCRT2ToLCD){
+            temp = 0;
+            if(tempbx > 800) temp = 0x60;
+         }
+      }
+  } else {
+      temp = 0x80;
+      if(SiS_VBInfo & SetCRT2ToLCD){
+            temp = 0;
+            if(tempbx > 800) temp = 0x60;
+      }
+  }
+  if(SiS_HiVision & 0x03) {
+        temp = 0;
+	if(SiS_VGAHDE == 1024) temp = 0x20;
+  }
+  SiS_SetRegANDOR(SiS_Part4Port,0x0E,0x10,temp);
+
+  tempebx = SiS_VDE;
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+     if(!(temp & 0xE0)) tempebx >>=1;
+  }
+
+  tempcx = SiS_RVBHRS;
+  temp = tempcx & 0x00FF;
+  SiS_SetReg1(SiS_Part4Port,0x18,temp);
+
+  tempeax = SiS_VGAVDE;
+  tempcx |= 0x4000;
+  if(tempeax <= tempebx){
+    tempcx = ((tempcx & 0xFF00) ^ 0x4000) | (tempcx & 0x00ff);
+  } else {
+    tempeax -= tempebx;
+  }
+
+  push1 = tempcx;
+
+  templong = (tempeax * 256 * 1024) % tempebx;
+  tempeax = (tempeax * 256 * 1024) / tempebx;
+  tempebx = tempeax;
+  if(templong != 0) tempebx++;
+
+  tempcx = push1;
+
+  temp = (USHORT)(tempebx & 0x000000FF);
+  SiS_SetReg1(SiS_Part4Port,0x1B,temp);
+  temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
+  SiS_SetReg1(SiS_Part4Port,0x1A,temp);
+
+  tempbx = (USHORT)(tempebx >> 16);
+  temp = tempbx & 0x00FF;
+  temp <<= 4;
+  temp |= ((tempcx & 0xFF00) >> 8);
+  SiS_SetReg1(SiS_Part4Port,0x19,temp);
+
+  if(SiS_VBType & VB_SIS301BLV302BLV) {
+         SiS_SetReg1(SiS_Part4Port,0x1C,0x28);
+	 tempbx = 0;   			/* TW: From 630/301B and 650/301LV BIOS */
+         tempax = SiS_VGAHDE;
+         if(modeflag & HalfDCLK) tempax >>= 1;
+         if((SiS_VBInfo & SetCRT2ToLCD) || (SiS_HiVision & 0x03)) {
+             if(tempax > 800) tempax -= 800;
+         }
+
+         if((SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) &&
+	                                 (!(SiS_HiVision & 0x03))) {
+           if(tempax > 800) {
+	      tempbx = 8;  		/* TW: From 630/301B and 650/301LV BIOS */
+              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;
+	 SiS_SetReg1(SiS_Part4Port,0x1D,tempax & 0x00FF);
+	 temp <<= 4;
+	 temp |= tempbx;
+	 SiS_SetReg1(SiS_Part4Port,0x1E,temp);
+
+         temp = 0x0036;
+         if((SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV)) &&
+	                               (!(SiS_HiVision & 0x03))) {  /* TW: From 650/301LV BIOS */
+		temp |= 0x01;
+	        if(SiS_VBInfo & SetInSlaveMode) {                   /* TW: From 650/301LV BIOS */
+	          if(!(SiS_SetFlag & TVSimuMode))                   /* TW: From 650/301LV BIOS */
+  	                  temp &= 0xFE;                             /* TW: From 650/301LV BIOS */
+		}
+         }
+         SiS_SetRegANDOR(SiS_Part4Port,0x1F,0xC0,temp);
+         tempbx = (SiS_HT >> 1) - 2;
+         temp = ((tempbx & 0x0700) >> 8) << 3;
+         SiS_SetRegANDOR(SiS_Part4Port,0x21,0xC0,temp);
+         temp = tempbx & 0x00FF;
+         SiS_SetReg1(SiS_Part4Port,0x22,temp);
+         if( (SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) &&
+	                        (SiS_VBInfo & SetCRT2ToLCD) ) {
+             SiS_SetReg1(SiS_Part4Port,0x24,0x0e);
+	 }
+  }
+
+  SiS_SetCRT2VCLK(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+}
+
+/* TW: Double-Checked against 650/301LV and 630/301B BIOS */
+void
+SiS_SetCRT2VCLK(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT vclkindex;
+  USHORT tempah,temp1;
+
+  vclkindex = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                              HwDeviceExtension);
+
+  if(SiS_VBType & VB_SIS301BLV302BLV) {
+   	tempah = SiS_VBVCLKData[vclkindex].Part4_A;
+   	SiS_SetReg1(SiS_Part4Port,0x0A,tempah);
+   	tempah = SiS_VBVCLKData[vclkindex].Part4_B;
+   	SiS_SetReg1(SiS_Part4Port,0x0B,tempah);
+	/* TW: New from 650/301LV BIOS */
+	if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {
+           if(SiS_VBInfo & SetCRT2ToTV) {
+	      if(!(SiS_VBInfo & SetPALTV)) {
+                 if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+		    SiS_SetReg1(SiS_Part4Port,0x0a,0x57);
+		    SiS_SetReg1(SiS_Part4Port,0x0b,0x46);
+		    SiS_SetReg1(SiS_Part4Port,0x1f,0xf6);
+                 }
+              }
+           }
+	}
+  } else {
+   	SiS_SetReg1(SiS_Part4Port,0x0A,0x01);
+   	tempah = SiS_VBVCLKData[vclkindex].Part4_B;
+   	SiS_SetReg1(SiS_Part4Port,0x0B,tempah);
+   	tempah = SiS_VBVCLKData[vclkindex].Part4_A;
+   	SiS_SetReg1(SiS_Part4Port,0x0A,tempah);
+  }
+  SiS_SetReg1(SiS_Part4Port,0x12,0x00);
+  tempah = 0x08;
+  if(SiS_VBInfo & SetCRT2ToRAMDAC) {
+    	tempah |= 0x020;
+  }
+  temp1 = SiS_GetReg1(SiS_Part4Port,0x12);
+  tempah |= temp1;
+  SiS_SetReg1(SiS_Part4Port,0x12,tempah);
 }
 
-void
-SiS_SetGroup3 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-	       USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/* TW: Double-checked against 650/LVDS (1.10.07), 630/301B/LVDS/LVDS+CH, 650/301LV BIOS */
+USHORT
+SiS_GetVCLK2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+        USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT i;
-	UCHAR *tempdi;
-	USHORT modeflag, temp, temp1;
+  USHORT tempbx;
+#ifdef SIS300
+  USHORT LCDXlat1VCLK300[4] = {VCLK65,   VCLK65,   VCLK65,   VCLK65};
+  USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
+  USHORT LVDSXlat2VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
+  USHORT LVDSXlat3VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
+#endif
+#ifdef SIS315H
+  USHORT LCDXlat1VCLK310[4] = {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
+  USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
+  USHORT LVDSXlat2VCLK310[4]= {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
+  USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
+  			   /* {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2}; -  650/LVDS 1.10.07 */
+#endif
+  USHORT LCDXlat0VCLK[4]    = {VCLK40, VCLK40, VCLK40, VCLK40};
+  USHORT LVDSXlat1VCLK[4]   = {VCLK40, VCLK40, VCLK40, VCLK40};
+  USHORT CRT2Index,VCLKIndex=0;
+  USHORT modeflag,resinfo;
+  UCHAR *CHTVVCLKPtr=NULL;
+  USHORT *LCDXlatVCLK1 = NULL;
+  USHORT *LCDXlatVCLK2 = NULL;
+  USHORT *LVDSXlatVCLK2 = NULL;
+  USHORT *LVDSXlatVCLK3 = NULL;
+
+#ifdef SIS315H
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+		LCDXlatVCLK1 = LCDXlat1VCLK310;
+		LCDXlatVCLK2 = LCDXlat2VCLK310;
+		LVDSXlatVCLK2 = LVDSXlat2VCLK310;
+		LVDSXlatVCLK3 = LVDSXlat3VCLK310;
+  } else {
+#endif
+#ifdef SIS300
+		LCDXlatVCLK1 = LCDXlat1VCLK300;
+		LCDXlatVCLK2 = LCDXlat2VCLK300;
+		LVDSXlatVCLK2 = LVDSXlat2VCLK300;
+		LVDSXlatVCLK3 = LVDSXlat3VCLK300;
+#endif
+#ifdef SIS315H
+  }
+#endif
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-	}
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+    	CRT2Index = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	CRT2Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+
+  if(SiS_IF_DEF_LVDS==0) {    /* 301 */
+
+     if (SiS_SetFlag & ProgrammingCRT2) {
+
+        CRT2Index >>= 6;
+        if(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){      /*  LCD */
+            if(HwDeviceExtension->jChipType < SIS_315H) {
+	       /* TW: Inserted from 630/301B BIOS */
+	       if(SiS_LCDResInfo == Panel800x600)
+	    		VCLKIndex = LCDXlat0VCLK[CRT2Index];
+	       else if(SiS_LCDResInfo == Panel1024x768)
+	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
+	       else
+	    		VCLKIndex = LCDXlatVCLK2[CRT2Index];
+	    } else {
+               /* TW: 650/301LV BIOS does not check expanding, 315 does  */
+	       if( (HwDeviceExtension->jChipType > SIS_315PRO) ||
+	           (!(SiS_LCDInfo & LCDNonExpanding)) ) {
+      	          if(SiS_LCDResInfo == Panel1024x768){
+		     VCLKIndex = LCDXlatVCLK1[CRT2Index];
+                   } else if(SiS_LCDResInfo == Panel1280x960) {
+		     VCLKIndex = 0x45;
+		     if(resinfo == 0x09) VCLKIndex++;
+	           } else {
+		     VCLKIndex = LCDXlatVCLK2[CRT2Index];
+      	           }
+	       } else {
+                   VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));  /*  Port 3cch */
+         	   VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+        	   if(ModeNo > 0x13) {
+          		VCLKIndex = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+        	   }
+		   if(ModeNo <= 0x13) {  /* TW: Inserted from 315 BIOS */
+		      if(SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
+		   }
+		   if(VCLKIndex == 0) VCLKIndex = 0x41;
+		   if(VCLKIndex == 1) VCLKIndex = 0x43;
+		   if(VCLKIndex == 4) VCLKIndex = 0x44;
+	       }
+	    }
+        } else if(SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
+        	if((SiS_IF_DEF_HiVision == 1) && (SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+          		if(SiS_SetFlag & RPLLDIV2XO)      VCLKIndex = HiTVVCLKDIV2;
+     			else                              VCLKIndex = HiTVVCLK;
+          		if(SiS_SetFlag & TVSimuMode) {
+            			if(modeflag & Charx8Dot)  VCLKIndex = HiTVSimuVCLK;
+            			else 			  VCLKIndex = HiTVTextVCLK;
+          		}
+        	} else {
+       			if(SiS_SetFlag & RPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
+            		else         		          VCLKIndex = TVVCLK;
+          	}
+		if(HwDeviceExtension->jChipType >= SIS_315H) {
+              		VCLKIndex += 25;
+  		}
+        } else {         					/* RAMDAC2 */
+        	VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));
+        	VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+        	if(ModeNo > 0x13) {
+          		VCLKIndex = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 
+			if(HwDeviceExtension->jChipType < SIS_315H) {
+          			VCLKIndex &= 0x3f;
+				if( (HwDeviceExtension->jChipType == SIS_630) &&
+				    (HwDeviceExtension->jChipRevision >= 0x30)) {
+				     if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
+				}
+			}
+        	}
+        }
+
+    } else {   /* If not programming CRT2 */
+
+        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));
+        VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+        if(ModeNo > 0x13) {
+             VCLKIndex = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+	     if(HwDeviceExtension->jChipType < SIS_315H) {
+                VCLKIndex &= 0x3f;
+		if(HwDeviceExtension->jChipType != SIS_630) {
+		   if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
+		}
+	     }
+        }
+    }
+
+  } else {       /*   LVDS  */
+
+    	VCLKIndex = CRT2Index;
+
+	if(SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
+
+	   if( (SiS_IF_DEF_CH70xx != 0) && (SiS_VBInfo & SetCRT2ToTV) ) {
+
+		VCLKIndex &= 0x1f;
+        	tempbx = 0;
+        	if(SiS_VBInfo & SetPALTV) tempbx += 2;
+        	if(SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+       		switch(tempbx) {
+          	   case 0: CHTVVCLKPtr = SiS_CHTVVCLKUNTSC;  break;
+         	   case 1: CHTVVCLKPtr = SiS_CHTVVCLKONTSC;  break;
+                   case 2: CHTVVCLKPtr = SiS_CHTVVCLKUPAL;   break;
+                   case 3: CHTVVCLKPtr = SiS_CHTVVCLKOPAL;   break;
+        	}
+        	VCLKIndex = CHTVVCLKPtr[VCLKIndex];
+
+	   } else if(SiS_VBInfo & SetCRT2ToLCD) {
+
+	        VCLKIndex >>= 6;
+     		if((SiS_LCDResInfo==Panel800x600) || (SiS_LCDResInfo==Panel320x480))
+     			VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
+     		else if(SiS_LCDResInfo==Panel1024x768)
+     			VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+     		else 	VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
+
+	   } else {
+
+	        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));
+                VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+                if(ModeNo > 0x13) {
+                     VCLKIndex = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+		     if( (HwDeviceExtension->jChipType == SIS_630) &&
+                         (HwDeviceExtension->jChipRevision >= 0x30) ) {
+		         	if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
+		     }
+	        }
+
+	   }
+
+	} else {  /* if not programming CRT2 */
+
+	   VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));
+           VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+           if(ModeNo > 0x13) {
+              VCLKIndex = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+              if(HwDeviceExtension->jChipType < SIS_315H) {
+	         if(HwDeviceExtension->jChipType != SIS_630) {
+		        if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
+	         }
+	      }
+	   }
+
+	}
+
+  }
+
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+    	VCLKIndex &= 0x3F;
+  }
+  return (VCLKIndex);
+}
+
+/* TW: Set 301 Palette address port registers */
+/* TW: Checked against 650/301LV BIOS */
+void
+SiS_SetGroup5(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+              USHORT ModeIdIndex)
+{
+
+  if((SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCDA))
+      return;
+
+  if(SiS_ModeType == ModeVGA){
+    if(!(SiS_VBInfo & (SetInSlaveMode|LoadDACFlag))){
+      SiS_EnableCRT2();
+      SiS_LoadDAC2(ROMAddr,SiS_Part5Port,ModeNo,ModeIdIndex);
+    }
+  }
+  return;
+}
+
+/* TW: Checked against 650/301LV BIOS */
+void
+SiS_LoadDAC2(UCHAR *ROMAddr,USHORT SiS_Part5Port,
+             USHORT ModeNo,USHORT ModeIdIndex)
+{
+   USHORT data,data2;
+   USHORT time,i,j,k;
+   USHORT m,n,o;
+   USHORT si,di,bx,dl;
+   USHORT al,ah,dh;
+   USHORT *table=0;
+   USHORT Pindex,Pdata,modeflag;
+
+/* if(SiS_SetFlag & SetDispDevSwitchFlag) return;  - TW: Not needed */
+
+   if(ModeNo <= 0x13)
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+   else
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
 
-	SiS_SetReg1 (SiS_Part3Port, 0x00, 0x00);
-	if (SiS_VBInfo & SetPALTV) {
-		SiS_SetReg1 (SiS_Part3Port, 0x13, 0xFA);
-		SiS_SetReg1 (SiS_Part3Port, 0x14, 0xC8);
-	} else {
-		SiS_SetReg1 (SiS_Part3Port, 0x13, 0xF6);
-		SiS_SetReg1 (SiS_Part3Port, 0x14, 0xBF);
-	}
-#ifdef CONFIG_FB_SIS_300
-	/*add PALMN */
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-			temp = temp & 0x01;
-			if (temp) {
-				temp1 = SiS_GetReg1 (SiS_P3d4, 0x35);
-				temp1 = temp1 & 0x40;
-				if (temp1) {
-					SiS_SetReg1 (SiS_Part3Port, 0x13, 0xFA);
-					SiS_SetReg1 (SiS_Part3Port, 0x14, 0xC8);
-					SiS_SetReg1 (SiS_Part3Port, 0x3D, 0xA8);
-				}
-			}
-		}
-	}
-	/*end add */
+#if 0
+   if(!(ds:489 & 0x08)) {
 #endif
-#ifdef CONFIG_FB_SIS_315
-/*add PALMN*/
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-		temp = temp & 0x01;
-		if (temp) {
-			temp1 = SiS_GetReg1 (SiS_P3d4, 0x38);
-			temp1 = temp1 & 0x40;
-			if (temp1) {
-				SiS_SetReg1 (SiS_Part3Port, 0x13, 0xFA);
-				SiS_SetReg1 (SiS_Part3Port, 0x14, 0xC8);
-				SiS_SetReg1 (SiS_Part3Port, 0x3D, 0xA8);
-			}
-		}
+
+	Pindex = SiS_Part5Port;
+	Pdata = SiS_Part5Port + 1;
+	data = modeflag & DACInfoFlag;
+	time = 64;
+	if(data == 0x00) table = SiS_MDA_DAC;
+	if(data == 0x08) table = SiS_CGA_DAC;
+	if(data == 0x10) table = SiS_EGA_DAC;
+	if(data == 0x18) {
+	   time = 256;
+	   table = SiS_VGA_DAC;
+	}
+
+	if(time == 256) j = 16;
+	else j = time;
+
+	SiS_SetReg3(Pindex,0x00);
+
+	for(i=0; i<j; i++) {
+	   data = table[i];
+	   for(k=0; k<3; k++) {
+		data2 = 0;
+		if(data & 0x01) data2 = 0x2A;
+		if(data & 0x02) data2 += 0x15;
+		data2 <<= 2;   			/* TW: New from 650/301LV BIOS */
+		SiS_SetReg3(Pdata,data2);
+		data >>= 2;
+	   }
 	}
-	/*end add */
+
+	if(time == 256) {
+	   for(i=16;i<32;i++) {
+		data = table[i];
+		data <<= 2;   			/* TW: New from 650/301LV BIOS */
+		for(k=0; k<3; k++) SiS_SetReg3(Pdata,data);
+	   }
+           si = 32;
+           for(m=0; m<9; m++) {
+             di = si;
+             bx = si + 0x04;
+             dl = 0;
+             for(n=0; n<3; n++) {
+                for(o=0; o<5; o++) {
+                  dh = table[si];
+                  ah = table[di];
+                  al = table[bx];
+                  si++;
+                  SiS_WriteDAC2(Pdata,dl,ah,al,dh);
+                }         /* for 5 */
+                si = si - 2;
+                for(o=0; o<3; o++) {
+                  dh = table[bx];
+                  ah = table[di];
+                  al = table[si];
+                  si--;
+                  SiS_WriteDAC2(Pdata,dl,ah,al,dh);
+                }         /* for 3 */
+                dl++;
+             }            /* for 3 */
+             si = si + 5;
+           }               /* for 9 */
+        }
+#if 0
+    } /* ds:489 & 0x08 */
 #endif
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		tempdi = SiS_HiTVGroup3Data;
-		if (SiS_SetFlag & TVSimuMode) {
-			tempdi = SiS_HiTVGroup3Simu;
-			if (!(modeflag & Charx8Dot)) {
-				tempdi = SiS_HiTVGroup3Text;
-			}
-		}
-		for (i = 0; i <= 0x3E; i++) {
-			SiS_SetReg1 (SiS_Part3Port, i, tempdi[i]);
-		}
-	}
-	return;
 }
 
+/* TW: Checked against 650/301LV BIOS */
 void
-SiS_SetGroup4 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-	       USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-	       PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_WriteDAC2(USHORT Pdata, USHORT dl, USHORT ah, USHORT al, USHORT dh)
 {
-	USHORT tempax, tempcx, tempbx, modeflag, temp, temp2, push1;
-	ULONG tempebx, tempeax, templong;
+  USHORT temp;
+  USHORT bh,bl;
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-	}
-	temp = SiS_RVBHCFACT;
-	SiS_SetReg1 (SiS_Part4Port, 0x13, temp);
+  bh = ah;
+  bl = al;
+  if(dl != 0) {
+    temp = bh;
+    bh = dh;
+    dh = temp;
+    if(dl == 1) {
+       temp = bl;
+       bl = dh;
+       dh = temp;
+    } else {
+       temp = bl;
+       bl = bh;
+       bh = temp;
+    }
+  }
+  dh <<= 2;   				/* TW: New from 650/301LV BIOS */
+  bh <<= 2;   				/* TW: New from 650/301LV BIOS */
+  bl <<= 2;   				/* TW: New from 650/301LV BIOS */
+  SiS_SetReg3(Pdata,(USHORT)dh);
+  SiS_SetReg3(Pdata,(USHORT)bh);
+  SiS_SetReg3(Pdata,(USHORT)bl);
+}
+
+/* TW: Checked against 650/LVDS and 630/301B BIOS */
+void
+SiS_ModCRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT temp,tempah,i,modeflag,j;
+  USHORT ResInfo,DisplayType;
+  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+
+  if(ModeNo <= 0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+
+  temp = SiS_GetLVDSCRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                            &ResInfo,&DisplayType);
+
+  if(temp == 0) return;
+
+  /* TW: Inserted from 630/LVDS BIOS */
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+     if(SiS_SetFlag & CRT2IsVGA) return;
+  }
+
+  switch(DisplayType) {
+    case 0 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;           break;
+    case 1 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;          break;
+    case 2 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;         break;
+    case 3 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;         break;
+    case 4 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;        break;
+    case 5 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;       break;
+    case 6 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;           break;
+    case 7 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;          break;
+    case 8 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;         break;
+    case 9 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;         break;
+    case 10: LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;        break;
+    case 11: LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;       break;
+    case 12: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1;           break;
+    case 13: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1_H;         break;
+    case 14: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1;         break;
+    case 15: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1_H;       break;
+    case 16: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2;         break;
+    case 17: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2_H;       break;
+    case 18: LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
+    case 19: LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
+    case 20: LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;                break;
+    case 21: LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;                break;
+    case 22: LVDSCRT1Ptr = SiS_LVDSCRT1320x480_1;           break; /* FSTN */
+    case 23: LVDSCRT1Ptr = SiS_LVDSCRT11024x600_1;          break;
+    case 24: LVDSCRT1Ptr = SiS_LVDSCRT11024x600_1_H;        break;
+    case 25: LVDSCRT1Ptr = SiS_LVDSCRT11024x600_2;          break;
+    case 26: LVDSCRT1Ptr = SiS_LVDSCRT11024x600_2_H;        break;
+    case 27: LVDSCRT1Ptr = SiS_LVDSCRT11152x768_1;          break;
+    case 28: LVDSCRT1Ptr = SiS_LVDSCRT11152x768_1_H;        break;
+    case 29: LVDSCRT1Ptr = SiS_LVDSCRT11152x768_2;          break;
+    case 30: LVDSCRT1Ptr = SiS_LVDSCRT11152x768_2_H;        break;
+  }
+
+  SiS_SetRegAND(SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
+
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
+  SiS_SetReg1(SiS_P3d4,0x00,tempah);
+
+  for(i=0x02,j=1;i<=0x05;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x06,j=5;i<=0x07;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x10,j=7;i<=0x11;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x15,j=9;i<=0x16;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x0A,j=11;i<=0x0C;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3c4,i,tempah);
+  }
+
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah &= 0xE0;
+  SiS_SetRegANDOR(SiS_P3c4,0x0E,0x1f,tempah);     	/* TW: Modfied (650/LVDS); Was SetReg(tempah) */
+
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah &= 0x01;
+  tempah <<= 5;
+  if(modeflag & DoubleScanMode){
+    	tempah |= 0x080;
+  }
+  SiS_SetRegANDOR(SiS_P3d4,0x09,~0x020,tempah);
+
+  /* TW: Inserted from 650/LVDS BIOS */
+  if(SiS_VBInfo & SetCRT2ToTV) {
+     if(modeflag & HalfDCLK)
+        SiS_SetRegAND(SiS_P3d4,0x11,0x7f);
+  }
 
-	tempbx = SiS_RVBHCMAX;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part4Port, 0x14, temp);
-	temp2 = ((tempbx & 0xFF00) >> 8) << 7;
-
-	tempcx = SiS_VGAHT - 1;
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part4Port, 0x16, temp);
-	temp = ((tempcx & 0xFF00) >> 8) << 3;
-	temp2 = temp | temp2;
-
-	tempcx = SiS_VGAVT - 1;
-	if (!(SiS_VBInfo & SetCRT2ToTV)) {
-		tempcx = tempcx - 5;
-	}
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part4Port, 0x17, temp);
-	temp = temp2 | ((tempcx & 0xFF00) >> 8);
-	SiS_SetReg1 (SiS_Part4Port, 0x15, temp);
-
-	tempcx = SiS_VBInfo;
-	tempbx = SiS_VGAHDE;
-	if (modeflag & HalfDCLK) {
-		tempbx = tempbx >> 1;
-	}
-	if (tempcx & SetCRT2ToHiVisionTV) {
-		temp = 0xA0;
-		if (tempbx != 1024) {
-			temp = 0xC0;
-			if (tempbx != 1280)
-				temp = 0;
-		}
-	} else if ((tempcx & SetCRT2ToTV) && (SiS_VGAHDE == 1024)) {	/*301b */
-		temp = 0xA0;
-	} else {
-		temp = 0x80;
-		if (SiS_VBInfo & SetCRT2ToLCD) {
-			temp = 0;
-			if (tempbx > 800)
-				temp = 0x60;
-		}
-	}
-	if (SiS_LCDResInfo != Panel1280x1024)
-		temp = temp | 0x0A;
-	SiS_SetRegANDOR (SiS_Part4Port, 0x0E, ~0xEF, temp);
-
-	tempebx = SiS_VDE;
-	if (tempcx & SetCRT2ToHiVisionTV) {
-		/* if(!(tempax&0xE000)) tempbx=tempbx>>1; */
-		if (!(temp & 0xE000))
-			tempbx = tempbx >> 1;	/* alan ???? */
+  return;
+}
 
-	}
+#if 0 /* TW: Unused */
+/*301b*/
+void
+SiS_CHACRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex)
+{
+  USHORT temp,tempah,i,modeflag,j;
+  USHORT ResInfo,DisplayType;
+  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+  }
+
+  temp=SiS_GetLVDSCRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                       &ResInfo,&DisplayType);
+  if(temp==0){
+    return;
+  }
+
+  switch(DisplayType) {
+    case 0 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;           break;
+    case 1 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;          break;
+    case 2 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;         break;
+    case 3 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;         break;
+    case 4 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;        break;
+    case 5 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;       break;
+    case 6 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;           break;
+    case 7 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;          break;
+    case 8 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;         break;
+    case 9 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;         break;
+    case 10: LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;        break;
+    case 11: LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;       break;
+    case 12: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1;           break;
+    case 13: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1_H;         break;
+    case 14: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1;         break;
+    case 15: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1_H;       break;
+    case 16: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2;         break;
+    case 17: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2_H;       break;
+    case 18: LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
+    case 19: LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
+    case 20: LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;                break;
+    case 21: LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;                break;
+    case 22: LVDSCRT1Ptr = SiS_LVDSCRT1320x480_1;           break; /* FSTN */
+  }
+
+  tempah=(UCHAR)SiS_GetReg1(SiS_P3d4,0x11);                        /*unlock cr0-7  */
+  tempah=tempah&0x7F;
+  SiS_SetReg1(SiS_P3d4,0x11,tempah);
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
+  SiS_SetReg1(SiS_P3d4,0x0,tempah);
+  for(i=0x02,j=1;i<=0x05;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x06,j=5;i<=0x07;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x10,j=7;i<=0x11;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x15,j=9;i<=0x16;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+
+  for(i=0x0A,j=11;i<=0x0C;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3c4,i,tempah);
+  }
+
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah=tempah&0x0E0;
+  SiS_SetReg1(SiS_P3c4,0x0E,tempah);
+
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah=tempah&0x01;
+  tempah=tempah<<5;
+  if(modeflag&DoubleScanMode){
+    	tempah=tempah|0x080;
+  }
+  SiS_SetRegANDOR(SiS_P3d4,0x09,~0x020,tempah);
+  return;
+}
+/*add for LCDA*/
+#endif
 
-	tempcx = SiS_RVBHRS;
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part4Port, 0x18, temp);
-
-	tempebx = tempebx;
-	tempeax = SiS_VGAVDE;
-	tempcx = tempcx | 0x04000;
-/*tempeax=tempeax-tempebx;  */
-	if (tempeax <= tempebx) {
-		tempcx = ((tempcx & 0xFF00) ^ 0x4000) | (tempcx & 0x00ff);
-		tempeax = SiS_VGAVDE;
-	}
-
-	else {
-		tempeax = tempeax - tempebx;
-	}
-
-	push1 = tempcx;
-	templong = (tempeax * 256 * 1024) % tempebx;
-	tempeax = (tempeax * 256 * 1024) / tempebx;
-	tempebx = tempeax;
-	if (templong != 0) {
-		tempebx++;
-	}
-	tempcx = push1;
-	temp = (USHORT) (tempebx & 0x000000FF);
-	SiS_SetReg1 (SiS_Part4Port, 0x1B, temp);
-	temp = (USHORT) ((tempebx & 0x0000FF00) >> 8);
-	SiS_SetReg1 (SiS_Part4Port, 0x1A, temp);
-	tempbx = (USHORT) (tempebx >> 16);
-	temp = tempbx & 0x00FF;
-	temp = temp << 4;
-	temp = temp | ((tempcx & 0xFF00) >> 8);
-	SiS_SetReg1 (SiS_Part4Port, 0x19, temp);
-	/*301b */
-
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		temp = 0x0028;
-		SiS_SetReg1 (SiS_Part4Port, 0x1C, temp);
-		tempax = SiS_VGAHDE;
-		if (modeflag & HalfDCLK) {
-			tempax = tempax >> 1;
-		}
-		if (SiS_VBInfo & (SetCRT2ToLCD)) {
-			if (tempax > 800)
-				tempax = tempax - 800;
-		}
-		tempax = tempax - 1;
+BOOLEAN
+SiS_GetLCDACRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
+		   USHORT *DisplayType)
+ {
+  USHORT tempbx=0,modeflag=0;
+  USHORT CRT2CRTC=0;
 
-		if (SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
-			if (SiS_VGAHDE > 800) {
-				if (SiS_VGAHDE == 1024)
-					tempax = (tempax * 25 / 32) - 1;
-				else
-					tempax = (tempax * 20 / 32) - 1;
-			}
-		}
-		temp = (tempax & 0xFF00) >> 8;
-		temp = ((temp & 0x0003) << 4);
-		SiS_SetReg1 (SiS_Part4Port, 0x1E, temp);
-		temp = (tempax & 0x00FF);
-		SiS_SetReg1 (SiS_Part4Port, 0x1D, temp);
-
-		if (SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
-			if (SiS_VGAHDE > 800) {
-				SiS_SetRegOR (SiS_Part4Port, 0x1E, 0x08);
-			}
-		}
-		temp = 0x0036;
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			temp = temp | 0x0001;
-		}
-		SiS_SetRegANDOR (SiS_Part4Port, 0x1F, 0x00C0, temp);
-		tempbx = (SiS_HT / 2) - 2;
-		temp = ((tempbx & 0x0700) >> 8) << 3;
-		SiS_SetRegANDOR (SiS_Part4Port, 0x21, 0x00C0, temp);
-		temp = tempbx & 0x00FF;
-		SiS_SetReg1 (SiS_Part4Port, 0x22, temp);
-	}
-/*end 301b*/
-	SiS_SetCRT2VCLK (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-			 RefreshRateTableIndex, HwDeviceExtension);
-}
+  if(ModeNo<=0x13) {
+  	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  	CRT2CRTC = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+  	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  	CRT2CRTC = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
 
-void
-SiS_SetCRT2VCLK (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		 USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT vclkindex;
-	USHORT tempah, temp1;
-
-	vclkindex =
-	    SiS_GetVCLK2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-			     RefreshRateTableIndex, HwDeviceExtension);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		tempah = SiS_VBVCLKData[vclkindex].Part4_A;
-		SiS_SetReg1 (SiS_Part4Port, 0x0A, tempah);
-		tempah = SiS_VBVCLKData[vclkindex].Part4_B;
-		SiS_SetReg1 (SiS_Part4Port, 0x0B, tempah);
-	} else {
-		SiS_SetReg1 (SiS_Part4Port, 0x0A, 0x01);
-		tempah = SiS_VBVCLKData[vclkindex].Part4_B;
-		SiS_SetReg1 (SiS_Part4Port, 0x0B, tempah);
-		tempah = SiS_VBVCLKData[vclkindex].Part4_A;
-		SiS_SetReg1 (SiS_Part4Port, 0x0A, tempah);
+  tempbx = SiS_LCDResInfo - PanelMinLVDS;
 
-	}
-	SiS_SetReg1 (SiS_Part4Port, 0x12, 0x00);
-	tempah = 0x08;
-	if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-		tempah = tempah | 0x020;
-	}
-	temp1 = SiS_GetReg1 (SiS_Part4Port, 0x12);
-	tempah = tempah | temp1;
-	SiS_SetReg1 (SiS_Part4Port, 0x12, tempah);
-}
+  if(SiS_LCDInfo & LCDNonExpanding) tempbx += 6;
 
-USHORT
-SiS_GetVCLK2Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT tempbx;
-#ifdef CONFIG_FB_SIS_300
-	USHORT LCDXlat1VCLK[4] = { VCLK65, VCLK65, VCLK65, VCLK65 };
-	USHORT LCDXlat2VCLK[4] = { VCLK108_2, VCLK108_2, VCLK108_2, VCLK108_2 };
-	USHORT LVDSXlat2VCLK[4] = { VCLK65, VCLK65, VCLK65, VCLK65 };
-	USHORT LVDSXlat3VCLK[4] = { VCLK65, VCLK65, VCLK65, VCLK65 };
-#else				/* SIS315H */
-	USHORT LCDXlat1VCLK[4] =
-	    { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, VCLK65 + 2 };
-	USHORT LCDXlat2VCLK[4] =
-	    { VCLK108_2 + 5, VCLK108_2 + 5, VCLK108_2 + 5, VCLK108_2 + 5 };
-	USHORT LVDSXlat2VCLK[4] =
-	    { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, VCLK65 + 2 };
-	USHORT LVDSXlat3VCLK[4] =
-	    { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, VCLK65 + 2 };
-#endif
-	USHORT LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 };
-	USHORT CRT2Index, VCLKIndex;
-	USHORT modeflag, resinfo;
-	UCHAR *CHTVVCLKPtr = NULL;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-		CRT2Index = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		CRT2Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
+  if(modeflag & HalfDCLK) tempbx += 3;
 
-	if (SiS_IF_DEF_LVDS == 0) {
-		CRT2Index = CRT2Index >> 6;	/*  for LCD */
-		if ((SiS_VBInfo & SetCRT2ToLCD) || (SiS_VBInfo & SetCRT2ToLCDA)) {	/*301b */
-			if (SiS_LCDResInfo != Panel1024x768) {
-				VCLKIndex = LCDXlat2VCLK[CRT2Index];
-			} else {
-				VCLKIndex = LCDXlat1VCLK[CRT2Index];
-			}
-		} else {	/* for TV */
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				if (SiS_IF_DEF_HiVision == 1) {
-					if (SiS_SetFlag & RPLLDIV2XO) {
-						VCLKIndex = HiTVVCLKDIV2;
-						if (HwDeviceExtension->
-						    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-							VCLKIndex += 25;	/* for chip315  */
-						}
-					} else {
-						VCLKIndex = HiTVVCLK;
-						if (HwDeviceExtension->
-						    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-							VCLKIndex += 25;	/* for chip315  */
-						}
-					}
-					if (SiS_SetFlag & TVSimuMode) {
-						if (modeflag & Charx8Dot) {
-							VCLKIndex =
-							    HiTVSimuVCLK;
-							if (HwDeviceExtension->
-							    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-								VCLKIndex += 25;	/* for chip315  */
-							}
-						} else {
-							VCLKIndex =
-							    HiTVTextVCLK;
-							if (HwDeviceExtension->
-							    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-								VCLKIndex += 25;	/* for chip315  */
-							}
-						}
-					}
-				} else {
-					if (SiS_VBInfo & SetCRT2ToTV) {
-						if (SiS_SetFlag & RPLLDIV2XO) {
-							VCLKIndex = TVVCLKDIV2;
-							if (HwDeviceExtension->
-							    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-								VCLKIndex += 25;	/* for chip315  */
-							}
-						} else {
-							VCLKIndex = TVVCLK;
-							if (HwDeviceExtension->
-							    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-								VCLKIndex += 25;	/* for chip315  */
-							}
-						}
-					}
-				}
-			} else {	/* for CRT2 */
-				VCLKIndex =
-				    (UCHAR) SiS_GetReg2 ((USHORT) (SiS_P3ca + 0x02));	/*  Port 3cch */
-				VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-				if (ModeNo > 0x13) {
-					VCLKIndex =
-					    SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;	/* di+Ext_CRTVCLK */
-					VCLKIndex = VCLKIndex & 0x3f;
-				}
-			}
-		}
-	} else {		/*   LVDS  */
-		if (ModeNo <= 0x13)
-			VCLKIndex = CRT2Index;
-		else
-			VCLKIndex = CRT2Index;
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (!(SiS_VBInfo & SetCRT2ToLCD)) {
-				VCLKIndex = VCLKIndex & 0x1f;
-				tempbx = 0;
-				if (SiS_VBInfo & SetPALTV)
-					tempbx = tempbx + 2;
-				if (SiS_VBInfo & SetCHTVOverScan)
-					tempbx = tempbx + 1;
-				switch (tempbx) {
-				case 0:
-					CHTVVCLKPtr = SiS_CHTVVCLKUNTSC;
-					break;
-				case 1:
-					CHTVVCLKPtr = SiS_CHTVVCLKONTSC;
-					break;
-				case 2:
-					CHTVVCLKPtr = SiS_CHTVVCLKUPAL;
-					break;
-				case 3:
-					CHTVVCLKPtr = SiS_CHTVVCLKOPAL;
-					break;
-				}
-				VCLKIndex = CHTVVCLKPtr[VCLKIndex];
-			}
-		} else {
-			VCLKIndex = VCLKIndex >> 6;
-			if (SiS_LCDResInfo == Panel800x600)
-				VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
-			else if (SiS_LCDResInfo == Panel1024x768)
-				VCLKIndex = LVDSXlat2VCLK[VCLKIndex];
-			else
-				VCLKIndex = LVDSXlat3VCLK[VCLKIndex];
-		}
-	}
-/*VCLKIndex=VCLKIndex&0x3F;   */
-	if (HwDeviceExtension->jChipType < SIS_315H) {	/* for300 serial */
-		VCLKIndex = VCLKIndex & 0x3F;
-	}
-	return (VCLKIndex);
+  *ResInfo = CRT2CRTC & 0x3F;
+  *DisplayType = tempbx;
+
+  return 1;
 }
 
+/* TW: Checked against 650/LVDS BIOS: modified for new panel resolutions */
+BOOLEAN
+SiS_GetLVDSCRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
+		   USHORT *DisplayType)
+ {
+  USHORT tempbx,modeflag=0;
+  USHORT Flag,CRT2CRTC;
+
+  if(!(SiS_VBInfo & SetCRT2ToLCDA)) {                    /* TW: Inserted from 650/LVDS BIOS */
+      if(!(SiS_VBInfo & SetInSlaveMode)) return 0;
+  }							 /* TW: Inserted from 650/LVDS BIOS */
+
+  if(ModeNo <= 0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	CRT2CRTC = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	CRT2CRTC = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+
+  Flag = 1;
+  tempbx = 0;
+  if(SiS_IF_DEF_CH70xx != 0) {
+    if(!(SiS_VBInfo & SetCRT2ToLCD)) {
+      Flag = 0;
+      tempbx = 18;
+      if(SiS_VBInfo & SetPALTV) tempbx += 2;
+      if(SiS_VBInfo & SetCHTVOverScan) tempbx++;
+    }
+  }
+  if(Flag) {
+    tempbx = SiS_LCDResInfo;
+    tempbx -= PanelMinLVDS;
+    if(SiS_LCDResInfo <= Panel1280x1024) {
+       if(SiS_LCDInfo & LCDNonExpanding) tempbx += 6;
+       if(modeflag & HalfDCLK) tempbx += 3;
+    } else {
+       if(SiS_LCDResInfo == Panel1400x1050) {
+           tempbx = 14;
+	   if(SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+	   if(modeflag & HalfDCLK) tempbx++;
+       } else if(SiS_LCDInfo & 0x0100) {
+           tempbx = 12;
+	   if(modeflag & HalfDCLK) tempbx++;
+       } else if(SiS_LCDResInfo == Panel1024x600) {
+           tempbx = 23;
+	   if(SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+	   if(modeflag & HalfDCLK) tempbx++;
+       } else if(SiS_LCDResInfo == Panel1152x768) {
+           tempbx = 27;
+	   if(SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+	   if(modeflag & HalfDCLK) tempbx++;
+       }
+    }
+  }
+  if(SiS_IF_DEF_FSTN){
+     if(SiS_LCDResInfo==Panel320x480){
+       tempbx=22;
+     }
+  }
+  *ResInfo = CRT2CRTC & 0x3F;
+  *DisplayType = tempbx;
+  return 1;
+}
+
+/* TW: Checked against 650/LVDS (1.10a, 1.10.07), 630/301B (I/II) and 630/LVDS BIOS */
 void
-SiS_SetGroup5 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-	       USHORT ModeIdIndex)
+SiS_SetCRT2ECLK(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+           USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT Pindex, Pdata;
+  USHORT tempah,tempal,pushax;
+  USHORT vclkindex=0;
 
-	Pindex = SiS_Part5Port;
-	Pdata = SiS_Part5Port + 1;
-	if (SiS_ModeType == ModeVGA) {
-		if (!
-		    (SiS_VBInfo &
-		     (SetInSlaveMode | LoadDACFlag | CRT2DisplayFlag))) {
-			SiS_EnableCRT2 ();
-/*    LoadDAC2(ROMAddr,SiS_Part5Port,ModeNo,ModeIdIndex);  */
-		}
-	}
-	return;
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+     if(SiS_VBType & VB_SIS301BLV302BLV) {
+        if(!(SiS_VBInfo & SetCRT2ToLCD)) return;
+     }
+  }
+
+  if((SiS_LCDResInfo == Panel640x480) || (SiS_IF_DEF_TRUMPION == 1)) {
+	SiS_SetFlag &= (~ProgrammingCRT2);
+        tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+    	tempal &= 0x3F;
+	if(tempal == 2) RefreshRateTableIndex--;
+	vclkindex = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
+                               RefreshRateTableIndex,HwDeviceExtension);
+	SiS_SetFlag |= ProgrammingCRT2;
+  } else {
+        vclkindex = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
+                               RefreshRateTableIndex,HwDeviceExtension);
+  }
+
+  tempal = 0x02B;
+  if(!(SiS_VBInfo & SetCRT2ToLCDA)) {
+     if(!(SiS_VBInfo & SetInSlaveMode)) {
+    	tempal += 3;
+     }
+  }
+  SiS_SetReg1(SiS_P3c4,0x05,0x86);
+  pushax = tempal;
+  SiS_SetReg1(SiS_P3c4,0x31,0x20);
+  tempah = SiS_VCLKData[vclkindex].SR2B;
+  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  tempal++;
+  tempah = SiS_VCLKData[vclkindex].SR2C;
+  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  SiS_SetReg1(SiS_P3c4,0x31,0x10);
+  tempal = pushax;
+  tempah = SiS_VCLKData[vclkindex].SR2B;
+  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  tempal++;
+  tempah = SiS_VCLKData[vclkindex].SR2C;
+  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  SiS_SetReg1(SiS_P3c4,0x31,0x00);
+  tempal = pushax;
+  tempah = SiS_VCLKData[vclkindex].SR2B;
+  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  tempal++;
+  tempah = SiS_VCLKData[vclkindex].SR2C;
+  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  return;
+}
+
+#if 0  /* TW: Not used */
+void
+SiS_SetDefCRT2ExtRegs(USHORT BaseAddr)
+{
+  USHORT  temp;
+
+  if(SiS_IF_DEF_LVDS==0) {
+    SiS_SetReg1(SiS_Part1Port,0x02,0x40);
+    SiS_SetReg1(SiS_Part4Port,0x10,0x80);
+    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x16);
+    temp &= 0xC3;
+    SiS_SetReg1(SiS_P3d4,0x35,temp);
+  } else {
+    SiS_SetReg1(SiS_P3d4,0x32,0x02);
+    SiS_SetReg1(SiS_Part1Port,0x02,0x00);
+  }
 }
+#endif
+
+/* TW: Start of Chrontel 70xx functions ---------------------- */
 
+/* Set-up the Chrontel Registers */
 void
-SiS_LoadDAC2 (ULONG ROMAddr, USHORT SiS_Part5Port, USHORT ModeNo,
-	      USHORT ModeIdIndex)
+SiS_SetCHTVReg(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+               USHORT RefreshRateTableIndex)
 {
-	USHORT data, data2;
-	USHORT time, i, j, k;
-	USHORT m, n, o;
-	USHORT si, di, bx, dl;
-	USHORT al, ah, dh;
-	USHORT *table = 0;
-	USHORT Pindex, Pdata, modeflag;
+  USHORT temp,tempbx,tempcl;
+  USHORT TVType,resindex;
+  SiS_CHTVRegDataStruct *CHTVRegData=NULL;
+
+  if(ModeNo<=0x13)
+    	tempcl = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  else
+    	tempcl = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+  TVType = 0;
+  if(SiS_VBInfo & SetPALTV) TVType += 2;
+  if(SiS_VBInfo & SetCHTVOverScan) TVType += 1;
+  switch(TVType) {
+    	case 0: CHTVRegData = SiS_CHTVReg_UNTSC; break;
+    	case 1: CHTVRegData = SiS_CHTVReg_ONTSC; break;
+    	case 2: CHTVRegData = SiS_CHTVReg_UPAL;  break;
+    	case 3: CHTVRegData = SiS_CHTVReg_OPAL;  break;
+  }
+  resindex = tempcl & 0x3F;
+
+  if(SiS_IF_DEF_CH70xx == 1) {
+
+     /* Chrontel 7005 */
+
+     /* TW: We don't support modes >800x600 */
+     if (resindex > 5) return;
+
+     if(SiS_VBInfo & SetPALTV) {
+    	SiS_SetCH700x(0x4304);  /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
+    	SiS_SetCH700x(0x6909);	/* TW: Black level for PAL (105)*/
+     } else {
+    	SiS_SetCH700x(0x0304);  /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
+    	SiS_SetCH700x(0x7109);	/* TW: Black level for NTSC (113)*/
+     }
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-	}
+     temp = CHTVRegData[resindex].Reg[0];
+     tempbx=((temp&0x00FF)<<8)|0x00;	/* TW: Mode register */
+     SiS_SetCH700x(tempbx);
+     temp = CHTVRegData[resindex].Reg[1];
+     tempbx=((temp&0x00FF)<<8)|0x07;	/* TW: Start active video register */
+     SiS_SetCH700x(tempbx);
+     temp = CHTVRegData[resindex].Reg[2];
+     tempbx=((temp&0x00FF)<<8)|0x08;	/* TW: Position overflow register */
+     SiS_SetCH700x(tempbx);
+     temp = CHTVRegData[resindex].Reg[3];
+     tempbx=((temp&0x00FF)<<8)|0x0A;	/* TW: Horiz Position register */
+     SiS_SetCH700x(tempbx);
+     temp = CHTVRegData[resindex].Reg[4];
+     tempbx=((temp&0x00FF)<<8)|0x0B;	/* TW: Vertical Position register */
+     SiS_SetCH700x(tempbx);
+
+     /* TW: 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(0x2801);
+
+     /* TW: 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)
+	    high bandwidth Chroma Filter (S5-4=11)
+	    =00110001=0x31
+     */
+     SiS_SetCH700x(0xb103);       /* old: 3103 */
 
-	Pindex = SiS_Part5Port;
-	Pdata = SiS_Part5Port + 1;
-	data = modeflag & DACInfoFlag;
-	time = 64;
-	if (data == 0x00)
-		table = SiS_MDA_DAC;
-	if (data == 0x08)
-		table = SiS_CGA_DAC;
-	if (data == 0x10)
-		table = SiS_EGA_DAC;
-	if (data == 0x18) {
-		time = 256;
-		table = SiS_VGA_DAC;
-	}
-	if (time == 256)
-		j = 16;
-	else
-		j = time;
+     /* TW: Register 0x3D does not exist in non-macrovision register map
+            (Maybe this is a macrovision register?)
+      */
+     /* SiS_SetCH70xx(0x003D); */
+
+     /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
+            all other bits a read-only. Macrovision?
+      */
+     SiS_SetCH70xxANDOR(0x0010,0x1F);
+
+     /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
+            contrast enhancement (set to 010 -> gain 2 Yout = 9/8*(Yin-57) )
+      */
+     SiS_SetCH70xxANDOR(0x0211,0xF8);
+
+     /* TW: Clear DSEN
+      */
+     SiS_SetCH70xxANDOR(0x001C,0xEF);
+
+     if(!(SiS_VBInfo&SetPALTV)) {		/* ---- NTSC ---- */
+       tempcl=tempcl&0x3F;
+       if(SiS_VBInfo&SetCHTVOverScan) {
+         if(tempcl==0x04) {   			/* 640x480 overscan: Mode 16 */
+      	   SiS_SetCH70xxANDOR(0x0020,0xEF);   	/* loop filter off */
+           SiS_SetCH70xxANDOR(0x0121,0xFE);       /* ACIV on, no need to set FSCI */
+         } else {
+           if(tempcl==0x05) {    			/* 800x600 overscan: Mode 23 */
+             SiS_SetCH70xxANDOR(0x0118,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
+             SiS_SetCH70xxANDOR(0x0C19,0xF0);
+             SiS_SetCH70xxANDOR(0x001A,0xF0);
+             SiS_SetCH70xxANDOR(0x001B,0xF0);
+             SiS_SetCH70xxANDOR(0x001C,0xF0);
+             SiS_SetCH70xxANDOR(0x001D,0xF0);
+             SiS_SetCH70xxANDOR(0x001E,0xF0);
+             SiS_SetCH70xxANDOR(0x001F,0xF0);
+             SiS_SetCH70xxANDOR(0x1020,0xEF);     /* Loop filter on for mode 23 */
+             SiS_SetCH70xxANDOR(0x0021,0xFE);     /* ACIV off, need to set FSCI */
+           }
+         }
+       } else {
+         if(tempcl==0x04) {     			/* ----- 640x480 underscan; Mode 17 */
+           SiS_SetCH70xxANDOR(0x0020,0xEF); 	/* loop filter off */
+           SiS_SetCH70xxANDOR(0x0121,0xFE);
+         } else {
+           if(tempcl==0x05) {   			/* ----- 800x600 underscan: Mode 24 */
+             SiS_SetCH70xxANDOR(0x0118,0xF0);   /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
+             SiS_SetCH70xxANDOR(0x0919,0xF0);	/* FSCI for mode 24 is 428,554,851 */
+             SiS_SetCH70xxANDOR(0x081A,0xF0);
+             SiS_SetCH70xxANDOR(0x0b1B,0xF0);
+             SiS_SetCH70xxANDOR(0x031C,0xF0);
+             SiS_SetCH70xxANDOR(0x0a1D,0xF0);
+             SiS_SetCH70xxANDOR(0x061E,0xF0);
+             SiS_SetCH70xxANDOR(0x031F,0xF0);
+             SiS_SetCH70xxANDOR(0x0020,0xEF);   /* loop filter off for mode 24 */
+             SiS_SetCH70xxANDOR(0x0021,0xFE);	/* ACIV off, need to set FSCI */
+           }
+         }
+       }
+     } else {				/* ---- PAL ---- */
+           /* TW: We don't play around with FSCI in PAL mode */
+         if (tempcl==0x04) {
+           SiS_SetCH70xxANDOR(0x0020,0xEF); 	/* loop filter off */
+           SiS_SetCH70xxANDOR(0x0121,0xFE);     /* ACIV on */
+         } else {
+           SiS_SetCH70xxANDOR(0x0020,0xEF); 	/* loop filter off */
+           SiS_SetCH70xxANDOR(0x0121,0xFE);     /* ACIV on */
+         }
+     }
 
-	SiS_SetReg3 (Pindex, 0x00);
+  } else {
 
-	for (i = 0; i < j; i++) {
-		data = table[i];
-		for (k = 0; k < 3; k++) {
-			data2 = 0;
-			if (data & 0x01)
-				data2 = 0x2A;
-			if (data & 0x02)
-				data2 = data2 + 0x15;
-			SiS_SetReg3 (Pdata, data2);
-			data = data >> 2;
-		}
-	}
+     /* Chrontel 7019 */
 
-	if (time == 256) {
-		for (i = 16; i < 32; i++) {
-			data = table[i];
-			for (k = 0; k < 3; k++)
-				SiS_SetReg3 (Pdata, data);
-		}
-		si = 32;
-		for (m = 0; m < 9; m++) {
-			di = si;
-			bx = si + 0x04;
-			dl = 0;
-			for (n = 0; n < 3; n++) {
-				for (o = 0; o < 5; o++) {
-					dh = table[si];
-					ah = table[di];
-					al = table[bx];
-					si++;
-					SiS_WriteDAC2 (Pdata, dl, ah, al, dh);
-				}	/* for 5 */
-				si = si - 2;
-				for (o = 0; o < 3; o++) {
-					dh = table[bx];
-					ah = table[di];
-					al = table[si];
-					si--;
-					SiS_WriteDAC2 (Pdata, dl, ah, al, dh);
-				}	/* for 3 */
-				dl++;
-			}	/* for 3 */
-			si = si + 5;
-		}		/* for 9 */
-	}
+     /* TW: We don't support modes >1024x768 */
+     if (resindex > 6) return;
+
+     temp = CHTVRegData[resindex].Reg[0];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x00;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[1];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x01;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[2];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x02;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[3];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x04;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[4];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x03;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[5];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x05;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[6];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x06;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[7];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x07;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[8];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x08;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[9];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x15;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[10];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x1f;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[11];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x0c;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[12];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x0d;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[13];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x0e;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[14];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x0f;
+     SiS_SetCH701x(tempbx);
+
+     temp = CHTVRegData[resindex].Reg[15];
+     tempbx=((temp & 0x00FF) <<8 ) | 0x10;
+     SiS_SetCH701x(tempbx);
+
+#if 0  /* TW: Not done in BIOS 1.10.07 */
+     SiS_SetCH701x(0x3848);
+     SiS_DDC2Delay(SiS_I2CDELAYSHORT * 2);
+     SiS_SetCH701x(0x1848);
+#endif
+  }
 }
 
 void
-SiS_WriteDAC2 (USHORT Pdata, USHORT dl, USHORT ah, USHORT al, USHORT dh)
-{
-	USHORT temp;
-	USHORT bh, bl;
-
-	bh = ah;
-	bl = al;
-	if (dl != 0) {
-		temp = bh;
-		bh = dh;
-		dh = temp;
-		if (dl == 1) {
-			temp = bl;
-			bl = dh;
-			dh = temp;
-		} else {
-			temp = bl;
-			bl = bh;
-			bh = temp;
-		}
-	}
-	SiS_SetReg3 (Pdata, (USHORT) dh);
-	SiS_SetReg3 (Pdata, (USHORT) bh);
-	SiS_SetReg3 (Pdata, (USHORT) bl);
+SiS_SetCHTVForLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d };
+  UCHAR table28b4[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+                        0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
+  UCHAR table28c0[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
+                        0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
+  UCHAR *tableptr = NULL;
+  USHORT tempbh;
+  int i;
+
+  if(SiS_LCDResInfo == Panel1400x1050) {
+      tableptr = table28c0;
+  } else {
+      tableptr = table28b4;
+  }
+  tempbh = SiS_GetCH701x(0x74);
+  if((tempbh == 0xf6) || (tempbh == 0xc7)) {
+     tempbh = SiS_GetCH701x(0x73);
+     if(tempbh == 0xc8) {
+        if(SiS_LCDResInfo != Panel1400x1050) return;
+     } else if(tempbh == 0xdb) {
+        if(SiS_LCDResInfo == Panel1400x1050) return;
+     }
+  }
+  for(i=0; i<0x0c; i++) {
+     SiS_SetCH701x((tableptr[i] << 8) | regtable[i]);
+  }
+  SiS_Chrontel19f2();
+  tempbh = SiS_GetCH701x(0x1e);			/* TW: NEW in BIOS 1.10.07 */
+  tempbh |= 0xc0;				/* TW: NEW in BIOS 1.10.07 */
+  SiS_SetCH701x((tempbh << 8) | 0x1e);		/* TW: NEW in BIOS 1.10.07 */
 }
 
+/* TW: Chrontel 701x functions ================================= */
+
 void
-SiS_SetCHTVReg (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		USHORT RefreshRateTableIndex)
+SiS_Chrontel19f2(void)
 {
-	USHORT temp, tempbx, tempcl;
-/*  USHORT CRT2CRTC; */
-	USHORT TVType, resindex;
-	SiS_CHTVRegDataStruct *CHTVRegData = NULL;
+  UCHAR regtable[]  = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
+  UCHAR table19e8[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+  UCHAR table19ed[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+  UCHAR *tableptr = NULL;
+  int i;
 
-	if (ModeNo <= 0x13) {
-		tempcl = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		tempcl = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-	TVType = 0;
-	if (SiS_VBInfo & SetPALTV)
-		TVType = TVType + 2;
-	if (SiS_VBInfo & SetCHTVOverScan)
-		TVType = TVType + 1;
-	switch (TVType) {
-	case 0:
-		CHTVRegData = SiS_CHTVReg_UNTSC;
-		break;
-	case 1:
-		CHTVRegData = SiS_CHTVReg_ONTSC;
-		break;
-	case 2:
-		CHTVRegData = SiS_CHTVReg_UPAL;
-		break;
-	case 3:
-		CHTVRegData = SiS_CHTVReg_OPAL;
-		break;
-	}
-	resindex = tempcl & 0x3F;
-
-	if (SiS_VBInfo & SetPALTV) {
-		SiS_SetCH7005 (0x4304);
-		SiS_SetCH7005 (0x6909);
-	} else {
-		SiS_SetCH7005 (0x0304);
-		SiS_SetCH7005 (0x7109);
-	}
+  if(SiS_LCDResInfo == Panel1400x1050) {
+      tableptr = table19ed;
+  } else {
+      tableptr = table19e8;
+  }
 
-	temp = CHTVRegData[resindex].Reg[0];
-	tempbx = ((temp & 0x00FF) << 8) | 0x00;
-	SiS_SetCH7005 (tempbx);
-	temp = CHTVRegData[resindex].Reg[1];
-	tempbx = ((temp & 0x00FF) << 8) | 0x07;
-	SiS_SetCH7005 (tempbx);
-	temp = CHTVRegData[resindex].Reg[2];
-	tempbx = ((temp & 0x00FF) << 8) | 0x08;
-	SiS_SetCH7005 (tempbx);
-	temp = CHTVRegData[resindex].Reg[3];
-	tempbx = ((temp & 0x00FF) << 8) | 0x0A;
-	SiS_SetCH7005 (tempbx);
-	temp = CHTVRegData[resindex].Reg[4];
-	tempbx = ((temp & 0x00FF) << 8) | 0x0B;
-	SiS_SetCH7005 (tempbx);
-
-	SiS_SetCH7005 (0x2801);
-	SiS_SetCH7005 (0x3103);
-	SiS_SetCH7005 (0x003D);
-	SiS_SetCHTVRegANDOR (0x0010, 0x1F);
-	SiS_SetCHTVRegANDOR (0x0211, 0xF8);
-	SiS_SetCHTVRegANDOR (0x001C, 0xEF);
-
-	if (!(SiS_VBInfo & SetPALTV)) {
-		/* tempcl=CRT2CRTC; */
-		tempcl = tempcl & 0x3F;
-		if (SiS_VBInfo & SetCHTVOverScan) {
-			if (tempcl == 0x04) {	/* 640x480   underscan */
-				SiS_SetCHTVRegANDOR (0x0020, 0xEF);
-				SiS_SetCHTVRegANDOR (0x0121, 0xFE);
-			} else {
-				if (tempcl == 0x05) {	/* 800x600  underscan */
-					SiS_SetCHTVRegANDOR (0x0118, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0C19, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001A, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001B, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001C, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001D, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001E, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001F, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0120, 0xEF);
-					SiS_SetCHTVRegANDOR (0x0021, 0xFE);
-				}
-			}
-		} else {
-			if (tempcl == 0x04) {	/* 640x480   overscan  */
-				SiS_SetCHTVRegANDOR (0x0020, 0xEF);
-				SiS_SetCHTVRegANDOR (0x0121, 0xFE);
-			} else {
-				if (tempcl == 0x05) {	/* 800x600   overscan */
-					SiS_SetCHTVRegANDOR (0x0118, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0F19, 0xF0);
-					SiS_SetCHTVRegANDOR (0x011A, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0C1B, 0xF0);
-					SiS_SetCHTVRegANDOR (0x071C, 0xF0);
-					SiS_SetCHTVRegANDOR (0x011D, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0C1E, 0xF0);
-					SiS_SetCHTVRegANDOR (0x071F, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0120, 0xEF);
-					SiS_SetCHTVRegANDOR (0x0021, 0xFE);
-				}
-			}
-		}
-	}
+  for(i=0; i<5; i++) {
+     SiS_SetCH701x((tableptr[i] << 8) | regtable[i]);
+  }
 }
 
 void
-SiS_SetCHTVRegANDOR (USHORT tempax, USHORT tempbh)
+SiS_Chrontel701xOn()
 {
-	USHORT tempal, tempah, tempbl;
+  USHORT temp;
 
-	tempal = tempax & 0x00FF;
-	tempah = (tempax >> 8) & 0x00FF;
-	tempbl = SiS_GetCH7005 (tempal);
-	tempbl = (((tempbl & tempbh) | tempah) << 8 | tempal);
-	SiS_SetCH7005 (tempbl);
+  if(SiS_IF_DEF_CH70xx == 2) {
+        temp = SiS_GetCH701x(0x66);
+        temp |= 0x20;
+	SiS_SetCH701x((temp << 8) | 0x66);
+  }
 }
 
 void
-SiS_SetCH7005 (USHORT tempbx)
-{
-	USHORT tempah, temp;
-
-	SiS_DDC_Port = 0x3c4;
-	SiS_DDC_Index = 0x11;
-	SiS_DDC_DataShift = 0x00;
-	SiS_DDC_DeviceAddr = 0xEA;
-
-	temp = 1;
-	for (; temp != 0;) {
-		SiS_SetSwitchDDC2 ();
-		SiS_SetStart ();
-		tempah = SiS_DDC_DeviceAddr;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-		tempah = tempbx & 0x00FF;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-		tempah = (tempbx & 0xFF00) >> 8;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-		SiS_SetStop ();
-	}
+SiS_Chrontel701xOn2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+  USHORT temp;
+
+  if(SiS_IF_DEF_CH70xx == 2) {
+     if(SiS_IsYPbPr(HwDeviceExtension, BaseAddr)) {
+        temp = SiS_GetCH701x(0x01);
+	temp &= 0x3f;
+	temp |= 0x80;
+	SiS_SetCH701x((temp << 8) | 0x01);
+     }
+     SiS_SetCH701x(0x2049);
+     temp = SiS_GetCH701x(0x49);
+     if(SiS_IsYPbPr(HwDeviceExtension, BaseAddr)) {
+        temp = SiS_GetCH701x(0x73);
+	temp |= 0x60;
+	SiS_SetCH701x((temp << 8) | 0x73);
+     }
+     /* TW: New from BIOS 1.10.07: */
+     temp = SiS_GetCH701x(0x47);
+     temp &= 0x7f;
+     SiS_SetCH701x((temp << 8) | 0x47);
+     SiS_LongDelay(2);
+     temp = SiS_GetCH701x(0x47);
+     temp |= 0x80;
+     SiS_SetCH701x((temp << 8) | 0x47);
+  }
 }
 
-USHORT
-SiS_GetCH7005 (USHORT tempbx)
+void
+SiS_Chrontel701xOff()
 {
-	USHORT tempah, temp;
+  USHORT temp;
 
-	SiS_DDC_Port = 0x3c4;
-	SiS_DDC_Index = 0x11;
-	SiS_DDC_DataShift = 0x00;
-	SiS_DDC_DeviceAddr = 0xEA;
-	SiS_DDC_ReadAddr = tempbx;
+  if(SiS_IF_DEF_CH70xx == 2) {
+        temp = SiS_GetCH701x(0x66);
+        temp &= 0xDF;
+	SiS_SetCH701x((temp << 8) | 0x66);
+  }
+}
 
-	for (;;) {
-		SiS_SetSwitchDDC2 ();
-		SiS_SetStart ();
-		tempah = SiS_DDC_DeviceAddr;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-		tempah = SiS_DDC_ReadAddr;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
+void
+SiS_Chrontel701xOff2()
+{
+  USHORT temp;
 
-		SiS_SetStart ();
-		tempah = SiS_DDC_DeviceAddr;
-		tempah = tempah | 0x01;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-		tempah = SiS_ReadDDC2Data (tempah);
-		SiS_SetStop ();
-		return (tempah);
-	}
+  if(SiS_IF_DEF_CH70xx == 2) {
+        SiS_LongDelay(2);
+	temp = SiS_GetCH701x(0x76);
+	temp &= 0xfc;
+	SiS_SetCH701x((temp << 8) | 0x76);
+	SiS_SetCH701x(0x0066);
+  }
 }
 
 void
-SiS_SetSwitchDDC2 (void)
+SiS_ChrontelFlip0x48()
 {
-	USHORT i;
-
-	SiS_SetSCLKHigh ();
-	for (i = 0; i < 1000; i++) {
-		SiS_GetReg1 (SiS_DDC_Port, 0x05);
-	}
-	SiS_SetSCLKLow ();
-	for (i = 0; i < 1000; i++) {
-		SiS_GetReg1 (SiS_DDC_Port, 0x05);
-	}
+     SiS_SetCH701x(0x1048);
+     SiS_LongDelay(1);
+     SiS_SetCH701x(0x1848);
 }
 
 void
-SiS_SetStart (void)
+SiS_ChrontelDoSomething4(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
+     USHORT temp;
 
-	SiS_SetSCLKLow ();
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x02);	/*  SetSDA(0x01); */
-	SiS_SetSCLKHigh ();
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x00);	/* SetSDA(0x00); */
-	SiS_SetSCLKHigh ();
+     SiS_SetCH701x(0xaf76);
+     temp = SiS_GetCH701x(0x49);
+     temp &= 1;
+     if(temp != 1) {
+	temp = SiS_GetCH701x(0x47);
+	temp &= 0x70;
+	SiS_SetCH701x((temp << 8) | 0x47);
+	SiS_LongDelay(3);
+	temp = SiS_GetCH701x(0x47);
+	temp |= 0x80;
+	SiS_SetCH701x((temp << 8) | 0x47);
+     }
 }
 
 void
-SiS_SetStop (void)
+SiS_ChrontelDoSomething3(USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                         USHORT BaseAddr)
 {
-	SiS_SetSCLKLow ();
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x00);	/*  SetSDA(0x00); */
-	SiS_SetSCLKHigh ();
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x02);	/* SetSDA(0x01); */
-	SiS_SetSCLKHigh ();
+     USHORT temp,temp1;
+
+     temp1 = 0;
+     temp = SiS_GetCH701x(0x61);
+     if(temp < 2) {
+          temp++;
+	  SiS_SetCH701x((temp << 8) | 0x61);
+	  temp1 = 1;
+     }
+     SiS_SetCH701x(0xac76);
+     temp = SiS_GetCH701x(0x66);
+     temp |= 0x5f;
+     SiS_SetCH701x((temp << 8) | 0x66);
+     if(ModeNo > 0x13) {
+         if(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr)) {
+	    SiS_GenericDelay(0x3ff);
+	 } else {
+	    SiS_GenericDelay(0x2ff);
+	 }
+     } else {
+         if(!temp1)
+	    SiS_GenericDelay(0x2ff);
+     }
+     temp = SiS_GetCH701x(0x76);
+     temp |= 0x03;
+     SiS_SetCH701x((temp << 8) | 0x76);
+     temp = SiS_GetCH701x(0x66);
+     temp &= 0x7f;
+     SiS_SetCH701x((temp << 8) | 0x66);
+     SiS_LongDelay(1);
+}
+
+void
+SiS_ChrontelDoSomething2(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+     USHORT temp,tempcl,tempch;
+
+     SiS_LongDelay(1);
+     tempcl = 3;
+     tempch = 0;
+
+     do {
+       temp = SiS_GetCH701x(0x66);
+       temp &= 0x04;
+       if(temp == 0x04) break;
+
+       SiS_SetCHTVForLCD(HwDeviceExtension, BaseAddr);
+
+       if(tempcl == 0) {
+           if(tempch == 3) break;
+	   SiS_ChrontelFlip0x48();
+	   tempcl = 3;
+	   tempch++;
+       }
+       tempcl--;
+       temp = SiS_GetCH701x(0x76);
+       temp &= 0xfb;
+       SiS_SetCH701x((temp << 8) | 0x76);
+       SiS_LongDelay(2);
+       temp = SiS_GetCH701x(0x76);
+       temp |= 0x04;
+       SiS_SetCH701x((temp << 8) | 0x76);
+       SiS_SetCH701x(0x6078);
+       SiS_LongDelay(2);
+    } while(0);
+
+    SiS_SetCH701x(0x0077);
+}
+
+void
+SiS_ChrontelDoSomething1(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                         USHORT BaseAddr)
+{
+     USHORT temp;
+
+     temp = SiS_GetCH701x(0x03);
+     temp |= 0x80;
+     temp &= 0xbf;
+     SiS_SetCH701x((temp << 8) | 0x03);
+
+     SiS_ChrontelFlip0x48();
+
+     SiS_ChrontelDoSomething2(HwDeviceExtension, BaseAddr);
+     
+     temp = SiS_GetReg1(SiS_P3d4,0x34);
+     SiS_ChrontelDoSomething3(temp, HwDeviceExtension, BaseAddr);
+
+     SiS_SetCH701x(0xaf76);
+}
+
+/* TW: End of Chrontel 701x functions ==================================== */
+
+/* TW: Generic Read/write routines for Chrontel ========================== */
+
+/* The Chrontel seems to be connected to the 630/730 via
+ * the 630/730's DDC port (which is used as a I2C port here).
+ *
+ * On 630(S)T chipset, the port changed from 0x11 to 0x0a
+ */
+
+void
+SiS_SetCH70xx(USHORT tempbx)
+{
+   if (SiS_IF_DEF_CH70xx == 1)
+      SiS_SetCH700x(tempbx);
+   else
+      SiS_SetCH701x(tempbx);
+}
+
+/* TW: Write to Chrontel 700x */
+/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
+void
+SiS_SetCH700x(USHORT tempbx)
+{
+  USHORT tempah,temp,i;
+
+  if(!(SiS_ChrontelInit)) {
+     SiS_DDC_Index = 0x11;		   /* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
+     SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
+     SiS_DDC_DataShift = 0x00;
+     SiS_DDC_DeviceAddr = 0xEA;  	   /* TW: DAB (Device Address Byte) */
+  }
+
+  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
+    SiS_SetSwitchDDC2();
+    if (SiS_SetStart()) continue;	/* TW: Set start condition */
+    tempah=SiS_DDC_DeviceAddr;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
+    if(temp) continue;			/* TW:    (ERROR: no ack) */
+    tempah=tempbx&0x00FF;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write RAB */
+    if(temp) continue;			/* TW:    (ERROR: no ack) */
+    tempah=(tempbx&0xFF00)>>8;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write data */
+    if(temp) continue;			/* TW:    (ERROR: no ack) */
+    if (SiS_SetStop()) continue;	/* TW: Set stop condition */
+    SiS_ChrontelInit = 1;
+    return;
+  }
+
+  if(!(SiS_ChrontelInit)) {
+     SiS_DDC_Index = 0x0a;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_DDC_Data  = 0x80;                 /* Bitmask in IndexReg for Data */
+     SiS_DDC_Clk   = 0x40;                 /* Bitmask in IndexReg for Clk */
+     SiS_DDC_DataShift = 0x00;
+     SiS_DDC_DeviceAddr = 0xEA;  		/* TW: DAB (Device Address Byte) */
+
+     for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
+       SiS_SetSwitchDDC2();
+       if (SiS_SetStart()) continue;		/* TW: Set start condition */
+       tempah=SiS_DDC_DeviceAddr;
+       temp=SiS_WriteDDC2Data(tempah);		/* TW: Write DAB (S0=0=write) */
+       if(temp) continue;			/* TW:    (ERROR: no ack) */
+       tempah=tempbx&0x00FF;
+       temp=SiS_WriteDDC2Data(tempah);		/* TW: Write RAB */
+       if(temp) continue;			/* TW:    (ERROR: no ack) */
+       tempah=(tempbx&0xFF00)>>8;
+       temp=SiS_WriteDDC2Data(tempah);		/* TW: Write data */
+       if(temp) continue;			/* TW:    (ERROR: no ack) */
+       if (SiS_SetStop()) continue;		/* TW: Set stop condition */
+       SiS_ChrontelInit = 1;
+       return;
+    }
+  }
+}
+
+/* TW: Write to Chrontel 701x */
+/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
+void
+SiS_SetCH701x(USHORT tempbx)
+{
+  USHORT tempah,temp,i;
+
+  /* TW: Toggle to DDC port */
+  SiS_SetRegOR(SiS_P3c4,0x38,0x20);
+
+  SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+  SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
+  SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
+  SiS_DDC_DataShift = 0x00;
+  SiS_DDC_DeviceAddr = 0xEA;  		/* TW: DAB (Device Address Byte) */
+
+  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
+    if (SiS_SetStart()) continue;	/* TW: Set start condition */
+    tempah=SiS_DDC_DeviceAddr;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
+    if(temp) continue;			/* TW:    (ERROR: no ack) */
+    tempah=tempbx&0x00FF;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write RAB */
+    if(temp) continue;			/* TW:    (ERROR: no ack) */
+    tempah=(tempbx&0xFF00)>>8;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write data */
+    if(temp) continue;			/* TW:    (ERROR: no ack) */
+    if (SiS_SetStop()) continue;	/* TW: Set stop condition */
+    return;
+  }
 }
 
+/* TW: Read from Chrontel 70xx */
+/* Parameter is [Register no (S7-S0)] */
 USHORT
-SiS_WriteDDC2Data (USHORT tempax)
+SiS_GetCH70xx(USHORT tempbx)
 {
-	USHORT i, flag, temp;
-
-	flag = 0x80;
-	for (i = 0; i < 8; i++) {
-		SiS_SetSCLKLow ();
-		if (tempax & flag) {
-			SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD,
-					 0x02);
-		} else {
-			SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD,
-					 0x00);
-		}
-		SiS_SetSCLKHigh ();
-		flag = flag >> 1;
-	}
-	temp = SiS_CheckACK ();
-	return (temp);
+   if (SiS_IF_DEF_CH70xx == 1)
+      return(SiS_GetCH700x(tempbx));
+   else
+      return(SiS_GetCH701x(tempbx));
 }
 
+/* TW: Read from Chrontel 700x */
+/* Parameter is [Register no (S7-S0)] */
 USHORT
-SiS_ReadDDC2Data (USHORT tempax)
+SiS_GetCH700x(USHORT tempbx)
 {
-	USHORT i, temp, getdata;
+  USHORT tempah,temp,i;
 
-	getdata = 0;
-	for (i = 0; i < 8; i++) {
-		getdata = getdata << 1;
-		SiS_SetSCLKLow ();
-		SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x02);
-		SiS_SetSCLKHigh ();
-		temp = SiS_GetReg1 (SiS_DDC_Port, SiS_DDC_Index);
-		if (temp & 0x02)
-			getdata = getdata | 0x01;
-	}
-	return (getdata);
+  if(!(SiS_ChrontelInit)) {
+     SiS_DDC_Index = 0x11;		/* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
+     SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
+     SiS_DDC_DataShift = 0x00;
+     SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
+  }
+
+  SiS_DDC_ReadAddr = tempbx;
+
+  for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
+    SiS_SetSwitchDDC2();
+    if(SiS_SetStart()) continue;	/* TW: Set start condition */
+    tempah = SiS_DDC_DeviceAddr;
+    temp = SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
+    if(temp) continue;			/* TW:        (ERROR: no ack) */
+    tempah = SiS_DDC_ReadAddr;		/* TW: Write RAB */
+    temp = SiS_WriteDDC2Data(tempah);
+    if(temp) continue;			/* TW:        (ERROR: no ack) */
+    if (SiS_SetStart()) continue;	/* TW: Re-start */
+    tempah = SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+    temp = SiS_WriteDDC2Data(tempah);	/* TW: DAB (S0=1=read) */
+    if(temp) continue;			/* TW:        (ERROR: no ack) */
+    tempah = SiS_ReadDDC2Data(tempah);	/* TW: Read byte */
+    if (SiS_SetStop()) continue;	/* TW: Stop condition */
+    SiS_ChrontelInit = 1;
+    return(tempah);
+  }
+
+  if(!SiS_ChrontelInit) {
+     SiS_DDC_Index = 0x0a;		/* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
+     SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
+     SiS_DDC_DataShift = 0x00;
+     SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
+
+     for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
+       SiS_SetSwitchDDC2();
+       if(SiS_SetStart()) continue;		/* TW: Set start condition */
+       tempah = SiS_DDC_DeviceAddr;
+       temp = SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
+       if(temp) continue;			/* TW:        (ERROR: no ack) */
+       tempah = SiS_DDC_ReadAddr;		/* TW: Write RAB */
+       temp = SiS_WriteDDC2Data(tempah);
+       if(temp) continue;			/* TW:        (ERROR: no ack) */
+       if (SiS_SetStart()) continue;		/* TW: Re-start */
+       tempah = SiS_DDC_DeviceAddr | 0x01; 	/* DAB | 0x01 = Read */
+       temp = SiS_WriteDDC2Data(tempah);	/* TW: DAB (S0=1=read) */
+       if(temp) continue;			/* TW:        (ERROR: no ack) */
+       tempah = SiS_ReadDDC2Data(tempah);	/* TW: Read byte */
+       if (SiS_SetStop()) continue;		/* TW: Stop condition */
+       SiS_ChrontelInit = 1;
+       return(tempah);
+     }
+  }
+  return(0xFFFF);
 }
 
-void
-SiS_SetSCLKLow (void)
+/* TW: Read from Chrontel 701x */
+/* Parameter is [Register no (S7-S0)] */
+USHORT
+SiS_GetCH701x(USHORT tempbx)
 {
-	USHORT temp;
+  USHORT tempah,temp,i;
+
+  /* TW: Toggle to DDC port */
+  SiS_SetRegOR(SiS_P3c4,0x38,0x20);
 
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFE, 0x00);	/* SetSCLKLow()  */
-	do {
-		temp = SiS_GetReg1 (SiS_DDC_Port, SiS_DDC_Index);
-	} while (temp & 0x01);
-	SiS_DDC2Delay ();
+  SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+  SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
+  SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
+  SiS_DDC_DataShift = 0x00;
+  SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
+  SiS_DDC_ReadAddr = tempbx;
+
+   for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
+    if(SiS_SetStart()) continue;	/* TW: Set start condition */
+    tempah = SiS_DDC_DeviceAddr;
+    temp = SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
+    if(temp) continue;			/* TW:        (ERROR: no ack) */
+    tempah = SiS_DDC_ReadAddr;		/* TW: Write RAB */
+    temp = SiS_WriteDDC2Data(tempah);
+    if(temp) continue;			/* TW:        (ERROR: no ack) */
+    if (SiS_SetStart()) continue;	/* TW: Re-start */
+    tempah = SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+    temp = SiS_WriteDDC2Data(tempah);	/* TW: DAB (S0=1=read) */
+    if(temp) continue;			/* TW:        (ERROR: no ack) */
+    tempah = SiS_ReadDDC2Data(tempah);	/* TW: Read byte */
+    SiS_SetStop();			/* TW: Stop condition */
+    return(tempah);
+   }
+  return 0xFFFF;
 }
 
 void
-SiS_SetSCLKHigh (void)
+SiS_SetCH70xxANDOR(USHORT tempax,USHORT tempbh)
 {
-	USHORT temp;
+  USHORT tempal,tempah,tempbl;
 
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFE, 0x01);	/* SetSCLKHigh()  */
-	do {
-		temp = SiS_GetReg1 (SiS_DDC_Port, SiS_DDC_Index);
-	} while (!(temp & 0x01));
-	SiS_DDC2Delay ();
+  tempal = tempax & 0x00FF;
+  tempah =(tempax >> 8) & 0x00FF;
+  tempbl = SiS_GetCH70xx(tempal);
+  tempbl = (((tempbl & tempbh) | tempah) << 8 | tempal);
+  SiS_SetCH70xx(tempbl);
 }
 
+/* TW: Generic I2C functions for Chrontel --------- */
+
+/* I2C functions CHECKED FOR TV BUG */
 void
-SiS_DDC2Delay (void)
+SiS_SetSwitchDDC2(void)
 {
-	USHORT i;
+  SiS_SetSCLKHigh();
+  SiS_DDC2Delay(SiS_I2CDELAY);
 
-	for (i = 0; i < DDC2DelayTime; i++) {
-		SiS_GetReg1 (SiS_P3c4, 0x05);
-	}
+  SiS_SetSCLKLow();
+  SiS_DDC2Delay(SiS_I2CDELAY);
 }
 
+/* TW: Set I2C start condition */
+/* TW: This is done by a SD high-to-low transition while SC is high */
 USHORT
-SiS_CheckACK (void)
+SiS_SetStart(void)
 {
-	USHORT tempah;
-
-	SiS_SetSCLKLow ();
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x02);
-	SiS_SetSCLKHigh ();
-	tempah = SiS_GetReg1 (SiS_DDC_Port, SiS_DDC_Index);
-	SiS_SetSCLKLow ();
-	if (tempah & 0x02)
-		return (1);
-	else
-		return (0);
+  if (SiS_SetSCLKLow()) return 0xFFFF;			                   /* TW: (SC->low)  */
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,SiS_DDC_Data);  /* TW: SD->high */
+  if (SiS_SetSCLKHigh()) return 0xFFFF;			                   /* TW: SC->high */
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,0x00);          /* TW: SD->low = start condition */
+  if (SiS_SetSCLKHigh()) return 0xFFFF;			                   /* TW: (SC->low) */
+  return 0;
 }
 
-void
-SiS_ModCRT1CRTC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex)
+/* TW: Set I2C stop condition */
+/* TW: This is done by a SD low-to-high transition while SC is high */
+USHORT
+SiS_SetStop(void)
 {
-	USHORT temp, tempah, i, modeflag, j;
-	USHORT ResInfo, DisplayType;
-	SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
+  if (SiS_SetSCLKLow()) return 0xFFFF;			                   /* TW: (SC->low) */
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,0x00);          /* TW: SD->low   */
+  if (SiS_SetSCLKHigh()) return 0xFFFF;			                   /* TW: SC->high  */
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,SiS_DDC_Data);  /* TW: SD->high = stop condition */
+  if (SiS_SetSCLKHigh()) return 0xFFFF;			                   /* TW: (SC->high) */
+  return 0;
+}
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-	}
+/* TW: Write 8 bits of data */
+USHORT
+SiS_WriteDDC2Data(USHORT tempax)
+{
+  USHORT i,flag,temp;
 
-	temp =
-	    SiS_GetLVDSCRT1Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &ResInfo, &DisplayType);
-	if (temp == 0) {
-		return;
-	}
-
-	switch (DisplayType) {
-	case 0:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;
-		break;
-	case 1:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;
-		break;
-	case 2:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;
-		break;
-	case 3:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;
-		break;
-	case 4:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;
-		break;
-	case 5:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;
-		break;
-	case 6:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;
-		break;
-	case 7:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;
-		break;
-	case 8:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;
-		break;
-	case 9:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;
-		break;
-	case 10:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;
-		break;
-	case 11:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;
-		break;
-	case 12:
-		LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;
-		break;
-	case 13:
-		LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;
-		break;
-	case 14:
-		LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;
-		break;
-	case 15:
-		LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;
-		break;
-	}
-
-	tempah = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x11);	/*unlock cr0-7  */
-	tempah = tempah & 0x7F;
-	SiS_SetReg1 (SiS_P3d4, 0x11, tempah);
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[0];
-	SiS_SetReg1 (SiS_P3d4, 0x0, tempah);
-	for (i = 0x02, j = 1; i <= 0x05; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x06, j = 5; i <= 0x07; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x10, j = 7; i <= 0x11; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x15, j = 9; i <= 0x16; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-
-	for (i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3c4, i, tempah);
-	}
-
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[14];
-	tempah = tempah & 0x0E0;
-	SiS_SetReg1 (SiS_P3c4, 0x0E, tempah);
-
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[14];
-	tempah = tempah & 0x01;
-	tempah = tempah << 5;
-	if (modeflag & DoubleScanMode) {
-		tempah = tempah | 0x080;
-	}
-	SiS_SetRegANDOR (SiS_P3d4, 0x09, ~0x020, tempah);
-	return;
+  flag=0x80;
+  for(i=0;i<8;i++) {
+    SiS_SetSCLKLow();					                      /* TW: SC->low */
+    if(tempax & flag) {
+      SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,SiS_DDC_Data); /* TW: Write bit (1) to SD */
+    } else {
+      SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,0x00);         /* TW: Write bit (0) to SD */
+    }
+    SiS_SetSCLKHigh();					                      /* TW: SC->high */
+    flag >>= 1;
+  }
+  temp=SiS_CheckACK();					                      /* TW: Check acknowledge */
+  return(temp);
 }
 
-/*301b*/
-void
-SiS_CHACRT1CRTC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex)
+USHORT
+SiS_ReadDDC2Data(USHORT tempax)
 {
-	USHORT temp, tempah, i, modeflag, j;
-	USHORT ResInfo, DisplayType;
-	SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
+  USHORT i,temp,getdata;
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-	}
-
-	temp =
-	    SiS_GetLVDSCRT1Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &ResInfo, &DisplayType);
-	if (temp == 0) {
-		return;
-	}
-
-	switch (DisplayType) {
-	case 0:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;
-		break;
-	case 1:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;
-		break;
-	case 2:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;
-		break;
-	case 3:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;
-		break;
-	case 4:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;
-		break;
-	case 5:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;
-		break;
-	case 6:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;
-		break;
-	case 7:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;
-		break;
-	case 8:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;
-		break;
-	case 9:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;
-		break;
-	case 10:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;
-		break;
-	case 11:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;
-		break;
-	case 12:
-		LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;
-		break;
-	case 13:
-		LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;
-		break;
-	case 14:
-		LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;
-		break;
-	case 15:
-		LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;
-		break;
-	}
-
-	tempah = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x11);	/*unlock cr0-7  */
-	tempah = tempah & 0x7F;
-	SiS_SetReg1 (SiS_P3d4, 0x11, tempah);
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[0];
-	SiS_SetReg1 (SiS_P3d4, 0x0, tempah);
-	for (i = 0x02, j = 1; i <= 0x05; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x06, j = 5; i <= 0x07; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x10, j = 7; i <= 0x11; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x15, j = 9; i <= 0x16; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-
-	for (i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3c4, i, tempah);
-	}
-
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[14];
-	tempah = tempah & 0x0E0;
-	SiS_SetReg1 (SiS_P3c4, 0x0E, tempah);
-
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[14];
-	tempah = tempah & 0x01;
-	tempah = tempah << 5;
-	if (modeflag & DoubleScanMode) {
-		tempah = tempah | 0x080;
-	}
-	SiS_SetRegANDOR (SiS_P3d4, 0x09, ~0x020, tempah);
-	return;
+  getdata=0;
+  for(i=0; i<8; i++) {
+    getdata <<= 1;
+    SiS_SetSCLKLow();
+    SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,SiS_DDC_Data);
+    SiS_SetSCLKHigh();
+    temp = SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);
+    if(temp & SiS_DDC_Data) getdata |= 0x01;
+  }
+  return(getdata);
 }
 
-/*add for LCDA*/
+USHORT
+SiS_SetSCLKLow(void)
+{
+  USHORT temp, watchdog=50000;
 
-BOOLEAN
-SiS_GetLCDACRT1Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex, USHORT * ResInfo,
-		    USHORT * DisplayType)
-{
-	USHORT tempbx = 0, modeflag = 0;
-	USHORT CRT2CRTC = 0;
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		tempbx = SiS_LCDResInfo;
-		tempbx -= Panel800x600;
-		if (SiS_LCDInfo & LCDNonExpanding)
-			tempbx += 6;
-		if (modeflag & HalfDCLK)
-			tempbx += +3;
-		if (ModeNo <= 0x13) {
-			modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-			CRT2CRTC = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-		} else {
-			modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-			CRT2CRTC =
-			    SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-		}
-	}
-	*ResInfo = CRT2CRTC & 0x3F;
-	*DisplayType = tempbx;
-	return 1;
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Clk,0x00);      /* SetSCLKLow()  */
+  do {
+    temp = SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);
+  } while((temp & SiS_DDC_Clk) && --watchdog);
+  if (!watchdog) return 0xFFFF;
+  SiS_DDC2Delay(SiS_I2CDELAYSHORT);
+  return 0;
 }
 
-/*end for 301b*/
+USHORT
+SiS_SetSCLKHigh(void)
+{
+  USHORT temp,watchdog=50000;
 
-BOOLEAN
-SiS_GetLVDSCRT1Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex, USHORT * ResInfo,
-		    USHORT * DisplayType)
-{
-	USHORT tempbx, modeflag = 0;
-	USHORT Flag, CRT2CRTC;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		CRT2CRTC = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		CRT2CRTC = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-	if (!(SiS_VBInfo & SetInSlaveMode)) {
-		return 0;
-	}
-	Flag = 1;
-	tempbx = 0;
-	if (SiS_IF_DEF_CH7005 == 1) {
-		if (!(SiS_VBInfo & SetCRT2ToLCD)) {
-			Flag = 0;
-			tempbx = 12;
-			if (SiS_VBInfo & SetPALTV)
-				tempbx += 2;
-			if (SiS_VBInfo & SetCHTVOverScan)
-				tempbx += 1;
-		}
-	}
-	if (Flag) {
-		tempbx = SiS_LCDResInfo;
-		tempbx -= Panel800x600;
-		if (SiS_LCDInfo & LCDNonExpanding)
-			tempbx += 6;
-		if (modeflag & HalfDCLK)
-			tempbx += +3;
-	}
-
-	*ResInfo = CRT2CRTC & 0x3F;
-	*DisplayType = tempbx;
-	return 1;
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Clk,SiS_DDC_Clk);      /* SetSCLKHigh()  */
+  do {
+    temp = SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);
+  } while((!(temp & SiS_DDC_Clk)) && --watchdog);
+  if (!watchdog) return 0xFFFF;
+  SiS_DDC2Delay(SiS_I2CDELAYSHORT);
+  return 0;
 }
 
 void
-SiS_SetCRT2ECLK (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT tempah, tempal;
-	USHORT P3cc = SiS_P3c9 + 3;
-	USHORT vclkindex = 0;
-
-	if (SiS_IF_DEF_TRUMPION == 0) {	/*no trumpion  */
-		tempal = SiS_GetReg2 (P3cc);
-		tempal = tempal & 0x0C;
-		vclkindex =
-		    SiS_GetVCLK2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				     RefreshRateTableIndex, HwDeviceExtension);
-	} else {		/*trumpion  */
-		SiS_SetFlag = SiS_SetFlag & (~ProgrammingCRT2);
-/*  tempal=*((UCHAR *)(ROMAddr+SiS_RefIndex+0x03));     &di+Ext_CRTVCLK  */
-		tempal = tempal & 0x03F;
-		if (tempal == 0x02) {	/*31.5MHz  */
-/*      SiS_RefIndex=SiS_RefIndex-Ext2StructSize;   */
-		}
-/*    SiS_RefIndex=GetVCLKPtr(ROMAddr,ModeNo);  */
-		SiS_SetFlag = SiS_SetFlag | ProgrammingCRT2;
-	}
-	tempal = 0x02B;
-	if (!(SiS_VBInfo & SetInSlaveMode)) {
-		tempal = tempal + 3;
-	}
-	SiS_SetReg1 (SiS_P3c4, 0x05, 0x86);
-	tempah = SiS_VCLKData[vclkindex].SR2B;
-	SiS_SetReg1 (SiS_P3c4, tempal, tempah);
-	tempal++;
-	tempah = SiS_VCLKData[vclkindex].SR2C;
-	SiS_SetReg1 (SiS_P3c4, tempal, tempah);
-	tempal++;
-	SiS_SetReg1 (SiS_P3c4, tempal, 0x80);
-	return;
+SiS_DDC2Delay(USHORT delaytime)
+{
+  USHORT i;
+
+  for(i=0; i<delaytime; i++) {
+    SiS_GetReg1(SiS_P3c4,0x05);
+  }
 }
 
-void
-SiS_SetDefCRT2ExtRegs (USHORT BaseAddr)
-{
-	USHORT temp;
-
-	if (SiS_IF_DEF_LVDS == 0) {
-		SiS_SetReg1 (SiS_Part1Port, 0x02, 0x40);
-		SiS_SetReg1 (SiS_Part4Port, 0x10, 0x80);
-		temp = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x16);
-		temp = temp & 0xC3;
-		SiS_SetReg1 (SiS_P3d4, 0x35, temp);
-	} else {
-		SiS_SetReg1 (SiS_P3d4, 0x32, 0x02);
-		SiS_SetReg1 (SiS_Part1Port, 0x02, 0x00);
-	}
+/* TW: Check I2C acknowledge */
+/* Returns 0 if ack ok, non-0 if ack not ok */
+USHORT
+SiS_CheckACK(void)
+{
+  USHORT tempah;
+
+  SiS_SetSCLKLow();					                   /* TW: (SC->low) */
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,SiS_DDC_Data);  /* TW: (SD->high) */
+  SiS_SetSCLKHigh();					                   /* TW: SC->high = clock impulse for ack */
+  tempah = SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);	                   /* TW: Read SD */
+  SiS_SetSCLKLow();					                   /* TW: SC->low = end of clock impulse */
+  if(tempah & SiS_DDC_Data) return(1);			                   /* TW: Ack OK if bit = 0 */
+  else return(0);
 }
 
-#ifdef CONFIG_FB_SIS_315
-/*
-    for SIS310 O.E.M.
-*/
+/* TW: End of I2C functions ----------------------- */
+
+
+/* =============== SiS 310 O.E.M. ================= */
+
+#ifdef SIS315H
+
 /*
 ---------------------------------------------------------
-   LCDResInfo 1 : 800x600
+   LCDResInfo 1 : 800x600          TW: Table wrong for LVDS!
               2 : 1024x768
               3 : 1280x1024
-              4 : 1280x960
-              5 : 640x480
+              4 : 1280x960         TW: 1400x1050
+              5 : 640x480          TW: 1600x1200
               6 : 1600x1200
               7 : 1920x1440
    VESA
@@ -5421,19 +7713,32 @@
 USHORT
 GetLCDPtrIndex (void)
 {
-	USHORT index;
+   USHORT index;
 
-	index = (SiS_LCDResInfo & 0x0F) - 1;
-	index *= 3;
-	if (SiS_LCDInfo & LCDNonExpanding)
-		index += 2;
-	else {
-		if (!(SiS_LCDInfo & LCDVESATiming))
-			index++;
-	}
+   if(SiS_IF_DEF_LVDS == 1) {   /* TW: Inserted entire if statement */
+
+     index = SiS_LCDResInfo & 0x0F;
+     if(SiS_LCDResInfo == Panel1400x1050)  index -= 5;
+     if(SiS_LCDResInfo == Panel1600x1200)  index -= 6;
+     index--;
+     index *= 3;
+     if(SiS_LCDInfo & LCDNonExpanding) index += 2;
+     else if(!(SiS_SetFlag & LCDVESATiming)) index++;
+
+   } else {
+
+     index = (SiS_LCDResInfo & 0x0F) - 1;
+     index *= 3;
+     if (SiS_LCDInfo & LCDNonExpanding)
+        index += 2;
+     else if (!(SiS_SetFlag & LCDVESATiming))
+         index++;
+
+   }
+
+  return index;
+ }
 
-	return index;
-}
 
 /*
 ---------------------------------------------------------
@@ -5447,555 +7752,551 @@
 ---------------------------------------------------------
 */
 USHORT
-GetTVPtrIndex (void)
-{
-	USHORT index;
-
-	index = 0;
-	if (SiS_VBInfo & SetPALTV)
-		index++;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV)	/* Hivision TV use PAL */
-		index++;
-	index *= 2;
-
-	if ((SiS_VBInfo & SetInSlaveMode) && (SiS_SetFlag & TVSimuMode))
-		index++;
-
-	return index;
-}
-
-void
-SetDelayComp (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-	      ULONG ROMAddr, USHORT ModeNo)
+GetTVPtrIndex(void)
 {
-	USHORT Part1Port;
-	USHORT delay, index;
+  USHORT index;
 
-	if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-		delay = SiS310_CRT2DelayCompensation1;
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-			delay = SiS310_CRT2DelayCompensation2;
-	} else if (SiS_VBInfo & SetCRT2ToLCD) {
-		index = GetLCDPtrIndex ();
-		delay = SiS310_LCDDelayCompensation1[index];
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-			delay = SiS310_LCDDelayCompensation2[index];
-	} else {
-		index = GetTVPtrIndex ();
-		delay = SiS310_TVDelayCompensation1[index];
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-			delay = SiS310_TVDelayCompensation2[index];
+  index = 0;
+  if (SiS_VBInfo & SetPALTV)
+    index++;
+  if (SiS_VBInfo & SetCRT2ToHiVisionTV)  /* Hivision TV use PAL */
+    index++;
+
+  index <<= 1;
+
+  if((SiS_VBInfo & SetInSlaveMode) && (SiS_SetFlag & TVSimuMode))
+    index++;
+
+  return index;
+}
+
+/* TW: Checked against 650/LVDS (1.10.07) and 650/301LV BIOS (including data) */
+void
+SetDelayComp(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+             UCHAR *ROMAddr,USHORT ModeNo)
+{
+  USHORT Part1Port;
+  USHORT delay,index;
+
+  if (SiS_VBInfo & SetCRT2ToRAMDAC) {
+     delay = SiS310_CRT2DelayCompensation1;
+     if (SiS_VBType & (VB_SIS301B | VB_SIS302B))
+       delay = SiS310_CRT2DelayCompensation2;
+     if(SiS_IF_DEF_LVDS == 1)
+       delay = SiS310_CRT2DelayCompensation3;
+  } else if (SiS_VBInfo & SetCRT2ToLCD) {
+       index = GetLCDPtrIndex();
+       delay = SiS310_LCDDelayCompensation1[index];
+       if (SiS_VBType & (VB_SIS301B|VB_SIS302B|VB_SIS301LV))
+         delay = SiS310_LCDDelayCompensation2[index];
+       if(SiS_IF_DEF_LVDS == 1)
+         delay = SiS310_LCDDelayCompensation3[index];
+  } else {
+       index = GetTVPtrIndex();
+       delay = SiS310_TVDelayCompensation1[index];
+       if (SiS_VBType & (VB_SIS301B | VB_SIS302B))
+         delay = SiS310_TVDelayCompensation2[index];
+       if(SiS_IF_DEF_LVDS == 1)
+         delay = SiS310_TVDelayCompensation3[index];
+  }
+  Part1Port=BaseAddr+SIS_CRT2_PORT_04;
+  if(SiS_IF_DEF_LVDS == 1) {
+    if(SiS_VBInfo & SetCRT2ToTV) {
+       SiS_SetRegANDOR(Part1Port,0x2D,0xF0,delay);
+    } else {
+       delay <<= 4;
+       SiS_SetRegANDOR(Part1Port,0x2D,0x0F,delay);
+    }
+  } else {
+     SiS_SetRegANDOR(Part1Port,0x2D,0xF0,delay);  /* index 2D D[3:0] */
+  }
+}
+
+/* TW: Checked against 650/301LV BIOS (including data) */
+void
+SetAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT Part2Port;
+  USHORT index,temp;
+
+  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+
+  temp = GetTVPtrIndex();
+  temp >>= 1;  	  /* 0: NTSC, 1 :PAL, 2:HiTV */
+
+  if (ModeNo<=0x13)
+    index = SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
+  else
+    index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
+
+  temp = SiS310_TVAntiFlick1[temp][index];
+  temp  <<= 4;
+
+  SiS_SetRegANDOR(Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
+}
+
+/* TW: Checked against 650/301LV BIOS (including data) */
+void
+SetEdgeEnhance(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT Part2Port;
+  USHORT index,temp;
+
+  Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+
+  temp = GetTVPtrIndex();
+  temp >>= 1;              	/* 0: NTSC, 1 :PAL, 2:HiTV */
+
+  if (ModeNo<=0x13)
+    index = SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
+  else
+    index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
+
+  temp = SiS310_TVEdge1[temp][index];
+  temp <<= 5;
+  SiS_SetRegANDOR(Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
+}
+
+/* TW: Checked against 650/301LV BIOS */
+void
+SetYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+           UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT Part2Port;
+  USHORT index,temp,i,j;
+  UCHAR  OutputSelect=*pSiS_OutputSelect;
+
+  Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+
+  temp = GetTVPtrIndex();
+  temp >>= 1;  			/* 0: NTSC, 1 :PAL, 2:HiTV */
+
+  if (ModeNo<=0x13) {
+    index =  SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+  } else {
+    index =  SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+  }
+
+  if (SiS_VBInfo&SetCRT2ToHiVisionTV)  /* Hivision TV uses PAL */
+    temp = 0;
+
+  if(SiS_VBType & VB_SIS301BLV302BLV) {
+    for(i=0x35, j=0; i<=0x38; i++, j++) {
+       SiS_SetReg1(Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
+    }
+    for(i=0x48; i<=0x4A; i++, j++) {
+       SiS_SetReg1(Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
+    }
+  } else {
+    for(i=0x35, j=0; i<=0x38; i++, j++){
+       SiS_SetReg1(Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
+    }
+  }
+
+  if(OutputSelect & EnablePALMN) {
+      if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
+         temp = SiS_GetReg1(SiS_P3d4,0x38);
+         temp &= (EnablePALMN | EnablePALN);
+         if(temp == EnablePALMN) {
+              if(SiS_VBType & VB_SIS301BLV302BLV) {
+                 for(i=0x35, j=0; i<=0x38; i++, j++){
+                      SiS_SetReg1(Part2Port,i,SiS310_PALMFilter2[index][j]);
+                 }
+                 for(i=0x48; i<=0x4A; i++, j++) {
+                       SiS_SetReg1(Part2Port,i,SiS310_PALMFilter2[index][j]);
+                 }
+              } else {
+                 for(i=0x35, j=0; i<=0x38; i++, j++) {
+                       SiS_SetReg1(Part2Port,i,SiS310_PALMFilter[index][j]);
+                 }
+              }
+         }
+         if(temp == EnablePALN) {
+              if(SiS_VBType & VB_SIS301BLV302BLV) {
+                 for(i=0x35, j=0; i<=0x38; i++, j++) {
+                      SiS_SetReg1(Part2Port,i,SiS310_PALNFilter2[index][j]);
+                 }
+                 for(i=0x48, j=0; i<=0x4A; i++, j++) {
+                       SiS_SetReg1(Part2Port,i,SiS310_PALNFilter2[index][j]);
+                 }
+             } else {
+                 for(i=0x35, j=0; i<=0x38; i++, j++)
+                       SiS_SetReg1(Part2Port,i,SiS310_PALNFilter[index][j]);
+             }
+         }
+      }
+  }
+}
+
+/* TW: Checked against 650/301LV BIOS (including data) */
+void
+SetPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+             UCHAR *ROMAddr,USHORT ModeNo)
+{
+  USHORT Part2Port;
+  USHORT index,temp,temp1,i,j;
+
+  if(!(SiS_VBInfo & SetCRT2ToTV)) return;
+
+  temp1 = SiS_GetReg1(SiS_P3d4,0x38);        /* if PALM/N not set */
+  temp1 &=  (EnablePALMN | EnablePALN);
+  if(temp1) return;
+
+  Part2Port=BaseAddr + SIS_CRT2_PORT_10;
+
+  temp = GetTVPtrIndex();
+  /* 0: NTSC Graphics, 1: NTSC Text,    2:PAL Graphics,
+   * 3: PAL Text,      4: HiTV Graphics 5:HiTV Text
+   */
+  index = temp % 2;
+  temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
+
+  for(j=0, i=0x31; i<=0x34; i++, j++) {
+     if(!(SiS_VBType & VB_SIS301BLV302BLV))
+	  SiS_SetReg1(Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
+     else if((!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode))
+          SiS_SetReg1(Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
+     else
+          SiS_SetReg1(Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
+  }
+  if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {
+     if(!(SiS_VBInfo & SetPALTV)) {
+        if((ModeNo == 0x38) || (ModeNo == 0x4a)) {
+	    SiS_SetReg1(SiS_Part2Port,0x31,0x1e);
+	    SiS_SetReg1(SiS_Part2Port,0x32,0x8c);
+	    SiS_SetReg1(SiS_Part2Port,0x33,0x5c);
+	    SiS_SetReg1(SiS_Part2Port,0x34,0x7a);
 	}
-
-	Part1Port = BaseAddr + SIS_CRT2_PORT_04;
-	SiS_SetRegANDOR (Part1Port, 0x2D, ~0x0F, delay);	/* index 2D D[3:0] */
-
+     }
+  }
 }
 
-/*
-*/
 void
-SetAntiFlicker (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_OEM310Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                  UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-	USHORT Part2Port;
-	USHORT index, temp;
-
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	temp = GetTVPtrIndex ();
-	temp = (temp >> 1);	/* 0: NTSC, 1 :PAL, 2:HiTV */
-	if (ModeNo <= 0x13) {
-		index = SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
-	} else {
-		index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
-	}
-	temp = SiS310_TVAntiFlick1[temp][index];
-	temp <<= 4;
-
-	SiS_SetRegANDOR (Part2Port, 0x0A, ~0x70, temp);	/* index 0A D[6:4] */
-
+   SetDelayComp(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+   /* TW: The TV funtions are not for LVDS */
+   if( (SiS_IF_DEF_LVDS == 0) && (SiS_VBInfo & SetCRT2ToTV) ) {
+       SetAntiFlicker(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       SetPhaseIncr(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+       SetYFilter(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       if(!(SiS_VBType & VB_SIS301BLV302BLV)) {
+          SetEdgeEnhance(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       }
+   }
+}
+
+/* TW: New and checked from 650/301LV BIOS */
+void
+SiS_OEMLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                  UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+   USHORT tempbx,tempah,tempbl,tempbh,tempcl;
+
+   if(SiS_IF_DEF_LVDS == 1) return;
+
+   if(SiS_VBInfo & SetCRT2ToLCDA) {
+      SiS_UnLockCRT2(HwDeviceExtension,BaseAddr);
+      tempbh = SiS_GetReg1(SiS_Part1Port,0x1a);
+      tempbh &= 0x38;
+      tempbh >>= 3;
+      tempbl = SiS_GetReg1(SiS_Part1Port,0x18);
+      tempbx = (tempbh << 8) | tempbl;
+      if(SiS_LCDTypeInfo == 1)  tempbx -= 0x12;
+      SiS_SetReg1(SiS_Part1Port,0x18,tempbx & 0x00ff);
+      tempah = (tempbx & 0xff00) >> 8;
+      tempah &= 0x07;
+      tempah <<= 3;
+      SiS_SetRegANDOR(SiS_Part1Port,0x1a,0xc7,tempah);
+      tempah = SiS_GetReg1(SiS_Part1Port,0x19);
+      tempah &= 0x0f;
+      if(SiS_LCDTypeInfo == 1)  tempah -= 2;
+      tempah &= 0x0f;
+      SiS_SetRegANDOR(SiS_Part1Port,0x19,0xF0,tempah);
+      tempah = SiS_GetReg1(SiS_Part1Port,0x14);
+      if(SiS_LCDTypeInfo == 1)  tempah++;
+      tempah -= 8;
+      SiS_SetReg1(SiS_Part1Port,0x14,tempah);
+   } else if(SiS_VBInfo & SetCRT2ToLCD) {
+      tempcl = tempbh = SiS_GetReg1(SiS_Part2Port,0x01);
+      tempbh &= 0x70;
+      tempbh >>= 4;
+      tempbl = SiS_GetReg1(SiS_Part2Port,0x04);
+      tempbx = (tempbh << 8) | tempbl;
+      if(SiS_LCDTypeInfo == 1)  {
+           tempbx -= 0x1e;
+	   tempcl &= 0x0f;
+	   tempcl -= 4;
+	   tempcl &= 0x0f;
+      }
+      tempbl = tempbx & 0x00ff;
+      tempbh = (tempbx >> 8) & 0x00ff;
+      SiS_SetReg1(SiS_Part2Port,0x04,tempbl);
+      tempbh <<= 4;
+      tempbh |= tempcl;
+      SiS_SetRegANDOR(SiS_Part2Port,0x01,0x80,tempbh);
+   }
 }
+#endif
 
-void
-SetEdgeEnhance (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
-{
-	USHORT Part2Port;
-	USHORT index, temp;
 
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	temp = GetTVPtrIndex ();
-	temp = (temp >> 1);	/* 0: NTSC, 1 :PAL, 2:HiTV */
-	if (ModeNo <= 0x13) {
-		index = SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;	/* si+VB_StTVEdgeIndex */
-	} else {
-		index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;	/* si+VB_ExtTVEdgeIndex */
-	}
-	temp = SiS310_TVEdge1[temp][index];
-	temp <<= 5;
+/*  =================  SiS 300 O.E.M. ================== */
 
-	SiS_SetRegANDOR (Part2Port, 0x3A, ~0xE0, temp);	/* index 0A D[7:5] */
+#ifdef SIS300
 
-}
-
-void
-SetYFilter (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-	    ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+#if 0   /* Not used */
+USHORT
+GetRevisionID(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT Part2Port, temp1, temp2;
-	USHORT index, temp, i, index1;
-	UCHAR OutputSelect = *pSiS_OutputSelect;
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	temp = GetTVPtrIndex ();
-	temp >>= 1;		/* 0: NTSC, 1 :PAL, 2:HiTV */
-
-	if (ModeNo <= 0x13) {
-		index = SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
-	} else {
-		index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
-	}
-
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV)	/* Hivision TV use PAL */
-		temp = 0;
-
-	/*301b */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		for (i = 0x35; i <= 0x38; i++) {
-			SiS_SetReg1 (Part2Port, i,
-				     SiS310_TVYFilter2[temp][index][i - 0x35]);
-		}
-		for (i = 0x48; i <= 0x4A; i++) {
-			SiS_SetReg1 (Part2Port, i,
-				     SiS310_TVYFilter2[temp][index][(i - 0x48) +
-								    0x04]);
-		}
-	}
-	/*end 301b */
-	else {
-		for (i = 0x35; i <= 0x38; i++) {
-			SiS_SetReg1 (Part2Port, i,
-				     SiS310_TVYFilter1[temp][index][i - 0x35]);
-		}
-	}
-/*add PALMN*/
-	if (OutputSelect & EnablePALMN) {
-		index1 = SiS_GetReg1 (SiS_P3d4, 0x31);
-		temp1 = index1 & 0x01;
-		index1 = SiS_GetReg1 (SiS_P3d4, 0x38);
-		temp2 = index1 & 0xC0;
-		if (temp1) {
-			if (temp2 == 0x40) {
-				if ((SiS_VBType & VB_SIS301B)
-				    || (SiS_VBType & VB_SIS302B)) {
-					for (i = 0x35; i <= 0x38; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALMFilter2
-							     [index][i - 0x35]);
-					}
-					for (i = 0x48; i <= 0x4A; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALMFilter2
-							     [index][(i - 0x48)
-								     + 0x04]);
-					}
-				} else {
-					for (i = 0x35; i <= 0x38; i++)
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALMFilter
-							     [index][i - 0x35]);
-				}
-			}
-			if (temp2 == 0x80) {
-				if ((SiS_VBType & VB_SIS301B)
-				    || (SiS_VBType & VB_SIS302B)) {
-					for (i = 0x35; i <= 0x38; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALNFilter2
-							     [index][i - 0x35]);
-					}
-					for (i = 0x48; i <= 0x4A; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALNFilter2
-							     [index][(i - 0x48)
-								     + 0x04]);
-					}
-				} else {
-					for (i = 0x35; i <= 0x38; i++)
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALNFilter
-							     [index][i - 0x35]);
-				}
-			}
-		}
-	}
-	/*end PALMN */
-}
+   ULONG temp1;
+#ifndef LINUX_XF86
+   ULONG base;
+#endif
+   USHORT temp2 = 0;
 
-void
-SetPhaseIncr (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-	      ULONG ROMAddr, USHORT ModeNo)
-{
-	USHORT Part2Port;
-	USHORT index, temp, temp1, i;
-
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	temp = GetTVPtrIndex ();
-	/* 0: NTSC Graphics, 1: NTSC Text, 2 :PAL Graphics, 3 :PAL Text, 4:HiTV Graphics 5:HiTV Text */
-	index = temp % 2;
-	temp >>= 1;		/* 0: NTSC, 1 :PAL, 2:HiTV */
-	temp1 = SiS_GetReg1 (SiS_P3d4, 0x38);	/*if PALMN Not Set */
-	temp1 = temp1 & 0xC0;
-	if (!temp1) {
-		for (i = 0x31; i <= 0x34; i++) {
-			if ((SiS_VBType & VB_SIS301B)
-			    || (SiS_VBType & VB_SIS302B))
-				    SiS_SetReg1 (Part2Port, i,
-						 SiS310_TVPhaseIncr2[temp]
-						 [index][i - 0x31]);
-			else
-				SiS_SetReg1 (Part2Port, i,
-					     SiS310_TVPhaseIncr1[temp][index][i
-									      -
-									      0x31]);
-		}
-	}
-}
-void
-SiS_OEM310Setting (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		   ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
-{
-	SetDelayComp (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo);
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		SetAntiFlicker (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo,
-				ModeIdIndex);
-		SetPhaseIncr (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo);
-		SetYFilter (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo,
-			    ModeIdIndex);
-		SetEdgeEnhance (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo,
-				ModeIdIndex);
-	}
+   if((HwDeviceExtension->jChipType==SIS_540)||
+      (HwDeviceExtension->jChipType==SIS_630)||
+      (HwDeviceExtension->jChipType==SIS_730)) {
+#ifndef LINUX_XF86
+     	base = 0x80000008;
+     	OutPortLong(base,0xcf8);
+     	temp1 = InPortLong(0xcfc);
+#else
+	temp1=pciReadLong(0x00000000, 0x08);
+#endif
+     	temp1 &= 0x000000FF;
+     	temp2 = (USHORT)(temp1);
+    	return temp2;
+   }
+   return 0;
 }
-
 #endif
 
-#ifdef CONFIG_FB_SIS_300
-/*
-    for SIS300 O.E.M.
-*/
-
+/* TW: Checked against 630/301B BIOS (incl data) */
 USHORT
-GetRevisionID (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+GetOEMLCDPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension, int Flag)
 {
-#ifdef CONFIG_FB_SIS_300
-	ULONG temp1, base;
-	USHORT temp2 = 0;
-	/* add to set SR14 */
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		base = 0x80000008;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 & 0x000000FF;
-		temp2 = (USHORT) (temp1);
-		return temp2;
-	}
+  USHORT tempbx=0;
+  UCHAR customtable[] = {
+  	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+  };
+
+  if(Flag) {
+      if(customtable[SiS_LCDTypeInfo] == 0xFF) return 0xFFFF;
+  }
+  if(SiS_IF_DEF_LVDS == 0) {
+        tempbx = SiS_LCDTypeInfo << 2;
+	if(SiS_VBInfo & SetInSlaveMode) tempbx += 2;
+	if(SiS_LCDInfo & LCDNonExpanding) tempbx++;
+  } else {
+  	tempbx = SiS_LCDTypeInfo;
+	if(SiS_LCDInfo & LCDNonExpanding) tempbx += 16;
+  }
+  return tempbx;
+}
+
+/* TW: Checked against 630/301B and 630/LVDS BIOS (incl data) */
+void
+SetOEMLCDDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT Part1Port;
+  USHORT index,temp;
+
+  /* TW: The Panel Compensation Delay should be set according to tables
+   *     here. Unfortunately, the different 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(). So we can't
+   *     rely on the other OEM bits in 0x237, 0x238 here either.
+   */
+#if 0
+  if(ROMAddr) {
+     if(!(ROMAddr[0x237] & 0x01)) return;
+     if(!(ROMAddr[0x237] & 0x02)) return;
+  }
 #endif
+  /* TW: We just check if a non-standard delay has been set; if not,
+   * we use our tables. Otherwise don't do anything here.
+   */
+  if(ROMAddr) {
+     if(ROMAddr[0x220] & 0x80) return;
+  }
+  /* TW: We don't need to set this if the user select a custom pdc */
+  if(HwDeviceExtension->pdc) return;
+
+  Part1Port = BaseAddr + SIS_CRT2_PORT_04;
+
+  temp = GetOEMLCDPtr(HwDeviceExtension, 0);
+
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
+
+  if (SiS_IF_DEF_LVDS == 0) {
+    	temp = SiS300_OEMLCDDelay2[temp][index];
+  } else {
+        temp = SiS300_OEMLCDDelay3[temp][index];
+  }
+  temp &= 0x3c;
+  SiS_SetRegANDOR(Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
 }
 
+/* TW: Checked against 630/301B and 630/LVDS BIOS */
 USHORT
-GetOEMLCDPtr (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+GetOEMTVPtr(void)
 {
-	USHORT temp, tempbx = 0, tempax;
+  USHORT index;
 
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_VBInfo & SetCRT2ToLCD) {	/* LCD */
-			tempax = SiS_LCDResInfo;
-			tempbx = SiS_LCDResInfo;
-			tempbx = tempbx - Panel1024x768;
-			if (!(SiS_SetFlag & LCDVESATiming)) {
-				tempbx += 4;
-				temp = GetRevisionID (HwDeviceExtension);
-				if ((HwDeviceExtension->jChipType == SIS_540)
-				    && (temp < 1))
-					tempbx += 4;
-				if ((HwDeviceExtension->jChipType == SIS_630)
-				    && (temp < 3))
-					tempbx += 4;
-			}
-			if ((tempax == Panel1024x768)
-			    && (SiS_LCDInfo == LCDNonExpanding)) {
-				tempbx = tempbx + 3;
-			}
-			/*add OEMLCDPanelIDSupport */
-			tempbx = SiS_LCDTypeInfo;
-			tempbx = tempbx << 1;
-			if (!(SiS_SetFlag & LCDVESATiming))
-				tempbx = tempbx + 1;
-		}
-	}
-	tempbx *= 2;
-	return tempbx;
-}
+  index = 0;
+  if(!(SiS_VBInfo & SetInSlaveMode)) index += 4;
+  if(SiS_IF_DEF_LVDS == 0) {
+     if(SiS_VBInfo & SetCRT2ToSCART) index += 2;
+     else if (SiS_VBInfo & SetCRT2ToHiVisionTV) index += 3;
+     else if(SiS_VBInfo & SetPALTV)  index += 1;
+  } else {
+     if(SiS_VBInfo & SetCHTVOverScan) index += 2;
+     if(SiS_VBInfo & SetPALTV)  index += 1;
+  }
+  return index;
+}
+
+/* TW: Checked against 630/301B and 630/LVDS BIOS (incl data) */
+void
+SetOEMTVDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT Part1Port;
+  USHORT index,temp;
+
+#if 0
+  if(ROMAddr) {
+     if(!(ROMAddr[0x238] & 0x01)) return;
+     if(!(ROMAddr[0x238] & 0x02)) return;
+  }
+#endif
 
-USHORT
-GetOEMTVPtr (void)
-{
-	USHORT index;
+  Part1Port = BaseAddr + SIS_CRT2_PORT_04;
 
-	index = 0;
-	if (!(SiS_VBInfo & SetInSlaveMode))
-		index = index + 4;
+  temp = GetOEMTVPtr();
 
-	if (SiS_VBInfo & SetCRT2ToSCART) {
-		index = index + 2;
-	} else {
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV)
-			index = index + 3;
-		else {
-			if (SiS_VBInfo & SetPALTV)
-				index = index + 1;
-		}
-	}
-	return index;
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
+
+  if(SiS_IF_DEF_LVDS == 0) {
+     temp = SiS300_OEMTVDelay301[temp][index];
+  } else {
+     temp = SiS300_OEMTVDelayLVDS[temp][index];
+  }
+  temp &= 0x3c;
+  SiS_SetRegANDOR(Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
 }
 
+/* TW: Checked against 630/301B BIOS (incl data) */
 void
-SetOEMTVDelay (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-	       ULONG ROMAddr, USHORT ModeNo)
+SetOEMAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+		  USHORT ModeIdIndex)
 {
-	USHORT Part1Port;
-	USHORT index, temp, ModeIdIndex;
-	Part1Port = BaseAddr + SIS_CRT2_PORT_04;
-	ModeIdIndex = SiS_SearchVBModeID (ROMAddr, ModeNo);
-	temp = GetOEMTVPtr ();
-	index = SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
-	temp = SiS300_OEMTVDelay[temp][index];
-	temp = temp & 0x3c;
-	SiS_SetRegANDOR (Part1Port, 0x13, ~0x3C, temp);	/* index 0A D[6:4] */
-}
+  USHORT Part2Port;
+  USHORT index,temp;
 
-void
-SetOEMLCDDelay (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		ULONG ROMAddr, USHORT ModeNo)
-{
-	USHORT Part2Port;
-	USHORT index, temp, ModeIdIndex;
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	ModeIdIndex = SiS_SearchVBModeID (ROMAddr, ModeNo);
-	temp = GetOEMLCDPtr (HwDeviceExtension);
-	index = SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
-	temp = SiS300_OEMLCDDelay1[temp][index];
-	/*add OEMLCDPanelIDSupport */
-	temp = SiS300_OEMLCDDelay2[temp][index];
-	temp = temp & 0x3c;
-	SiS_SetRegANDOR (Part2Port, 0x13, ~0x3C, temp);	/* index 0A D[6:4] */
+  Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+
+  temp = GetOEMTVPtr();
+
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
+
+  temp = SiS300_OEMTVFlicker[temp][index];
+  temp &= 0x70;
+  SiS_SetRegANDOR(Part2Port,0x0A,0x8F,temp);  /* index 0A D[6:4] */
 }
 
-/*
-*/
+/* TW: Checked against 630/301B BIOS (incl data) */
 void
-SetOEMAntiFlicker (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		   ULONG ROMAddr, USHORT ModeNo)
+SetOEMPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-	USHORT Part2Port;
-	USHORT index, temp;
-	USHORT ModeIdIndex;
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	ModeIdIndex = SiS_SearchVBModeID (ROMAddr, ModeNo);
-	temp = GetOEMTVPtr ();
-	index = SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
-	temp = SiS300_OEMTVFlicker[temp][index];
-	temp = temp & 0x70;
-	SiS_SetRegANDOR (Part2Port, 0x0A, ~0x70, temp);	/* index 0A D[6:4] */
+  USHORT Part2Port;
+  USHORT index,i,j,temp;
 
-}
+  if(SiS_VBInfo & SetCRT2ToHiVisionTV) return;
 
-void
-SetOEMPhaseIncr (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		 ULONG ROMAddr, USHORT ModeNo)
-{
-	USHORT Part2Port;
-	USHORT index, i, ModeIdIndex;
-
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	// temp = GetTVPtrIndex();
-	/* 0: NTSC Graphics, 1: NTSC Text, 2 :PAL Graphics, 3 :PAL Text, 4:HiTV Graphics 5:HiTV Text */
-	// index = temp % 2;
-	// temp >>= 1;   /* 0: NTSC, 1 :PAL, 2:HiTV */
-	ModeIdIndex = SiS_SearchVBModeID (ROMAddr, ModeNo);
-	index = SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
-	if (SiS_VBInfo & SetInSlaveMode) {
-		if (SiS_VBInfo & SetPALTV) {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_StPALPhase[index][i -
-								      0x31]);
-		} else {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_StNTSCPhase[index][i -
-								       0x31]);
-		}
-		if (SiS_VBInfo & SetCRT2ToSCART) {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_StSCARTPhase[index][i -
-									0x31]);
-		}
-	} else {
-		if (SiS_VBInfo & SetPALTV) {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_ExtPALPhase[index][i -
-								       0x31]);
-		} else {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_ExtNTSCPhase[index][i -
-									0x31]);
-		}
-		if (SiS_VBInfo & SetCRT2ToSCART) {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_ExtSCARTPhase[index][i -
-									 0x31]);
-		}
-	}
+  Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+
+  temp = GetOEMTVPtr();
+
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
+
+  if(SiS_VBType & VB_SIS301BLV302BLV) {
+       for(i=0x31, j=0; i<=0x34; i++, j++) {
+          SiS_SetReg1(Part2Port,i,SiS300_Phase2[temp][index][j]);
+       }
+  } else {
+       for(i=0x31, j=0; i<=0x34; i++, j++) {
+          SiS_SetReg1(Part2Port,i,SiS300_Phase1[temp][index][j]);
+       }
+  }
 }
 
+/* TW: Checked against 630/301B BIOS (incl data) */
 void
-SetOEMYFilter (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-	       ULONG ROMAddr, USHORT ModeNo)
+SetOEMYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-	USHORT Part2Port;
-	USHORT index, temp1, temp2, i, ModeIdIndex, index1;
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	/*301b */
-	ModeIdIndex = SiS_SearchVBModeID (ROMAddr, ModeNo);
-	index = SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
-	if (SiS_VBInfo & SetInSlaveMode) {
-		if (SiS_VBInfo & SetPALTV) {
-			for (i = 0x35; i <= 0x38; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_StPALFilter[index][i -
-								       0x35]);
-		} else {
-			for (i = 0x35; i <= 0x38; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_StNTSCFilter[index][i -
-									0x35]);
-		}
-	} else {
-		if (SiS_VBInfo & SetPALTV) {
-			for (i = 0x35; i <= 0x38; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_ExtPALFilter[index][i -
-									0x35]);
-		} else {
-			for (i = 0x35; i <= 0x38; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_ExtNTSCFilter[index][i -
-									 0x35]);
-		}
-	}
+  USHORT Part2Port;
+  USHORT index,temp,temp1,i,j;
 
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		if (SiS_VBInfo & SetPALTV) {
-			for (i = 0x35; i <= 0x38; i++) {
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_PALFilter2[index][i -
-								      0x35]);
-			}
-			for (i = 0x48; i <= 0x4A; i++) {
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_PALFilter2[index][(i - 0x48)
-								      + 0x04]);
-			}
-		} else {
-			for (i = 0x35; i <= 0x38; i++) {
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_NTSCFilter2[index][i -
-								       0x35]);
-			}
-			for (i = 0x48; i <= 0x4A; i++) {
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_NTSCFilter2[index][
-								       (i -
-									0x48) +
-								       0x04]);
-			}
-		}
-	}
+  if(SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVisionTV)) return;
 
-/*add PALMN*/
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		index1 = SiS_GetReg1 (SiS_P3d4, 0x31);
-		temp1 = index1 & 0x01;
-		index1 = SiS_GetReg1 (SiS_P3d4, 0x35);
-		temp2 = index1 & 0xC0;
-		if (temp1) {
-			if (temp2 == 0x40) {
-				if ((SiS_VBType & VB_SIS301B)
-				    || (SiS_VBType & VB_SIS302B)) {
-					for (i = 0x35; i <= 0x38; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALMFilter2
-							     [index][i - 0x35]);
-					}
-					for (i = 0x48; i <= 0x4A; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALMFilter2
-							     [index][(i - 0x48)
-								     + 0x04]);
-					}
-				} else {
-					for (i = 0x35; i <= 0x38; i++)
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALMFilter
-							     [index][i - 0x35]);
-				}
-			}
-			if (temp2 == 0x80) {
-				if ((SiS_VBType & VB_SIS301B)
-				    || (SiS_VBType & VB_SIS302B)) {
-					for (i = 0x35; i <= 0x38; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALNFilter2
-							     [index][i - 0x35]);
-					}
-					for (i = 0x48; i <= 0x4A; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALNFilter2
-							     [index][(i - 0x48)
-								     + 0x04]);
-					}
-				} else {
-					for (i = 0x35; i <= 0x38; i++)
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALNFilter
-							     [index][i - 0x35]);
-				}
-			}
-		}
-	}
-	/*end PALMN */
+  Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+
+  temp = GetOEMTVPtr();
+
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
+
+  if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
+       temp1 = SiS_GetReg1(SiS_P3d4,0x35);
+       if(temp1 & (EnablePALMN | EnablePALN)) {
+          temp = 16;
+	  if(temp1 & EnablePALN) temp = 18;
+       }
+  }
+  if(SiS_VBType & VB_SIS301BLV302BLV) {
+      for(i=0x35, j=0; i<=0x38; i++, j++) {
+       	SiS_SetReg1(Part2Port,i,SiS300_Filter2[temp][index][j]);
+      }
+      for(i=0x48; i<=0x4A; i++, j++) {
+     	SiS_SetReg1(Part2Port,i,SiS300_Filter2[temp][index][j]);
+      }
+  } else {
+      for(i=0x35, j=0; i<=0x38; i++, j++) {
+       	SiS_SetReg1(Part2Port,i,SiS300_Filter1[temp][index][j]);
+      }
+  }
 }
 
 void
-SiS_OEM300Setting (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		   ULONG ROMAddr, USHORT ModeNo)
+SiS_OEM300Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+		  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo)
 {
-	if (SiS_VBInfo & SetCRT2ToLCD) {
-		SetOEMLCDDelay (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo);
-	}
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		SetOEMTVDelay (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo);
-		SetOEMAntiFlicker (HwDeviceExtension, BaseAddr, ROMAddr,
-				   ModeNo);
-		/* SetOEMPhaseIncr(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo); */
-		SetOEMYFilter (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo);
-	}
+  USHORT ModeIdIndex;
+
+  ModeIdIndex = SiS_SearchVBModeID(ROMAddr,&ModeNo);
+  if(!(ModeIdIndex)) return;
+
+  if (SiS_VBInfo & SetCRT2ToLCD) {
+       SetOEMLCDDelay(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+  }
+  if (SiS_VBInfo & SetCRT2ToTV) {
+       SetOEMTVDelay(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       if(SiS_IF_DEF_LVDS==0) {
+       		SetOEMAntiFlicker(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+    		SetOEMPhaseIncr(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       		SetOEMYFilter(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       }
+  }
 }
 #endif
+
+
diff -Nru a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
--- a/drivers/video/sis/init301.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/sis/init301.h	Wed Jul 24 14:03:38 2002
@@ -7,217 +7,308 @@
 #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"
+#include "xf86PciInfo.h"
+#include "sis.h"
+#include "sis_regs.h"
+#endif
+
+#ifdef LINUX_KERNEL
 #include <asm/io.h>
 #include <linux/types.h>
 #include <linux/sisfb.h>
+#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
+
+USHORT   SiS_SetFlag;
+USHORT   SiS_RVBHCFACT,SiS_RVBHCMAX,SiS_RVBHRS;
+USHORT   SiS_VGAVT,SiS_VGAHT;
+USHORT   SiS_VT,SiS_HT;
+USHORT   SiS_VGAVDE,SiS_VGAHDE;
+USHORT   SiS_VDE,SiS_HDE;
+USHORT   SiS_NewFlickerMode,SiS_RY1COE,SiS_RY2COE,SiS_RY3COE,SiS_RY4COE;
+USHORT   SiS_LCDHDES,SiS_LCDVDES;
+USHORT   SiS_DDC_Port, SiS_DDC_Index,SiS_DDC_Data, SiS_DDC_Clk;
+USHORT   SiS_DDC_DataShift, SiS_DDC_DeviceAddr, SiS_DDC_Flag;
+USHORT   SiS_DDC_ReadAddr, SiS_DDC_Buffer;
+
+USHORT   Panel800x600,   Panel1024x768,  Panel1280x1024, Panel1600x1200;
+USHORT   Panel1280x960,  Panel1400x1050, Panel320x480,   Panel1152x768;
+USHORT   Panel1280x768,  Panel1024x600,  Panel640x480,   Panel1152x864;
+USHORT   PanelMax, PanelMinLVDS, PanelMin301;
+
+USHORT   SiS_ChrontelInit;
+
+extern   USHORT   SiS_CRT1Mode;
+extern   USHORT   SiS_P3c4,SiS_P3d4;
+extern   USHORT   SiS_P3ca;
+extern   USHORT   SiS_P3c9;
+extern   USHORT   SiS_P3da;
+extern   USHORT   SiS_Part1Port,SiS_Part2Port;
+extern   USHORT   SiS_Part3Port,SiS_Part4Port,SiS_Part5Port;
+extern   USHORT   SiS_MDA_DAC[];
+extern   USHORT   SiS_CGA_DAC[];
+extern   USHORT   SiS_EGA_DAC[];
+extern   USHORT   SiS_VGA_DAC[];
+extern   USHORT   SiS_ModeType;
+extern   USHORT   SiS_SelectCRT2Rate;
+extern   USHORT   SiS_IF_DEF_LVDS;
+extern   USHORT   SiS_IF_DEF_TRUMPION;
+extern   USHORT   SiS_IF_DEF_CH70xx;
+extern   USHORT   SiS_Backup70xx;
+extern   USHORT   SiS_IF_DEF_HiVision;
+extern   USHORT   SiS_IF_DEF_DSTN;   /*add for dstn*/
+extern   USHORT   SiS_IF_DEF_FSTN;   /*add for fstn*/
+extern   USHORT   SiS_VBInfo;
+extern   USHORT   SiS_VBType;
+extern   USHORT   SiS_VBExtInfo;
+extern   USHORT   SiS_LCDResInfo;
+extern   USHORT   SiS_LCDTypeInfo;
+extern   USHORT   SiS_LCDInfo;
+extern   USHORT   SiS_HiVision;
+
+extern   BOOLEAN  SiS_SearchVBModeID(UCHAR *RomAddr, USHORT *);
+
+BOOLEAN  SiS_Is301B(USHORT BaseAddr);
+BOOLEAN  SiS_IsDisableCRT2(USHORT BaseAddr);
+BOOLEAN  SiS_IsVAMode(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_IsDualEdge(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_CRT2IsLCD(USHORT BaseAddr);
+
+void     SiS_SetDefCRT2ExtRegs(USHORT BaseAddr);
+USHORT   SiS_GetRatePtrCRT2(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+BOOLEAN  SiS_AdjustCRT2Rate(UCHAR *ROMAddr,USHORT ModeNo,USHORT MODEIdIndex,USHORT RefreshRateTableIndex,USHORT *i);
+void     SiS_SaveCRT2Info(USHORT ModeNo);
+void     SiS_GetCRT2Data(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+                         PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetCRT2DataLVDS(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetCRT2PtrA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+                         USHORT *CRT2Index,USHORT *ResIndex);
+void     SiS_GetCRT2Part2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		             USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+		             USHORT *ResIndex);
+void     SiS_GetCRT2Data301(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_GetResInfo(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_GetCRT2ResInfo(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetRAMDAC2DATA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetCRT2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+		        USHORT *CRT2Index,USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT2ModeRegs(USHORT BaseAddr,USHORT ModeNo,USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO );
+void     SiS_SetHiVision(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+void     SiS_GetLVDSDesData(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT2Offset(USHORT Part1Port,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                           USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_GetOffset(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+                       PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_GetColorDepth(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+USHORT   SiS_GetMCLK(UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_CalcDelayVB(void);
+USHORT   SiS_GetVCLK2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT2Sync(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex,
+                         PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR);
+void     SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR);
+void     SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND);
+USHORT   SiS_GetVGAHT2(void);
+void     SiS_SetGroup2(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                       USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetGroup3(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                       PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetGroup4(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                       USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetGroup5(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_SetCRT2VCLK(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_EnableCRT2(void);
+void     SiS_LoadDAC2(UCHAR *ROMAddr,USHORT Part5Port,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_WriteDAC2(USHORT Pdata,USHORT dl, USHORT ah, USHORT al, USHORT dh);
+void     SiS_GetVBInfo301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                          PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_GetLCDResInfo(UCHAR *ROMAddr,USHORT P3d4,USHORT ModeNo,USHORT ModeIdIndex);
+BOOLEAN  SiS_BridgeIsOn(USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+BOOLEAN  SiS_BridgeIsEnable(USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+BOOLEAN  SiS_BridgeInSlave(void);
+void     SiS_PresetScratchregister(USHORT SiS_P3d4,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetTVSystem(VOID);
+void     SiS_LongWait(VOID);
+USHORT   SiS_GetQueueConfig(VOID);
+void     SiS_VBLongWait(VOID);
+USHORT   SiS_GetVCLKLen(UCHAR *ROMAddr);
+void     SiS_WaitVBRetrace(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_WaitRetrace1(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_WaitRetrace2(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT2ECLK(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+                         PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetLVDSDesPtr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+                           USHORT *PanelIndex,USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetLVDSDesPtrA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+                            USHORT *PanelIndex,USHORT *ResIndex);
+void     SiS_SetTPData(VOID);
+void     SiS_ModCRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+			 PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN  SiS_GetLVDSCRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+		       USHORT *ResInfo,USHORT *DisplayType);
+void     SiS_SetCHTVReg(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_GetCHTVRegPtr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_SetCH700x(USHORT tempax);
+USHORT   SiS_GetCH700x(USHORT tempax);
+void     SiS_SetCH701x(USHORT tempax);
+USHORT   SiS_GetCH701x(USHORT tempax);
+void     SiS_SetCH70xx(USHORT tempax);
+USHORT   SiS_GetCH70xx(USHORT tempax);
+void     SiS_SetCH70xxANDOR(USHORT tempax,USHORT tempbh);
+void     SiS_SetSwitchDDC2(void);
+USHORT   SiS_SetStart(void);
+USHORT   SiS_SetStop(void);
+void     SiS_DDC2Delay(USHORT delaytime);
+USHORT   SiS_SetSCLKLow(void);
+USHORT   SiS_SetSCLKHigh(void);
+USHORT   SiS_ReadDDC2Data(USHORT tempax);
+USHORT   SiS_WriteDDC2Data(USHORT tempax);
+USHORT   SiS_CheckACK(void);
+#ifdef SIS315H
+void     SiS_OEM310Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                           UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_OEMLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                    UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+#endif
+#ifdef SIS300
+void     SiS_OEM300Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                           UCHAR *ROMAddr,USHORT ModeNo);
+#endif
+USHORT   GetRevisionID(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_LowModeStuff(USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+BOOLEAN  SiS_GetLCDResInfo301(UCHAR *ROMAddr,USHORT SiS_P3d4, USHORT ModeNo, USHORT ModeIdIndex,
+                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
+/* void    SiS_CHACRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                        USHORT RefreshRateTableIndex); */
+BOOLEAN  SiS_GetLCDACRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
+		   USHORT *DisplayType);
+/* 310 series OEM */
+USHORT 	GetLCDPtrIndex (void);
+USHORT  GetTVPtrIndex(void);
+void    SetDelayComp(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+             	     UCHAR *ROMAddr,USHORT ModeNo);
+void    SetAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               	       UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void    SetEdgeEnhance (PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                        UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void    SetYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+           	   UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void	SetPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+             	     UCHAR *ROMAddr,USHORT ModeNo);
+/* 300 series OEM */
+USHORT 	GetOEMLCDPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension, int Flag);
+USHORT 	GetOEMTVPtr(void);
+void	SetOEMTVDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+              	      UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void	SetOEMLCDDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               	       UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void	SetOEMAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                          USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void  	SetOEMPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                        UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void	SetOEMYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+              	      UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+
+extern   void     SiS_SetReg1(USHORT, USHORT, USHORT);
+extern   void     SiS_SetReg3(USHORT, USHORT);
+extern   UCHAR    SiS_GetReg1(USHORT, USHORT);
+extern   UCHAR    SiS_GetReg2(USHORT);
+extern   BOOLEAN  SiS_SearchModeID(UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
+extern   BOOLEAN  SiS_GetRatePtr(ULONG, USHORT);
+extern   void     SiS_SetReg4(USHORT, ULONG);
+extern   ULONG    SiS_GetReg3(USHORT);
+extern   void     SiS_DisplayOff(void);
+extern   void     SiS_DisplayOn(void);
+extern   UCHAR    SiS_GetModePtr(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+#ifdef SIS315H
+extern   UCHAR    SiS_Get310DRAMType(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#endif
+
+BOOLEAN  SiS_SetCRT2Group301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetGroup1(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                       PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+void     SiS_SetGroup1_LVDS(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                            PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+void     SiS_SetGroup1_LCDA(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                            PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);/*301b*/
+void     SiS_SetGroup1_301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                           PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+#ifdef SIS300
+void     SiS_SetCRT2FIFO_300(UCHAR *ROMAddr,USHORT ModeNo,
+                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#endif
+#ifdef SIS315H
+void     SiS_SetCRT2FIFO_310(UCHAR *ROMAddr,USHORT ModeNo,
+                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_CRT2AutoThreshold(USHORT  BaseAddr);
+#endif
+BOOLEAN  SiS_GetLCDDDCInfo(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_UnLockCRT2(PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void     SiS_LockCRT2(PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void     SiS_DisableBridge(PSIS_HW_DEVICE_INFO,USHORT  BaseAddr);
+void     SiS_EnableBridge(PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void     SiS_SetPanelDelay(UCHAR* ROMAddr,PSIS_HW_DEVICE_INFO,USHORT DelayTime);
+void     SiS_ShortDelay(USHORT delay);
+void     SiS_LongDelay(USHORT delay);
+void     SiS_GenericDelay(USHORT delay);
+void     SiS_VBWait(void);
+
+/* TW: New functions (with temporary names) */
+void     SiS_Chrontel701xOn(void);
+void     SiS_Chrontel701xOn2(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                           USHORT BaseAddr);
+void     SiS_Chrontel701xOff(void);
+void     SiS_Chrontel701xOff2(void);
+void     SiS_ChrontelFlip0x48(void);
+void     SiS_ChrontelDoSomething4(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void     SiS_ChrontelDoSomething3(USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void     SiS_ChrontelDoSomething2(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void     SiS_ChrontelDoSomething1(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_WeHaveBacklightCtrl(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+#if 0
+BOOLEAN  SiS_IsSomethingCR5F(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+#endif
+BOOLEAN  SiS_IsYPbPr(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_IsTVOrSomething(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_IsLCDOrLCDA(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void     SiS_SetCHTVForLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void     SiS_Chrontel19f2(void);
+BOOLEAN  SiS_CR36BIOSWord23b(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_CR36BIOSWord23d(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_IsSR13_CR30(PSIS_HW_DEVICE_INFO HwDeviceExtension);
 
-USHORT SiS_SetFlag;
-USHORT SiS_RVBHCFACT, SiS_RVBHCMAX, SiS_RVBHRS;
-USHORT SiS_VGAVT, SiS_VGAHT;
-USHORT SiS_VT, SiS_HT;
-USHORT SiS_VGAVDE, SiS_VGAHDE;
-USHORT SiS_VDE, SiS_HDE;
-USHORT SiS_NewFlickerMode, SiS_RY1COE, SiS_RY2COE, SiS_RY3COE, SiS_RY4COE;
-USHORT SiS_LCDHDES, SiS_LCDVDES;
-USHORT SiS_DDC_Port;
-USHORT SiS_DDC_Index;
-USHORT SiS_DDC_DataShift;
-USHORT SiS_DDC_DeviceAddr;
-USHORT SiS_DDC_Flag;
-USHORT SiS_DDC_ReadAddr;
-USHORT SiS_DDC_Buffer;
-
-extern USHORT SiS_CRT1Mode;
-extern USHORT SiS_P3c4, SiS_P3d4;
-/*extern   USHORT      SiS_P3c0,SiS_P3ce,SiS_P3c2;*/
-extern USHORT SiS_P3ca;
-/*extern   USHORT      SiS_P3c6,SiS_P3c7,SiS_P3c8;*/
-extern USHORT SiS_P3c9;
-extern USHORT SiS_P3da;
-extern USHORT SiS_Part1Port, SiS_Part2Port;
-extern USHORT SiS_Part3Port, SiS_Part4Port, SiS_Part5Port;
-extern USHORT SiS_MDA_DAC[];
-extern USHORT SiS_CGA_DAC[];
-extern USHORT SiS_EGA_DAC[];
-extern USHORT SiS_VGA_DAC[];
-extern USHORT SiS_ModeType;
-extern USHORT SiS_SelectCRT2Rate;
-extern USHORT SiS_IF_DEF_LVDS;
-extern USHORT SiS_IF_DEF_TRUMPION;
-extern USHORT SiS_IF_DEF_CH7005;
-extern USHORT SiS_IF_DEF_HiVision;
-extern USHORT SiS_IF_DEF_DSTN;	/*add for dstn */
-extern USHORT SiS_VBInfo;
-extern USHORT SiS_VBType;	/*301b */
-extern USHORT SiS_LCDResInfo;
-extern USHORT SiS_LCDTypeInfo;
-extern USHORT SiS_LCDInfo;
-extern BOOLEAN SiS_SearchVBModeID (ULONG, USHORT);
-extern BOOLEAN SiS_Is301B (USHORT BaseAddr);	/*301b */
-extern BOOLEAN SiS_IsDisableCRT2 (USHORT BaseAddr);
-extern BOOLEAN SiS_IsVAMode (USHORT BaseAddr);
-extern BOOLEAN SiS_IsDualEdge (USHORT BaseAddr);
-/*end 301b*/
-
-void SiS_SetDefCRT2ExtRegs (USHORT BaseAddr);
-USHORT SiS_GetRatePtrCRT2 (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-BOOLEAN SiS_AjustCRT2Rate (ULONG ROMAddr, USHORT ModeNo, USHORT MODEIdIndex,
-			   USHORT RefreshRateTableIndex, USHORT * i);
-void SiS_SaveCRT2Info (USHORT ModeNo);
-void SiS_GetCRT2Data (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex);
-void SiS_GetCRT2DataLVDS (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			  USHORT RefreshRateTableIndex);
-void SiS_GetCRT2PtrA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex, USHORT * CRT2Index, USHORT * ResIndex);	/*301b */
-void SiS_GetCRT2Data301 (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			 USHORT RefreshRateTableIndex);
-USHORT SiS_GetResInfo (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_GetCRT2ResInfo (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_GetRAMDAC2DATA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			 USHORT RefreshRateTableIndex);
-void SiS_GetCRT2Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		     USHORT RefreshRateTableIndex, USHORT * CRT2Index,
-		     USHORT * ResIndex);
-void SiS_SetCRT2ModeRegs (USHORT BaseAddr, USHORT ModeNo, PSIS_HW_DEVICE_INFO);
-
-void SiS_GetLVDSDesData (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			 USHORT RefreshRateTableIndex);
-void SiS_SetCRT2Offset (USHORT Part1Port, ULONG ROMAddr, USHORT ModeNo,
-			USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-			PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT SiS_GetOffset (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex,
-		      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT SiS_GetColorDepth (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-USHORT SiS_GetVCLK (ULONG ROMAddr, USHORT ModeNo);
-USHORT SiS_GetVCLKPtr (ULONG ROMAddr, USHORT ModeNo);
-USHORT SiS_GetColorTh (ULONG ROMAddr);
-USHORT SiS_GetMCLK (ULONG ROMAddr);
-USHORT SiS_GetMCLKPtr (ULONG ROMAddr);
-USHORT SiS_GetDRAMType (ULONG ROMAddr);
-USHORT SiS_CalcDelayVB (void);
-extern USHORT SiS_GetVCLK2Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			       USHORT RefreshRateTableIndex,
-			       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetCRT2Sync (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		      USHORT RefreshRateTableIndex);
-void SiS_SetRegANDOR (USHORT Port, USHORT Index, USHORT DataAND, USHORT DataOR);
-void SiS_SetRegOR (USHORT Port, USHORT Index, USHORT DataOR);
-void SiS_SetRegAND (USHORT Port, USHORT Index, USHORT DataAND);
-USHORT SiS_GetVGAHT2 (void);
-void SiS_SetGroup2 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-		    PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetGroup3 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetGroup4 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-		    PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetGroup5 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex);
-void SiS_SetCRT2VCLK (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		      USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-		      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_EnableCRT2 (void);
-void SiS_LoadDAC2 (ULONG ROMAddr, USHORT Part5Port, USHORT ModeNo,
-		   USHORT ModeIdIndex);
-void SiS_WriteDAC2 (USHORT Pdata, USHORT dl, USHORT ah, USHORT al, USHORT dh);
-void SiS_GetVBInfo301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		       USHORT ModeIdIndex,
-		       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN SiS_GetLCDResInfo (ULONG ROMAddr, USHORT P3d4, USHORT ModeNo,
-			   USHORT ModeIdIndex);
-BOOLEAN SiS_BridgeIsOn (USHORT BaseAddr);
-BOOLEAN SiS_BridgeIsEnable (USHORT BaseAddr, PSIS_HW_DEVICE_INFO);
-BOOLEAN SiS_BridgeInSlave (void);
-/*void     SiS_PresetScratchregister(USHORT P3d4);*/
-void SiS_PresetScratchregister (USHORT SiS_P3d4,
-				PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetTVSystem (VOID);
-void SiS_LongWait (VOID);
-USHORT SiS_GetQueueConfig (VOID);
-void SiS_VBLongWait (VOID);
-USHORT SiS_GetVCLKLen (ULONG ROMAddr);
-BOOLEAN SiS_WaitVBRetrace (USHORT BaseAddr);
-void SiS_SetCRT2ECLK (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex,
-		      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_GetLVDSDesPtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			USHORT RefreshRateTableIndex, USHORT * PanelIndex,
-			USHORT * ResIndex);
-void SiS_GetLVDSDesPtrA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			 USHORT RefreshRateTableIndex, USHORT * PanelIndex,
-			 USHORT * ResIndex);	/*301b */
-void SiS_SetTPData (VOID);
-void SiS_ModCRT1CRTC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex);
-extern BOOLEAN SiS_GetLVDSCRT1Ptr (ULONG ROMAddr, USHORT ModeNo,
-				   USHORT ModeIdIndex,
-				   USHORT RefreshRateTableIndex,
-				   USHORT * ResInfo, USHORT * DisplayType);
-void SiS_SetCHTVReg (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		     USHORT RefreshRateTableIndex);
-void SiS_SetCHTVRegANDOR (USHORT tempax, USHORT tempbh);
-void SiS_GetCHTVRegPtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			USHORT RefreshRateTableIndex);
-void SiS_SetCH7005 (USHORT tempax);
-USHORT SiS_GetCH7005 (USHORT tempax);
-void SiS_SetSwitchDDC2 (void);
-void SiS_SetStart (void);
-void SiS_SetStop (void);
-void SiS_DDC2Delay (void);
-void SiS_SetSCLKLow (void);
-void SiS_SetSCLKHigh (void);
-USHORT SiS_ReadDDC2Data (USHORT tempax);
-USHORT SiS_WriteDDC2Data (USHORT tempax);
-USHORT SiS_CheckACK (void);
-void SiS_OEM310Setting (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-			ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_OEM300Setting (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-			ULONG ROMAddr, USHORT ModeNo);
-USHORT GetRevisionID (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_SetReg1 (USHORT, USHORT, USHORT);
-extern void SiS_SetReg3 (USHORT, USHORT);
-extern UCHAR SiS_GetReg1 (USHORT, USHORT);
-extern UCHAR SiS_GetReg2 (USHORT);
-extern BOOLEAN SiS_SearchModeID (ULONG ROMAddr, USHORT ModeNo,
-				 USHORT * ModeIdIndex);
-extern BOOLEAN SiS_GetRatePtr (ULONG, USHORT);
-extern void SiS_SetReg4 (USHORT, ULONG);
-extern ULONG SiS_GetReg3 (USHORT);
-extern void SiS_DisplayOff (void);
-extern void SiS_CRT2AutoThreshold (USHORT BaseAddr);
-extern void SiS_DisplayOn (void);
-extern UCHAR SiS_GetModePtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-extern UCHAR SiS_Get310DRAMType (ULONG ROMAddr);
-
-BOOLEAN SiS_SetCRT2Group301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-			     PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetGroup1 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		    USHORT RefreshRateTableIndex);
-void SiS_SetGroup1_LVDS (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-			 USHORT ModeIdIndex,
-			 PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			 USHORT RefreshRateTableIndex);
-void SiS_SetGroup1_LCDA (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-			 USHORT ModeIdIndex,
-			 PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT RefreshRateTableIndex);	/*301b */
-void SiS_SetGroup1_301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-			USHORT ModeIdIndex,
-			PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			USHORT RefreshRateTableIndex);
-void SiS_SetCRT2FIFO (USHORT Part1Port, ULONG ROMAddr, USHORT ModeNo,
-		      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetCRT2FIFO2 (USHORT Part1Port, ULONG ROMAddr, USHORT ModeNo,
-		       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN SiS_GetLCDDDCInfo (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_UnLockCRT2 (PSIS_HW_DEVICE_INFO, USHORT BaseAddr);
-void SiS_LockCRT2 (PSIS_HW_DEVICE_INFO, USHORT BaseAddr);
-void SiS_DisableBridge (PSIS_HW_DEVICE_INFO, USHORT BaseAddr);
-void SiS_EnableBridge (PSIS_HW_DEVICE_INFO, USHORT BaseAddr);
-void SiS_SetPanelDelay (USHORT DelayTime);
-void SiS_LCD_Wait_Time (UCHAR DelayTime);
+/* TW end */
 
 #endif
diff -Nru a/drivers/video/sis/initdef.h b/drivers/video/sis/initdef.h
--- a/drivers/video/sis/initdef.h	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/sis/initdef.h	Wed Jul 24 14:03:38 2002
@@ -1,4 +1,6 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
+
+
 #ifndef _INITDEF_
 #define _INITDEF_
 
@@ -6,18 +8,21 @@
 #define SiS540                  0x5300
 #define SiS630                  0x6300
 #define SiS730                  0x6300
-#define VB_SIS301		0x0001	/*301b */
-#define VB_SIS301B		0x0002
-#define VB_SIS302B		0x0004
-#define  VB_NoLCD		0x8000
 
-/*end 301b*/
+/* SiS_VBType */
+#define VB_SIS301	      	0x0001
+#define VB_SIS301B        	0x0002
+#define VB_SIS302B        	0x0004
+#define VB_SIS301LV     	0x0008
+#define VB_SIS302LV     	0x0010
+#define VB_NoLCD        	0x8000
+#define VB_SIS301BLV302BLV      (VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)
+
 #define CRT1Len                 17
 #define LVDSCRT1Len             15
 #define CHTVRegDataLen          5
 
-#define ModeInfoFlag            0x07
-#define IsTextMode              0x07
+/* SiS_ModeType */
 #define ModeText                0x00
 #define ModeCGA                 0x01
 #define ModeEGA                 0x02
@@ -27,10 +32,14 @@
 #define Mode24Bpp               0x06
 #define Mode32Bpp               0x07
 
+#define ModeInfoFlag            0x07
+#define IsTextMode              0x07
+
 #define DACInfoFlag             0x18
 #define MemoryInfoFlag          0x1E0
 #define MemorySizeShift         0x05
 
+/* modeflag */
 #define Charx8Dot               0x0200
 #define LineCompareOff          0x0400
 #define CRT2Mode                0x0800
@@ -38,16 +47,17 @@
 #define NoSupportSimuTV         0x2000
 #define DoubleScanMode          0x8000
 
+/* Infoflag */
 #define SupportAllCRT2          0x0078
 #define SupportTV               0x0008
 #define SupportHiVisionTV       0x0010
 #define SupportLCD              0x0020
-#define SupportRAMDAC2          0x0040
+#define SupportRAMDAC2          0x0040  
 #define NoSupportTV             0x0070
 #define NoSupportHiVisionTV     0x0060
 #define NoSupportLCD            0x0058
 #define SupportCHTV 		0x0800
-#define SupportTV1024           0x0800	/*301b */
+#define SupportTV1024           0x0800  /*301b*/            
 #define InterlaceMode           0x0080
 #define SyncPP                  0x0000
 #define SyncPN                  0x4000
@@ -59,7 +69,8 @@
 #define ECLKindex3              0x0300
 #define ECLKindex4              0x0400
 
-#define SetSimuScanMode         0x0001
+/* VBInfo */
+#define SetSimuScanMode         0x0001   /* CR 30 */
 #define SwitchToCRT2            0x0002
 #define SetCRT2ToTV             0x009C
 #define SetCRT2ToAVIDEO         0x0004
@@ -68,30 +79,93 @@
 #define SetCRT2ToLCD            0x0020
 #define SetCRT2ToRAMDAC         0x0040
 #define SetCRT2ToHiVisionTV     0x0080
-#define SetNTSCTV               0x0000
+#define SetNTSCTV               0x0000   /* CR 31 */
 #define SetPALTV                0x0100
 #define SetInSlaveMode          0x0200
 #define SetNotSimuMode          0x0400
 #define SetNotSimuTVMode        0x0400
 #define SetDispDevSwitch        0x0800
 #define LoadDACFlag             0x1000
+#define SetCHTVOverScan  	0x1000  /* TW: Re-defined (from 0x8000) */
 #define DisableCRT2Display      0x2000
+#define CRT2DisplayFlag         0x2000
 #define DriverMode              0x4000
-#define HotKeySwitch            0x8000
-#define SetCHTVOverScan  	0x8000
-#define SetCRT2ToLCDA		0x8000	/*301b */
+#define HotKeySwitch            0x8000  /* TW: ? */
+#define SetCRT2ToLCDA           0x8000
 #define PanelRGB18Bit           0x0100
 #define PanelRGB24Bit           0x0000
 
-#define TVOverScan              0x10
+#define TVOverScan              0x10    /* Bit in CR35 (300 series only) */
 #define TVOverScanShift         4
 #define ClearBufferFlag         0x20
-#define EnableDualEdge 		0x01	/*301b */
-#define SetToLCDA		0x02
+
+/* CR32 (Newer 630, and 310/325 series)
+
+   [0]   VB connected with CVBS
+   [1]   VB connected with SVHS
+   [2]   VB connected with SCART
+   [3]   VB connected with LCD
+   [4]   VB connected with CRT2 (secondary VGA)
+   [5]   CRT1 monitor is connected
+   [6]   VB connected with Hi-Vision TV
+   [7]   VB connected with DVI combo connector
+
+
+   CR37
+
+   [0]   Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS)
+   [3:1] External chip
+         300 series:
+	    001   SiS301 (never seen)
+	    010   LVDS
+	    011   LVDS + Tumpion Zurac
+	    100   LVDS + Chrontel 7005
+	    110   Chrontel 7005
+	  310/325 series
+	    001   SiS30x (never seen)
+	    010   LVDS
+	    011   LVDS + Chrontel 7019
+	  All other combinations reserved
+   [4]    LVDS: Expanding(0)/Non-expanding(1) LCD display
+          30x:  SiS30x(0)/LCD monitor(1) scaling display
+   [5]    LCD polarity select
+          0: VESA DMT Standard
+	  1: EDID 2.x defined
+   [6]    LCD honrizontal polarity select
+          0: High active
+	  1: Low active
+   [7]    LCD vertical polarity select
+          0: High active
+	  1: Low active
+*/
+
+#define EnableDualEdge 		0x01   /* CR38 (310/325 series) */
+/* #define PAL_NTSC             0x01      (only on 315PRO) */
+#define SetToLCDA		0x02   /* TW: LCD channel A (302 only) */
+#define SetYPbPr                0x10   /* TW: ? */
+#define EnablePALMN             0x40
+#define EnablePALN              0x80
+
+/* CR79 (310/325 series only)
+   [3-0] Notify driver
+         0001 Mode Switch event (set by BIOS)
+	 0010 Epansion On/Off event
+	 0011 TV UnderScan/OverScan event
+	 0100 Set Brightness event
+	 0101 Set Contrast event
+	 0110 Set Mute event
+	 0111 Set Volume Up/Down event
+   [4]   Enable Backlight Control by BIOS/driver (set by driver)
+   [5]   PAL/NTSC (set by BIOS)
+   [6]   Expansion On/Off (set by BIOS)
+   [7]   TV UnderScan/OverScan (set by BIOS)
+*/
+
 
 #define SetSCARTOutput          0x01
 #define BoardTVType             0x02
-#define  EnablePALMN		0x40
+
+/* SetFlag */
 #define ProgrammingCRT2         0x01
 #define TVSimuMode              0x02
 #define RPLLDIV2XO              0x04
@@ -100,35 +174,57 @@
 #define SetDispDevSwitchFlag    0x20
 #define CheckWinDos             0x40
 #define SetJDOSMode             0x80
+#define CRT2IsVGA	        0x80  /* TW: Not sure about this name... */
+
+/* LCDResInfo */
+#define Panel300_800x600        0x01	/* CR36 */
+#define Panel300_1024x768       0x02
+#define Panel300_1280x1024      0x03
+#define Panel300_1280x960       0x04
+#define Panel300_640x480        0x05
+#define Panel300_1024x600       0x06
+#define Panel300_1152x768       0x07
+/* #define Panel300_1600x1200      0x06  OLD */
+#define Panel300_320x480        0x08 	/* fstn - TW: This is fake, can be any */
+
+#define Panel310_800x600        0x01
+#define Panel310_1024x768       0x02
+#define Panel310_1280x1024      0x03
+#define Panel310_640x480        0x04
+#define Panel310_1024x600       0x05
+#define Panel310_1152x864       0x06
+#define Panel310_1280x960       0x07
+#define Panel310_1152x768       0x08
+#define Panel310_1400x1050      0x09
+#define Panel310_1280x768       0x0a
+#define Panel310_1600x1200      0x0b
+#define Panel310_320x480        0x0c           /* fstn - TW: This is fake, can be any */
 
-#define Panel800x600            0x01
-#define Panel1024x768           0x02
-#define Panel1280x1024          0x03
-#define Panel1280x960           0x04
-#define Panel640x480            0x05
-#define Panel1600x1200          0x06	/*301b */
-#define LCDRGB18Bit             0x01
 #define ExtChipType             0x0e
 #define ExtChip301              0x02
 #define ExtChipLVDS             0x04
 #define ExtChipTrumpion         0x06
 #define ExtChipCH7005           0x08
-#define ExtChipMitacTV          0x0a
+#define ExtChipMitacTV          0x0a            /* TW: Incorrect, 0x0a = Chrontel 7005 only */
+
+#define IsM650                  0x80   		/* TW: CR5F */
+
+/* LCDInfo */
+#define LCDRGB18Bit             0x01
+#define LCDNonExpandingShift    0x04
 #define LCDNonExpanding         0x10
-#define LCDNonExpandingShift    4
 #define LCDSync                 0x20
+/* TW: What is.. */        /*  0x100   */
 #define LCDSyncBit              0xe0
 #define LCDSyncShift            6
 
-#define DDC2DelayTime           300
-
-#define CRT2DisplayFlag         0x2000
 #define LCDDataLen              8
 #define HiTVDataLen             12
 #define TVDataLen               16
 #define SetPALTV                0x0100
-#define HalfDCLK                0x1000
+#define HalfDCLK                0x1000  /* modeflag */
 #define NTSCHT                  1716
+#define NTSC2HT                 1920
 #define NTSCVT                  525
 #define PALHT                   1728
 #define PALVT                   625
@@ -141,25 +237,23 @@
 
 #define VCLKStartFreq           25
 #define SoftDramType            0x80
-#define VCLK40                  0x04
-#define VCLK65                  0x09
-#define VCLK108_2               0x14
-#define LCDRGB18Bit             0x01
+
+#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
+
 #define LoadDACFlag             0x1000
 #define AfterLockCRT2           0x4000
 #define SetCRT2ToAVIDEO         0x0004
 #define SetCRT2ToSCART          0x0010
 #define Ext2StructSize          5
 
-#define TVVCLKDIV2              0x021
-#define TVVCLK                  0x022
-
-#define HiTVVCLKDIV2            0x023
-#define HiTVVCLK                0x024
-#define HiTVSimuVCLK            0x025
-#define HiTVTextVCLK            0x026
-#define SwitchToCRT2            0x0002
-#define LCDVESATiming           0x08
 #define SetSCARTOutput          0x01
 #define AVIDEOSense             0x01
 #define SVIDEOSense             0x02
@@ -172,14 +266,13 @@
 #define HotPlugFunction         0x08
 #define StStructSize            0x06
 
-#define SIS_CRT2_PORT_04        0x04 - 0x030
+#define SIS_CRT2_PORT_04        0x04 - 0x30
 #define SIS_CRT2_PORT_10        0x10 - 0x30
 #define SIS_CRT2_PORT_12        0x12 - 0x30
 #define SIS_CRT2_PORT_14        0x14 - 0x30
 
-#define LCDNonExpanding         0x10
 #define ADR_CRT2PtrData         0x20E
-#define offset_Zurac            0x210
+#define offset_Zurac            0x210   /* TW: Trumpion Zurac data pointer */
 #define ADR_LVDSDesPtrData      0x212
 #define ADR_LVDSCRT1DataPtr     0x214
 #define ADR_CHTVVCLKPtr         0x216
@@ -198,26 +291,26 @@
 #define ModeSettingAddr         0x53
 
 #define SelectCRT1Rate          0x4
+        
+#define _PanelType00             0x00
+#define _PanelType01             0x08
+#define _PanelType02             0x10
+#define _PanelType03             0x18
+#define _PanelType04             0x20
+#define _PanelType05             0x28
+#define _PanelType06             0x30
+#define _PanelType07             0x38
+#define _PanelType08             0x40
+#define _PanelType09             0x48
+#define _PanelType0A             0x50
+#define _PanelType0B             0x58
+#define _PanelType0C             0x60
+#define _PanelType0D             0x68
+#define _PanelType0E             0x70
+#define _PanelType0F             0x78
 
-#define _PanelType00            0x00
-#define _PanelType01            0x08
-#define _PanelType02            0x10
-#define _PanelType03            0x18
-#define _PanelType04            0x20
-#define _PanelType05            0x28
-#define _PanelType06            0x30
-#define _PanelType07            0x38
-#define _PanelType08            0x40
-#define _PanelType09            0x48
-#define _PanelType0A            0x50
-#define _PanelType0B            0x58
-#define _PanelType0C            0x60
-#define _PanelType0D            0x68
-#define _PanelType0E            0x70
-#define _PanelType0F            0x78
-
-#define PRIMARY_VGA		0	/* 1: SiS is primary vga 0:SiS is secondary vga */
-#define BIOSIDCodeAddr          0x235
+#define PRIMARY_VGA       	0     /* 1: SiS is primary vga 0:SiS is secondary vga */
+#define BIOSIDCodeAddr          0x235  /* TW: Offsets to ptrs in BIOS image */
 #define OEMUtilIDCodeAddr       0x237
 #define VBModeIDTableAddr       0x239
 #define OEMTVPtrAddr            0x241
@@ -258,55 +351,57 @@
 
 #define OEMLCDPanelIDSupport    0x0080
 
-/* =============================================================
-   for 310
-============================================================== */
-#define SoftDRAMType      	0x80
-#define SoftSetting_OFFSET	0x52
-#define SR07_OFFSET		0x7C
-#define SR15_OFFSET		0x7D
-#define SR16_OFFSET		0x81
-#define SR17_OFFSET		0x85
-#define SR19_OFFSET		0x8D
-#define SR1F_OFFSET		0x99
-#define SR21_OFFSET		0x9A
-#define SR22_OFFSET		0x9B
-#define SR23_OFFSET		0x9C
-#define SR24_OFFSET		0x9D
-#define SR25_OFFSET		0x9E
-#define SR31_OFFSET		0x9F
-#define SR32_OFFSET		0xA0
-#define SR33_OFFSET		0xA1
-
-#define CR40_OFFSET		0xA2
-#define SR25_1_OFFSET		0xF6
-#define CR49_OFFSET		0xF7
-
-#define VB310Data_1_2_Offset	0xB6
-#define VB310Data_4_D_Offset	0xB7
-#define VB310Data_4_E_Offset	0xB8
-#define VB310Data_4_10_Offset	0xBB
-
-#define RGBSenseDataOffset	0xBD
-#define YCSenseDataOffset	0xBF
-#define VideoSenseDataOffset	0xC1
-#define OutputSelectOffset	0xF3
-
-#define ECLK_MCLK_DISTANCE	0x14
-#define VBIOSTablePointerStart	0x100
-#define StandTablePtrOffset	VBIOSTablePointerStart+0x02
-#define EModeIDTablePtrOffset	VBIOSTablePointerStart+0x04
-#define CRT1TablePtrOffset	VBIOSTablePointerStart+0x06
-#define ScreenOffsetPtrOffset	VBIOSTablePointerStart+0x08
-#define VCLKDataPtrOffset	VBIOSTablePointerStart+0x0A
-#define MCLKDataPtrOffset	VBIOSTablePointerStart+0x0E
-#define CRT2PtrDataPtrOffset	VBIOSTablePointerStart+0x10
-#define TVAntiFlickPtrOffset	VBIOSTablePointerStart+0x12
-#define TVDelayPtr1Offset	VBIOSTablePointerStart+0x14
-#define TVPhaseIncrPtr1Offset	VBIOSTablePointerStart+0x16
-#define TVYFilterPtr1Offset	VBIOSTablePointerStart+0x18
-#define LCDDelayPtr1Offset	VBIOSTablePointerStart+0x20
-#define TVEdgePtr1Offset	VBIOSTablePointerStart+0x24
-#define CRT2Delay1Offset	VBIOSTablePointerStart+0x28
+/*
+  =============================================================
+   			for 310/325 series
+  =============================================================
+*/
+#define SoftDRAMType        0x80
+#define SoftSetting_OFFSET  0x52
+#define SR07_OFFSET  0x7C
+#define SR15_OFFSET  0x7D
+#define SR16_OFFSET  0x81
+#define SR17_OFFSET  0x85
+#define SR19_OFFSET  0x8D
+#define SR1F_OFFSET  0x99
+#define SR21_OFFSET  0x9A
+#define SR22_OFFSET  0x9B
+#define SR23_OFFSET  0x9C
+#define SR24_OFFSET  0x9D
+#define SR25_OFFSET  0x9E
+#define SR31_OFFSET  0x9F
+#define SR32_OFFSET  0xA0
+#define SR33_OFFSET  0xA1
+
+#define CR40_OFFSET  0xA2
+#define SR25_1_OFFSET  0xF6
+#define CR49_OFFSET  0xF7
+
+#define VB310Data_1_2_Offset  0xB6
+#define VB310Data_4_D_Offset  0xB7
+#define VB310Data_4_E_Offset  0xB8
+#define VB310Data_4_10_Offset 0xBB
+
+#define RGBSenseDataOffset    0xBD
+#define YCSenseDataOffset     0xBF
+#define VideoSenseDataOffset  0xC1
+#define OutputSelectOffset    0xF3
+
+#define ECLK_MCLK_DISTANCE  0x14
+#define VBIOSTablePointerStart    0x100
+#define StandTablePtrOffset       VBIOSTablePointerStart+0x02
+#define EModeIDTablePtrOffset     VBIOSTablePointerStart+0x04
+#define CRT1TablePtrOffset        VBIOSTablePointerStart+0x06
+#define ScreenOffsetPtrOffset     VBIOSTablePointerStart+0x08
+#define VCLKDataPtrOffset         VBIOSTablePointerStart+0x0A
+#define MCLKDataPtrOffset         VBIOSTablePointerStart+0x0E
+#define CRT2PtrDataPtrOffset      VBIOSTablePointerStart+0x10
+#define TVAntiFlickPtrOffset      VBIOSTablePointerStart+0x12
+#define TVDelayPtr1Offset         VBIOSTablePointerStart+0x14
+#define TVPhaseIncrPtr1Offset     VBIOSTablePointerStart+0x16
+#define TVYFilterPtr1Offset       VBIOSTablePointerStart+0x18
+#define LCDDelayPtr1Offset        VBIOSTablePointerStart+0x20
+#define TVEdgePtr1Offset          VBIOSTablePointerStart+0x24
+#define CRT2Delay1Offset          VBIOSTablePointerStart+0x28
 
 #endif
diff -Nru a/drivers/video/sis/oem300.h b/drivers/video/sis/oem300.h
--- a/drivers/video/sis/oem300.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/sis/oem300.h	Wed Jul 24 14:03:37 2002
@@ -1,397 +1,606 @@
-UCHAR SiS300_TVEdge1[3][2] = {
-	{0x0, 0x4},
-	{0x0, 0x4},
-	{0x0, 0x0}
-};
-
-UCHAR SiS300_OEMTVDelay[8][4] = {
-	{0x08, 0x08, 0x08, 0x08},
-	{0x08, 0x08, 0x08, 0x08},
-	{0x08, 0x08, 0x08, 0x08},
-	{0x2c, 0x2c, 0x2c, 0x2c},
-	{0x08, 0x08, 0x08, 0x08},
-	{0x08, 0x08, 0x08, 0x08},
-	{0x08, 0x08, 0x08, 0x08},
-	{0x20, 0x20, 0x20, 0x20}
-};
 
-UCHAR SiS300_OEMTVFlicker[8][4] = {
-	{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}
-};
+/* OEM Data for 300 series */
 
-UCHAR SiS300_OEMLCDDelay1[12][4] = {
-	{0x2c, 0x2c, 0x2c, 0x2c},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x2c, 0x2c, 0x2c, 0x2c},
-	{0x2c, 0x2c, 0x2c, 0x2c},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x24, 0x24, 0x24, 0x24},
-	{0x24, 0x24, 0x24, 0x24},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x24, 0x24, 0x24, 0x24}
+UCHAR SiS300_OEMTVDelay301[8][4] =
+{
+	{0x08,0x08,0x08,0x08},
+	{0x08,0x08,0x08,0x08},
+	{0x08,0x08,0x08,0x08},
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x08,0x08,0x08,0x08},
+	{0x08,0x08,0x08,0x08},
+	{0x08,0x08,0x08,0x08},
+	{0x20,0x20,0x20,0x20}
+};
+
+UCHAR SiS300_OEMTVDelayLVDS[8][4] =
+{
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20}
+};
+
+UCHAR SiS300_OEMTVFlicker[8][4] =
+{
+	{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}
+};
+
+#if 0   /* TW: Not used */
+UCHAR SiS300_OEMLCDDelay1[12][4]={
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x24,0x24,0x24,0x24},
+	{0x24,0x24,0x24,0x24},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x24,0x24,0x24,0x24}
+};
+#endif
+
+/* TW: From 630/301B BIOS */
+UCHAR SiS300_OEMLCDDelay2[64][4] =		 /* for 301/301b/302b/301LV/302LV */
+{
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20}
+};
+
+/* TW: Added for LVDS */
+UCHAR SiS300_OEMLCDDelay3[32][4] = {	/* For LVDS */
+	{0x20,0x20,0x20,0x20},  /* --- Expanding panels */
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x04,0x04,0x04,0x04},		/* Clevo 2202 (PanelType 12); Mitac needs 0x20! */
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},  	/* Uniwill N241S2 (PanelType 14)*/
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},  /* ---- NonExpanding panels */
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x04,0x04,0x04,0x04},          /* Gericom 2200C (PanelType 28) */
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20}
+};
+
+UCHAR SiS300_Phase1[8][6][4] =
+{
+    {
+	{0x21,0xed,0x00,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x21,0xed,0x00,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    }
+};
+
+
+UCHAR SiS300_Phase2[8][6][4] =
+{
+    {
+        {0x21,0xed,0x00,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x21,0xed,0x00,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+        {0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+    }
+};
+
+UCHAR SiS300_Filter1[10][17][4] =
+{
+    {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+    },
+    {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+    },
+};
+
+UCHAR SiS300_Filter2[10][9][7] =
+{
+    {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+    },
+    {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+    },
+    {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+    },
+    {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+    },
+    {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+    },
+    {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+    },
+    {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+    },
+    {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+    },
+    {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+    },
+    {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+    }
 };
 
-UCHAR SiS300_OEMLCDDelay2[32][4] = {
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20}
-};
-
-UCHAR SiS300_StNTSCPhase[6][4] = {
-	{0x21, 0xed, 0x00, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StPALPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StSCARTPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StHiTVPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtNTSCPhase[6][4] = {
-	{0x21, 0xed, 0x00, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtPALPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtSCARTPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtHiTVPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StNTSCFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StPALFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StSCARTFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StHiTVFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtNTSCFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtPALFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtSCARTFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtHiTVFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_NTSCFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-};
-
-UCHAR SiS300_PALFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-};
-
-UCHAR SiS300_PALMFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_PALNFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_PALMFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-};
-
-UCHAR SiS300_PALNFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-};
diff -Nru a/drivers/video/sis/oem310.h b/drivers/video/sis/oem310.h
--- a/drivers/video/sis/oem310.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/video/sis/oem310.h	Wed Jul 24 14:03:35 2002
@@ -1,204 +1,262 @@
-UCHAR SiS310_CRT2DelayCompensation1 = 0x4;	/* 301A */
 
-UCHAR SiS310_LCDDelayCompensation1[] = { 
-	0x0, 0x0, 0x0, 0xb, 0xb, 0xb, 0x8, 0x8, 
-	0x8, 0x8, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 
-	0x0, 0x0, 0x0, 0x0, 0x0 
-};
-	
-UCHAR SiS310_TVDelayCompensation1[] = { 0x2, 0x2, 0x2, 0x2, 0x8, 0xb };
-UCHAR SiS310_CRT2DelayCompensation2 = 0xC;	/* 301B */
-UCHAR SiS310_LCDDelayCompensation2[] = {
-	0x0, 0x0, 0x0, 0x0C, 0x0C, 0x0C, 0x0C, 
-	0x0C, 0x0C, 0x8, 0x8, 0x8, 0x0, 0x0, 
-	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
-};
-
-UCHAR SiS310_TVDelayCompensation2[] = { 0x3, 0x3, 0x3, 0x3, 0x8, 0xb };
-
-UCHAR SiS310_TVAntiFlick1[3][2] = {
-	{0x4, 0x0},
-	{0x4, 0x8},
-	{0x0, 0x0}
-};
-
-UCHAR SiS310_TVEdge1[3][2] = {
-	{0x0, 0x4},
-	{0x0, 0x4},
-	{0x0, 0x0}
-};
-
-UCHAR SiS310_TVYFilter1[3][8][4] = {
-	{
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xeb, 0x4, 0x25, 0x18},
-	 {0xf7, 0x6, 0x19, 0x14},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xeb, 0x4, 0x25, 0x18},
-	 {0xee, 0xc, 0x22, 0x8},
-	 {0xeb, 0x15, 0x25, 0xf6}
-	 }
-	,
-	{
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xf1, 0xf7, 0x1f, 0x32},
-	 {0xf3, 0x0, 0x1d, 0x20},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xf1, 0xf7, 0x1f, 0x32},
-	 {0xf3, 0x0, 0x1d, 0x20},
-	 {0xfc, 0xfb, 0x14, 0x2a}
-	}
-	,
-	{
-	 {0x0, 0x0, 0x0, 0x0},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xeb, 0x4, 0x25, 0x18},
-	 {0xf7, 0x6, 0x19, 0x14},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xeb, 0x4, 0x25, 0x18},
-	 {0xee, 0xc, 0x22, 0x8}
-	}
-};
-
-/*301b*/
-UCHAR SiS310_TVYFilter2[3][9][7] = {
-	{
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	 {0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-	 }
-	,
-	{
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	 {0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-	}
-	,
-	{
-
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22}
-	}
-};
-/*end 301b*/
-/*add PALMN*/
-
-UCHAR SiS310_PALMFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS310_PALNFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS310_PALMFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-};
-
-UCHAR SiS310_PALNFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-};
-
-/*end PALMN*/
-UCHAR SiS310_TVPhaseIncr1[3][2][4] = {
-	{
-	 {0x21, 0xed, 0x8a, 0x8},
-	 {0x21, 0xed, 0x8a, 0x8}
-	 }
-	,
-	{
-	 {0x2a, 0x5, 0xd3, 0x0},
-	 {0x2a, 0x5, 0xd3, 0x0}
-	 }
-	,
-	{
-	 {0x2a, 0x5, 0xd3, 0x0},
-	 {0x2a, 0x5, 0xd3, 0x0}
-	 }
-};
-
-UCHAR SiS310_TVPhaseIncr2[3][2][4] = {
-	{
-	 {0x21, 0xF0, 0x7b, 0xd6},
-	 {0x21, 0xF0, 0x7b, 0xd6}
-	 }
-	,
-	{
-	 {0x2a, 0x09, 0x86, 0xe9},
-	 {0x2a, 0x09, 0x86, 0xe9}
-	 }
-	,
-	{
-	 {0x2a, 0x5, 0xd3, 0x0},
-	 {0x2a, 0x5, 0xd3, 0x0}
-	 }
+/* OEM Data for 300 series */
+
+UCHAR SiS310_CRT2DelayCompensation1 = 0x04; /* 301A */
+
+UCHAR SiS310_LCDDelayCompensation1[] =
+{
+		 0x00,0x00,0x00,
+		 0x0b,0x0b,0x0b,
+		 0x08,0x08,0x08,
+		 0x08,0x08,0x08,
+		 0x00,0x00,0x00,
+		 0x00,0x00,0x00,
+		 0x00,0x00,0x00
+};
+
+UCHAR SiS310_TVDelayCompensation1[] =
+{
+		  0x02,0x02,    /* NTSC Enhanced, Standard */
+                  0x02,0x02,    /* PAL */
+		  0x08,0x0b     /* HiVision */
+};
+
+UCHAR SiS310_CRT2DelayCompensation2 = 0x00;   /* TW: From 650/301LV BIOS; was 0x0C; */      /* 301B */
+
+UCHAR SiS310_LCDDelayCompensation2[] =
+{
+		  0x01,0x01,0x01,   /* TW: From 650/301LV BIOS */
+		  0x01,0x01,0x01,
+		  0x01,0x01,0x01,
+		  0x01,0x01,0x01,
+		  0x01,0x01,0x01,
+		  0x01,0x01,0x01,
+		  0x01,0x01,0x01
+#if 0
+		  0x00,0x00,0x00,   /* 800x600 VESA, non-VESA, non-expanding */
+		  0x0C,0x0C,0x0C,   /* 1024x768 */
+		  0x0C,0x0C,0x0C,   /* 1280x1024 */
+		  0x08,0x08,0x08,   /* 1280x960 */
+		  0x00,0x00,0x00,   /* 640x480 */
+		  0x00,0x00,0x00,   /* 1600x1200 */
+		  0x00,0x00,0x00    /* 1920x1440 */
+#endif
+};
+
+UCHAR SiS310_TVDelayCompensation2[] =
+{
+		  0x05,0x05,        /* TW: From 650/301LV BIOS */
+		  0x05,0x05,
+		  0x05,0x05
+#if 0
+		  0x03,0x03,        /* NTSC Enhanced, Standard */
+                  0x03,0x03,        /* PAL */
+		  0x08,0x0b         /* HiVision */
+#endif
+};
+
+UCHAR SiS310_CRT2DelayCompensation3 = 0x00;   /* LVDS */
+
+UCHAR SiS310_LCDDelayCompensation3[] =
+{
+                   0x00,0x00,0x00,  /* 800x600 */
+		   0x00,0x00,0x00,  /* 1024x768 */
+		   0x00,0x00,0x00,  /* 1280x1024 */
+		   0x00,0x00,0x00,  /* 1400x1050 */
+		   0x00,0x00,0x00   /* 1600x1200 */
+};
+
+UCHAR SiS310_TVDelayCompensation3[] =
+{
+		   0x0a,0x0a,
+		   0x0a,0x0a,
+		   0x0a,0x0a
+};
+
+UCHAR SiS310_TVAntiFlick1[3][2] =
+{
+            {0x4,0x0},
+	    {0x4,0x8},
+	    {0x0,0x0}
+};
+
+UCHAR SiS310_TVEdge1[3][2] =
+{
+            {0x0,0x4},
+	    {0x0,0x4},
+	    {0x0,0x0}
+};
+
+UCHAR SiS310_TVYFilter1[3][8][4] =
+{
+ {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xf1,0x04,0x1f,0x18},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xee,0x0c,0x22,0x08},
+	{0xeb,0x15,0x25,0xf6}
+ },
+ {
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0xfc,0xfb,0x14,0x2a}
+ },
+ {
+	{0x00,0x00,0x00,0x00},
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xee,0x0c,0x22,0x08}
+ }
+};
+
+UCHAR SiS310_TVYFilter2[3][9][7] =
+{
+ {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+ },
+ {
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+ },
+ {
+	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}
+ }
+};
+
+UCHAR SiS310_PALMFilter[17][4] =
+{
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+};
+
+UCHAR SiS310_PALNFilter[17][4] =
+{
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+};
+
+
+UCHAR SiS310_PALMFilter2[9][7] =
+{
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+};
+
+UCHAR SiS310_PALNFilter2[9][7] =
+{
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+};
+
+UCHAR SiS310_TVPhaseIncr1[3][2][4]=
+{
+ {
+	{0x21,0xed,0xba,0x08},
+	{0x21,0xed,0xba,0x08}
+ },
+ {
+	{0x2a,0x05,0xe3,0x00},
+	{0x2a,0x05,0xe3,0x00}
+ },
+ {
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00}
+ }
+};
+
+UCHAR SiS310_TVPhaseIncr2[3][2][4]=
+{
+ {
+	{0x21,0xF1,0x37,0x56},
+	{0x21,0xF1,0x37,0x56}
+ },
+ {
+	{0x2a,0x09,0x86,0xe9},
+	{0x2a,0x09,0x86,0xe9}
+ },
+ {
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00}
+ }
 };
+
+
+
diff -Nru a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
--- a/drivers/video/sis/osdef.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/video/sis/osdef.h	Wed Jul 24 14:03:35 2002
@@ -1,37 +1,159 @@
-#define LINUX_KERNEL
+/* #define WINCE_HEADER */
+/* #define WIN2000 */
+/* #define TC */
+#define LINUX_KERNEL	   /* Kernel framebuffer */
+/* #define LINUX_XF86 */   /* XFree86 */
 
+/**********************************************************************/
+#ifdef LINUX_KERNEL
+	#include <linux/config.h>
+	#ifdef CONFIG_FB_SIS_300
+ 		#define SIS300
+	#endif
+
+	#ifdef CONFIG_FB_SIS_315
+		#define SIS315H
+	#endif
+#else
+/*	#define SIS300*/
+	#define SIS315H
+#endif
+#ifdef LINUX_XF86
+	#define SIS300
+	/* #define SIS315H */ /* TW: done above */
+#endif
+
+/**********************************************************************/
+#ifdef TC
+#endif
+#ifdef WIN2000
+#endif
+#ifdef WINCE_HEADER
+#endif
+#ifdef LINUX_XF86
+#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);
+#endif
+#ifdef WINCE_HEADER
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
+#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)
+#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_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
+#endif
+#ifdef LINUX_KERNEL
+#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
+#endif
 
 /**********************************************************************/
 
 #ifdef OutPortByte
 #undef OutPortByte
-#endif				/* OutPortByte */
+#endif /* OutPortByte */
 
 #ifdef OutPortWord
 #undef OutPortWord
-#endif				/* OutPortWord */
+#endif /* OutPortWord */
 
 #ifdef OutPortLong
 #undef OutPortLong
-#endif				/* OutPortLong */
+#endif /* OutPortLong */
 
 #ifdef InPortByte
 #undef InPortByte
-#endif				/* InPortByte */
+#endif /* InPortByte */
 
 #ifdef InPortWord
 #undef InPortWord
-#endif				/* InPortWord */
+#endif /* InPortWord */
 
 #ifdef InPortLong
 #undef InPortLong
-#endif				/* InPortLong */
+#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                                                        */
+/**********************************************************************/
+
+#ifdef LINUX_XF86
+#define OutPortByte(p,v) outb((CARD16)(p),(CARD8)(v))
+#define OutPortWord(p,v) outw((CARD16)(p),(CARD16)(v))
+#define OutPortLong(p,v) outl((CARD16)(p),(CARD32)(v))
+#define InPortByte(p)    inb((CARD16)(p))
+#define InPortWord(p)    inw((CARD16)(p))
+#define InPortLong(p)    inl((CARD16)(p))
+#endif
+
+#ifdef LINUX_KERNEL
 #define OutPortByte(p,v) outb((u8)(v),(u16)(p))
 #define OutPortWord(p,v) outw((u16)(v),(u16)(p))
 #define OutPortLong(p,v) outl((u32)(v),(u16)(p))
 #define InPortByte(p)    inb((u16)(p))
 #define InPortWord(p)    inw((u16)(p))
 #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
diff -Nru a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
--- a/drivers/video/sis/sis_main.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/sis/sis_main.c	Wed Jul 24 14:03:38 2002
@@ -1,16 +1,26 @@
 /*
- * SiS 300/630/540/315H/315 frame buffer device For Kernal 2.4.x
+ * SiS 300/630/730/540/315/550/650/740 frame buffer device
+ * for Linux kernels 2.4.x and 2.5.x
  *
- * This driver is partly based on the VBE 2.0 compliant graphic 
- * boards framebuffer driver, which is 
- * 
- * (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ * Partly 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>:
+ *			- many fixes and enhancements for 630 & 310/325 series,
+ *			- extended bridge handling, TV output for Chrontel
+ *                      - 650/LVDS support (for LCD panels up to 1400x1050)
+ *                      - 650/Chrontel 7019 support
+ *                      - 301B/301LV LCD and TV support
+ *			- memory queue handling enhancements,
+ *			- everything marked with "TW"
+ *			(see http://www.winischhofer.net/linuxsis630.shtml
+ *			for more information and updates)
  */
 
-//#undef SISFBDEBUG
-
 #include <linux/config.h>
+#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -29,11 +39,12 @@
 #include <linux/capability.h>
 #include <linux/fs.h>
 #include <linux/agp_backend.h>
+
 #include <linux/types.h>
 #include <linux/sisfb.h>
 
 #include <asm/io.h>
-#include <asm/mtrr.h>
+#include <asm/mtrr.h> 
 
 #include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
@@ -44,9 +55,13 @@
 #include "osdef.h"
 #include "vgatypes.h"
 #include "sis_main.h"
+//#ifdef LINUXBIOS
+//#include "bios.h"
+//#endif
 
 /* -------------------- Macro definitions ---------------------------- */
-
+// #define SISFBDEBUG
+#undef SISFBDEBUG /* TW */
 #ifdef SISFBDEBUG
 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
 #else
@@ -64,71 +79,88 @@
 
 /* --------------- Hardware Access Routines -------------------------- */
 
-void sisfb_set_reg1 (u16 port, u16 index, u16 data)
+void sisfb_set_reg1(u16 port, u16 index, u16 data)
 {
-	outb ((u8) (index & 0xff), port);
+	outb((u8) (index & 0xff), port);
 	port++;
-	outb ((u8) (data & 0xff), port);
+	outb((u8) (data & 0xff), port);
 }
 
-void sisfb_set_reg3 (u16 port, u16 data)
+void sisfb_set_reg3(u16 port, u16 data)
 {
-	outb ((u8) (data & 0xff), port);
+	outb((u8) (data & 0xff), port);
 }
 
-void sisfb_set_reg4 (u16 port, unsigned long data)
+void sisfb_set_reg4(u16 port, unsigned long data)
 {
-	outl ((u32) (data & 0xffffffff), port);
+	outl((u32) (data & 0xffffffff), port);
 }
 
-u8 sisfb_get_reg1 (u16 port, u16 index)
+u8 sisfb_get_reg1(u16 port, u16 index)
 {
 	u8 data;
 
-	outb ((u8) (index & 0xff), port);
+	outb((u8) (index & 0xff), port);
 	port += 1;
-	data = inb (port);
+	data = inb(port);
 	return (data);
 }
 
-u8 sisfb_get_reg2 (u16 port)
+u8 sisfb_get_reg2(u16 port)
 {
 	u8 data;
 
-	data = inb (port);
-
+	data = inb(port);
 	return (data);
 }
 
-u32 sisfb_get_reg3 (u16 port)
+u32 sisfb_get_reg3(u16 port)
 {
 	u32 data;
 
-	data = inl (port);
+	data = inl(port);
 	return (data);
 }
 
+// Eden Chen
+//void sisfb_clear_DAC(u16 port)
+//{
+//	int i,j;
+//
+//	vgawb(DAC_ADR, 0x00);
+//	for(i=0; i<256; i++)
+//		for(j=0; j<3; j++)
+//			vgawb(DAC_DATA, 0);
+//}
+
+//void sisfb_clear_buffer(PHW_DEVICE_EXTENSION psishw_ext)
+//{
+//	memset((char *) ivideo.video_vbase, 0,
+//		video_linelength * ivideo.video_height);
+//}
+// ~Eden Chen
+
 /* --------------- Interface to BIOS code ---------------------------- */
 
-BOOLEAN sisfb_query_VGA_config_space (PSIS_HW_DEVICE_INFO psishw_ext,
-			      unsigned long offset, unsigned long set,
-			      unsigned long *value)
+BOOLEAN
+sisfb_query_VGA_config_space(PSIS_HW_DEVICE_INFO psishw_ext,
+	unsigned long offset, unsigned long set, unsigned long *value)
 {
 	static struct pci_dev *pdev = NULL;
 	static unsigned char init = 0, valid_pdev = 0;
 
 	if (!set)
-		DPRINTK ("Get VGA offset 0x%lx\n", offset);
+		DPRINTK("sisfb: Get VGA offset 0x%lx\n", offset);
 	else
-		DPRINTK ("Set offset 0x%lx to 0x%lx\n", offset, *value);
+		DPRINTK("sisfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
 
 	if (!init) {
 		init = TRUE;
-		pci_for_each_dev (pdev) {
-			DPRINTK ("Current: 0x%x, target: 0x%x\n", pdev->device,
-				 ivideo.chip_id);
+		pci_for_each_dev(pdev) {
+			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)) {
+			           && (pdev->device == ivideo.chip_id)) {
 				valid_pdev = TRUE;
 				break;
 			}
@@ -136,22 +168,21 @@
 	}
 
 	if (!valid_pdev) {
-		printk (KERN_DEBUG "Can't find SiS %d VGA device.\n",
-			ivideo.chip_id);
+		printk(KERN_DEBUG "sisfb: Can't find SiS %d VGA device.\n",
+				ivideo.chip_id);
 		return FALSE;
 	}
 
 	if (set == 0)
-		pci_read_config_dword (pdev, offset, (u32 *) value);
+		pci_read_config_dword(pdev, offset, (u32 *)value);
 	else
-		pci_write_config_dword (pdev, offset, (u32) (*value));
+		pci_write_config_dword(pdev, offset, (u32)(*value));
 
 	return TRUE;
 }
 
-BOOLEAN sisfb_query_north_bridge_space (PSIS_HW_DEVICE_INFO psishw_ext,
-				unsigned long offset, unsigned long set,
-				unsigned long *value)
+BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext,
+	unsigned long offset, unsigned long set, unsigned long *value)
 {
 	static struct pci_dev *pdev = NULL;
 	static unsigned char init = 0, valid_pdev = 0;
@@ -172,16 +203,19 @@
 		case SIS_550:
 			nbridge_id = PCI_DEVICE_ID_SI_550;
 			break;
+		case SIS_650:
+			nbridge_id = PCI_DEVICE_ID_SI_650;
+			break;
 		default:
 			nbridge_id = 0;
 			break;
 		}
 
-		pci_for_each_dev (pdev) {
-			DPRINTK ("Current: 0x%x, target: 0x%x\n", pdev->device,
-				 ivideo.chip_id);
+		pci_for_each_dev(pdev) {
+			DPRINTK("Current: 0x%x, target: 0x%x\n",
+					pdev->device, ivideo.chip_id);
 			if ((pdev->vendor == PCI_VENDOR_ID_SI)
-			    && (pdev->device == nbridge_id)) {
+					&& (pdev->device == nbridge_id)) {
 				valid_pdev = TRUE;
 				break;
 			}
@@ -189,68 +223,77 @@
 	}
 
 	if (!valid_pdev) {
-		printk (KERN_DEBUG "Can't find SiS %d North Bridge device.\n",
-			nbridge_id);
+		printk(KERN_DEBUG "sisfb: Can't find SiS %d North Bridge device.\n",
+				nbridge_id);
 		return FALSE;
 	}
 
 	if (set == 0)
-		pci_read_config_dword (pdev, offset, (u32 *) value);
+		pci_read_config_dword(pdev, offset, (u32 *)value);
 	else
-		pci_write_config_dword (pdev, offset, (u32) (*value));
+		pci_write_config_dword(pdev, offset, (u32)(*value));
 
 	return TRUE;
 }
 
 /* -------------------- Export functions ----------------------------- */
 
-static void sis_get_glyph (struct fb_info *info, SIS_GLYINFO * gly)
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
+static void sis_get_glyph(SIS_GLYINFO *gly)
+#else
+static void sis_get_glyph(struct fb_info *info, SIS_GLYINFO *gly)
+#endif
 {
-	struct display *p = &fb_display[info->currcon];
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
+	struct display *p = &fb_display[currcon];
+#else
+        struct display *p = &fb_display[info->currcon];
+#endif
 	u16 c;
 	u8 *cdat;
 	int widthb;
 	u8 *gbuf = gly->gmask;
 	int size;
 
-	gly->fontheight = fontheight (p);
-	gly->fontwidth = fontwidth (p);
-	widthb = (fontwidth (p) + 7) / 8;
+
+	gly->fontheight = fontheight(p);
+	gly->fontwidth = fontwidth(p);
+	widthb = (fontwidth(p) + 7) / 8;
 
 	c = gly->ch & p->charmask;
-	if (fontwidth (p) <= 8)
-		cdat = p->fontdata + c * fontheight (p);
+	if (fontwidth(p) <= 8)
+		cdat = p->fontdata + c * fontheight(p);
 	else
-		cdat = p->fontdata + (c * fontheight (p) << 1);
+		cdat = p->fontdata + (c * fontheight(p) << 1);
 
-	size = fontheight (p) * widthb;
-	memcpy (gbuf, cdat, size);
+	size = fontheight(p) * widthb;
+	memcpy(gbuf, cdat, size);
 	gly->ngmask = size;
 }
 
-void sis_dispinfo (struct ap_data *rec)
+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.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.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;
 }
 
 /* ------------------ Internal Routines ------------------------------ */
 
-static void sisfb_search_mode (const char *name)
+static void sisfb_search_mode(const char *name)
 {
 	int i = 0;
 
@@ -258,64 +301,66 @@
 		return;
 
 	while (sisbios_mode[i].mode_no != 0) {
-		if (!strcmp (name, sisbios_mode[i].name)) {
+		if (!strcmp(name, sisbios_mode[i].name)) {
 			sisfb_mode_idx = i;
 			break;
 		}
 		i++;
 	}
-
 	if (sisfb_mode_idx < 0)
-		DPRINTK ("Invalid user mode : %s\n", name);
+		printk(KERN_INFO "sisfb: Invalid mode '%s'\n", name);
 }
 
-static void sisfb_validate_mode (void)
+static void sisfb_validate_mode(void)
 {
+   u16 xres, yres;
+
 	switch (ivideo.disp_state & DISPTYPE_DISP2) {
 	case DISPTYPE_LCD:
-// Eden Chen
-		switch (sishw_ext.ulCRT2LCDType) {
+	    switch (sishw_ext.ulCRT2LCDType) {
 		case LCD_1024x768:
-			if (sisbios_mode[sisfb_mode_idx].xres > 1024)
-				sisfb_mode_idx = -1;
-			break;
+			xres = 1024; yres =  768;  break;
 		case LCD_1280x1024:
+		        xres = 1280; yres = 1024;  break;
 		case LCD_1280x960:
-			if (sisbios_mode[sisfb_mode_idx].xres > 1280)
-				sisfb_mode_idx = -1;
-			break;
+	                xres = 1280; yres =  960;  break;
 		case LCD_2048x1536:
-			if (sisbios_mode[sisfb_mode_idx].xres > 2048)
-				sisfb_mode_idx = -1;
-			break;
+		        xres = 2048; yres = 1536;  break;
 		case LCD_1920x1440:
-			if (sisbios_mode[sisfb_mode_idx].xres > 1920)
-				sisfb_mode_idx = -1;
-			break;
+			xres = 1920; yres = 1440;  break;
 		case LCD_1600x1200:
-			if (sisbios_mode[sisfb_mode_idx].xres > 1600)
-				sisfb_mode_idx = -1;
-			break;
+			xres = 1600; yres = 1200;  break;
 		case LCD_800x600:
-			if (sisbios_mode[sisfb_mode_idx].xres > 800)
-				sisfb_mode_idx = -1;
-			break;
+			xres =  800; yres =  600;  break;
 		case LCD_640x480:
-			if (sisbios_mode[sisfb_mode_idx].xres > 640)
-				sisfb_mode_idx = -1;
-			break;
+			xres =  640; yres =  480;  break;
+		case LCD_320x480:	/* TW: FSTN */
+			xres =  320; yres =  480;  break;
+                case LCD_1024x600:
+			xres = 1024; yres =  600;  break;
+		case LCD_1152x864:
+			xres = 1152; yres =  864;  break;
+		case LCD_1152x768:
+			xres = 1152; yres =  768;  break;
+		case LCD_1280x768:
+			xres = 1280; yres =  768;  break;
+		case LCD_1400x1050:
+			xres = 1400; yres = 1050;  break;
 		default:
-			sisfb_mode_idx = -1;
+		        xres =    0; yres =    0;  break;
 		}
-// ~Eden Chen
-
+		if(sisbios_mode[sisfb_mode_idx].xres > xres)
+		        sisfb_mode_idx = -1;
+                if(sisbios_mode[sisfb_mode_idx].yres > yres)
+		        sisfb_mode_idx = -1;
 		if (sisbios_mode[sisfb_mode_idx].xres == 720)
 			sisfb_mode_idx = -1;
 		break;
 	case DISPTYPE_TV:
-		switch (sisbios_mode[sisfb_mode_idx].xres) {
-		case 800:
+	    switch (sisbios_mode[sisfb_mode_idx].xres) {
+	        case 512:
 		case 640:
+		case 800:
 			break;
 		case 720:
 			if (ivideo.TV_type == TVMODE_NTSC) {
@@ -325,12 +370,22 @@
 				if (sisbios_mode[sisfb_mode_idx].yres != 576)
 					sisfb_mode_idx = -1;
 			}
+			/* TW: LVDS/CHRONTEL does not support 720 */
+			if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
+						ivideo.hasVB == HASVB_CHRONTEL)
+					sisfb_mode_idx = -1;
 			break;
-			/*karl */
 		case 1024:
 			if (ivideo.TV_type == TVMODE_NTSC) {
-				if (sisbios_mode[sisfb_mode_idx].bpp == 32)
-					sisfb_mode_idx -= 1;
+				if(sisbios_mode[sisfb_mode_idx].bpp == 32)
+				       sisfb_mode_idx = -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) {
+					sisfb_mode_idx = -1;
+			    }
 			}
 			break;
 		default:
@@ -338,9 +393,51 @@
 		}
 		break;
 	}
+
+	if(ivideo.chip < SIS_315H) {
+             if(sisbios_mode[sisfb_mode_idx].xres > 1920)
+	         sisfb_mode_idx = -1;
+	}
+	/* TW: TODO: Validate modes available on either 300 or 310/325 series only */
 }
 
-static u8 sisfb_search_refresh_rate (unsigned int rate)
+static void sisfb_search_crt2type(const char *name)
+{
+	int i = 0;
+
+	if (name == NULL)
+		return;
+
+	while (sis_crt2type[i].type_no != -1) {
+		if (!strcmp(name, sis_crt2type[i].name)) {
+			sisfb_crt2type = sis_crt2type[i].type_no;
+			break;
+		}
+		i++;
+	}
+	if (sisfb_crt2type < 0)
+		printk(KERN_INFO "sisfb: Invalid CRT2 type: %s\n", name);
+}
+
+static void sisfb_search_queuemode(const char *name)
+{
+	int i = 0;
+
+	if (name == NULL)
+		return;
+
+	while (sis_queuemode[i].type_no != -1) {
+		if (!strcmp(name, 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);
+}
+
+static u8 sisfb_search_refresh_rate(unsigned int rate)
 {
 	u16 xres, yres;
 	int i = 0;
@@ -350,44 +447,39 @@
 
 	sisfb_rate_idx = 0;
 	while ((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
-		if ((sisfb_vrate[i].xres == xres)
-		    && (sisfb_vrate[i].yres == yres)) {
+		if ((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) {
 			if (sisfb_vrate[i].refresh == rate) {
 				sisfb_rate_idx = sisfb_vrate[i].idx;
 				break;
 			} else if (sisfb_vrate[i].refresh > rate) {
 				if ((sisfb_vrate[i].refresh - rate) <= 2) {
-					DPRINTK
-					    ("Adjust rate from %d up to %d\n",
-					     rate, sisfb_vrate[i].refresh);
+					DPRINTK("sisfb: Adjusting rate from %d up to %d\n",
+						rate, sisfb_vrate[i].refresh);
 					sisfb_rate_idx = sisfb_vrate[i].idx;
-					ivideo.refresh_rate =
-					    sisfb_vrate[i].refresh;
-				} else if (((rate - sisfb_vrate[i - 1].refresh) <=  2) 
-				    	&& (sisfb_vrate[i].idx != 1)) {
-					DPRINTK("Adjust rate from %d down to %d\n",
-					     rate, sisfb_vrate[i - 1].refresh);
-					sisfb_rate_idx = sisfb_vrate[i - 1].idx;
-					ivideo.refresh_rate = sisfb_vrate[i - 1].refresh;
+					ivideo.refresh_rate = sisfb_vrate[i].refresh;
+				} else if (((rate - sisfb_vrate[i-1].refresh) <= 2)
+						&& (sisfb_vrate[i].idx != 1)) {
+					DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
+						rate, sisfb_vrate[i-1].refresh);
+					sisfb_rate_idx = sisfb_vrate[i-1].idx;
+					ivideo.refresh_rate = sisfb_vrate[i-1].refresh;
 				}
 				break;
 			}
 		}
 		i++;
 	}
-
 	if (sisfb_rate_idx > 0) {
 		return sisfb_rate_idx;
 	} else {
-		DPRINTK ("Unsupported rate %d for %dx%d mode\n", rate, xres,
-			 yres);
+		printk(KERN_INFO
+			"sisfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
 		return 0;
 	}
-
 }
 
-static int sis_getcolreg (unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
-	       unsigned *transp, struct fb_info *fb_info)
+static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
+			 unsigned *transp, struct fb_info *fb_info)
 {
 	if (regno >= video_cmap_len)
 		return 1;
@@ -399,10 +491,10 @@
 	return 0;
 }
 
-static int sisfb_setcolreg (unsigned regno, unsigned red, unsigned green, unsigned blue,
-	      		    unsigned transp, struct fb_info *fb_info)
-{
 
+static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+                           unsigned transp, struct fb_info *fb_info)
+{
 	if (regno >= video_cmap_len)
 		return 1;
 
@@ -413,17 +505,16 @@
 	switch (ivideo.video_bpp) {
 #ifdef FBCON_HAS_CFB8
 	case 8:
-		vgawb (DAC_ADR, regno);
-		vgawb (DAC_DATA, red >> 10);
-		vgawb (DAC_DATA, green >> 10);
-		vgawb (DAC_DATA, blue >> 10);
+		vgawb(DAC_ADR, regno);
+		vgawb(DAC_DATA, red >> 10);
+		vgawb(DAC_DATA, green >> 10);
+		vgawb(DAC_DATA, blue >> 10);
 		if (ivideo.disp_state & DISPTYPE_DISP2) {
-			vgawb (DAC2_ADR, regno);
-			vgawb (DAC2_DATA, red >> 8);
-			vgawb (DAC2_DATA, green >> 8);
-			vgawb (DAC2_DATA, blue >> 8);
+		 	vgawb(DAC2_ADR,  regno);
+			vgawb(DAC2_DATA, red >> 8);
+			vgawb(DAC2_DATA, green >> 8);
+			vgawb(DAC2_DATA, blue >> 8);
 		}
-
 		break;
 #endif
 #ifdef FBCON_HAS_CFB16
@@ -439,7 +530,8 @@
 		red >>= 8;
 		green >>= 8;
 		blue >>= 8;
-		fbcon_cmap.cfb24[regno] = (red << 16) | (green << 8) | (blue);
+		fbcon_cmap.cfb24[regno] =
+		    (red << 16) | (green << 8) | (blue);
 		break;
 #endif
 #ifdef FBCON_HAS_CFB32
@@ -447,33 +539,44 @@
 		red >>= 8;
 		green >>= 8;
 		blue >>= 8;
-		fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
+		fbcon_cmap.cfb32[regno] =
+		    (red << 16) | (green << 8) | (blue);
 		break;
 #endif
 	}
 	return 0;
 }
 
-static int sisfb_do_set_var (struct fb_var_screeninfo *var, int isactive,
-		  struct fb_info *info)
+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 =
-	    var->upper_margin + var->yres + var->lower_margin + var->vsync_len;
+		var->left_margin + var->xres + var->right_margin +
+		var->hsync_len;
+	unsigned int vtotal = 0; /* TW */
+	/*	var->upper_margin + var->yres + var->lower_margin +
+		var->vsync_len;     */
 	double drate = 0, hrate = 0;
 	int found_mode = 0;
 	int old_mode;
 
-	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
+	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
+		vtotal = var->upper_margin + var->yres + var->lower_margin +
+		         var->vsync_len;   /* TW */
 		vtotal <<= 1;
-	else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
+	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+		vtotal = var->upper_margin + var->yres + var->lower_margin +
+		         var->vsync_len;   /* TW */
 		vtotal <<= 2;
-	else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
-		var->yres <<= 1;
+	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
+		         var->vsync_len;   /* TW */
+		/* var->yres <<= 1; */ /* TW */
+	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +
+		         var->vsync_len;
 
-	if (!htotal || !vtotal) {
-		DPRINTK ("Invalid 'var' Information!\n");
+	if (!(htotal) || !(vtotal)) {
+		DPRINTK("sisfb: Invalid 'var' information\n");
 		return -EINVAL;
 	}
 
@@ -481,19 +584,17 @@
 	hrate = drate / htotal;
 	ivideo.refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
 
-	DPRINTK ("Chagne mode to %dx%dx%d-%dMHz\n",
-		 var->xres, var->yres, var->bits_per_pixel,
-		 ivideo.refresh_rate);
+	printk("sisfb: Change mode to %dx%dx%d-%dHz\n",
+		var->xres,var->yres,var->bits_per_pixel,ivideo.refresh_rate);
 
 	old_mode = sisfb_mode_idx;
 	sisfb_mode_idx = 0;
 
-	while ((sisbios_mode[sisfb_mode_idx].mode_no != 0)
-	       && (sisbios_mode[sisfb_mode_idx].xres <= var->xres)) {
-		if ((sisbios_mode[sisfb_mode_idx].xres == var->xres)
-		    && (sisbios_mode[sisfb_mode_idx].yres == var->yres)
-		    && (sisbios_mode[sisfb_mode_idx].bpp ==
-			var->bits_per_pixel)) {
+	while( (sisbios_mode[sisfb_mode_idx].mode_no != 0) &&
+	       (sisbios_mode[sisfb_mode_idx].xres <= var->xres) ) {
+		if( (sisbios_mode[sisfb_mode_idx].xres == var->xres) &&
+		    (sisbios_mode[sisfb_mode_idx].yres == var->yres) &&
+		    (sisbios_mode[sisfb_mode_idx].bpp == var->bits_per_pixel)) {
 			sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
 			found_mode = 1;
 			break;
@@ -502,83 +603,66 @@
 	}
 
 	if (found_mode)
-		sisfb_validate_mode ();
+		sisfb_validate_mode();
 	else
 		sisfb_mode_idx = -1;
 
-	if (sisfb_mode_idx < 0) {
-		DPRINTK ("sisfb does not support mode %dx%d-%d\n", var->xres,
-			 var->yres, var->bits_per_pixel);
+       	if (sisfb_mode_idx < 0) {
+		printk("sisfb: Mode %dx%d-%d not supported\n", var->xres,
+		       var->yres, var->bits_per_pixel);
 		sisfb_mode_idx = old_mode;
 		return -EINVAL;
 	}
 
-	if (sisfb_search_refresh_rate (ivideo.refresh_rate) == 0) {
+	if (sisfb_search_refresh_rate(ivideo.refresh_rate) == 0) {
 		sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
 		ivideo.refresh_rate = 60;
 	}
 
 	if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
-		sisfb_pre_setmode ();
 
-// Eden Chen
-/*
-#ifdef CONFIG_FB_SIS_300
-		if (SiSSetMode(&sishw_ext, sisfb_mode_no)) {
-			DPRINTK("set mode[0x%x]: failed\n", sisfb_mode_no);
-			return -1;
-		}
-#endif
+		sisfb_pre_setmode();
 
-#ifdef CONFIG_FB_SIS_315
-		if (SiSSetMode310(&sishw_ext, sisfb_mode_no)) {
-			DPRINTK("set mode[0x%x]: failed\n", sisfb_mode_no);
+		if (SiSSetMode(&sishw_ext, sisfb_mode_no) == 0) {
+			printk("sisfb: Setting mode[0x%x] failed\n", sisfb_mode_no);
 			return -1;
 		}
 
-#endif
-*/
-		if (SiSSetMode (&sishw_ext, sisfb_mode_no) == 0) {
-			DPRINTK ("set mode[0x%x]: failed\n", sisfb_mode_no);
-			return -1;
-		}
+		vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+		vgawb(SEQ_DATA, SIS_PASSWORD);
 
-		vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-		vgawb (SEQ_DATA, SIS_PASSWORD);
-// ~Eden Chen
-		sisfb_post_setmode ();
+		sisfb_post_setmode();
 
-		DPRINTK ("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);
+		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;
+		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;
 		video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
-
 	}
 	return 0;
 }
 
-static void sisfb_set_disp (int con, struct fb_var_screeninfo *var)
+static void sisfb_set_disp(int con, struct fb_var_screeninfo *var)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
 	struct display_switch *sw;
-	u32 flags;
+	long flags;
 
 	if (con >= 0)
 		display = &fb_display[con];
 	else
-		display = &disp;
+		display = &disp;	
 
-	sisfb_get_fix (&fix, con, 0);
+	sisfb_get_fix(&fix, con, 0);
 
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
+	display->screen_base = ivideo.video_vbase;
+#endif
 	display->visual = fix.visual;
 	display->type = fix.type;
 	display->type_aux = fix.type_aux;
@@ -590,139 +674,147 @@
 	display->inverse = sisfb_inverse;
 	display->var = *var;
 
-	save_flags (flags);
+	save_flags(flags);
 	switch (ivideo.video_bpp) {
 #ifdef FBCON_HAS_CFB8
-	case 8:
+	   case 8:
 		sw = &fbcon_cfb8;
 		break;
 #endif
 #ifdef FBCON_HAS_CFB16
-	case 15:
-	case 16:
+	   case 15:
+	   case 16:
 		sw = &fbcon_cfb16;
 		display->dispsw_data = fbcon_cmap.cfb16;
 		break;
 #endif
 #ifdef FBCON_HAS_CFB24
-	case 24:
+	   case 24:
 		sw = &fbcon_cfb24;
 		display->dispsw_data = fbcon_cmap.cfb24;
 		break;
 #endif
 #ifdef FBCON_HAS_CFB32
-	case 32:
+	   case 32:
 		sw = &fbcon_cfb32;
 		display->dispsw_data = fbcon_cmap.cfb32;
 		break;
 #endif
-	default:
+	   default:
 		sw = &fbcon_dummy;
 		return;
 	}
-	memcpy (&sisfb_sw, sw, sizeof (*sw));
+	memcpy(&sisfb_sw, sw, sizeof(*sw));
 	display->dispsw = &sisfb_sw;
-	restore_flags (flags);
+	restore_flags(flags);
 
 	display->scrollmode = SCROLL_YREDRAW;
 	sisfb_sw.bmove = fbcon_redraw_bmove;
 }
 
-static void sisfb_do_install_cmap (int con, struct fb_info *info)
+static void sisfb_do_install_cmap(int con, struct fb_info *info)
 {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
 	if (con != info->currcon)
 		return;
 
-	if (fb_display[con].cmap.len)
-		fb_set_cmap (&fb_display[con].cmap, 1, info);
-	else
-		fb_set_cmap (fb_default_cmap (video_cmap_len), 1, info);
+        if (fb_display[con].cmap.len)
+                fb_set_cmap(&fb_display[con].cmap, 1, info);
+        else
+		fb_set_cmap(fb_default_cmap(video_cmap_len), 1, info);
+#else
+        if (con != currcon)
+		return;
+
+        if (fb_display[con].cmap.len)
+		fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);
+        else
+		fb_set_cmap(fb_default_cmap(video_cmap_len), 1,
+			    sisfb_setcolreg, info);
+#endif
+
 }
 
+
 /* --------------- Chip-dependent Routines --------------------------- */
 
-#ifdef CONFIG_FB_SIS_300	/* for SiS 300/630/540/730 */
-static int sisfb_get_dram_size_300 (void)
+#ifdef CONFIG_FB_SIS_300 /* for SiS 300/630/540/730 */
+static int sisfb_get_dram_size_300(void)
 {
 	struct pci_dev *pdev = NULL;
 	int pdev_valid = 0;
-	u8 pci_data, reg;
+	u8  pci_data, reg;
 	u16 nbridge_id;
 
 	switch (ivideo.chip) {
-	case SIS_540:
+	   case SIS_540:
 		nbridge_id = PCI_DEVICE_ID_SI_540;
 		break;
-	case SIS_630:
+	   case SIS_630:
 		nbridge_id = PCI_DEVICE_ID_SI_630;
 		break;
-	case SIS_730:
+	   case SIS_730:
 		nbridge_id = PCI_DEVICE_ID_SI_730;
 		break;
-	default:
+	   default:
 		nbridge_id = 0;
 		break;
 	}
 
-	if (nbridge_id == 0) {
-		vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE);
+	if (nbridge_id == 0) {  /* 300 */
+		vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
 		ivideo.video_size =
-		    ((unsigned
-		      int) ((vgarb (SEQ_DATA) & SIS_DRAM_SIZE_MASK) + 1) << 20);
-	} else {
-		pci_for_each_dev (pdev) {
-			if ((pdev->vendor == PCI_VENDOR_ID_SI)
-			    && (pdev->device == nbridge_id)) {
-				//&& (pdev->device == PCI_DEVICE_ID_SI_630)) {
-				pci_read_config_byte (pdev, IND_BRI_DRAM_STATUS,
-						      &pci_data);
+		        ((unsigned int) ((vgarb(SEQ_DATA) & SIS_DRAM_SIZE_MASK) + 1) << 20);
+	} else {		/* 540, 630, 730 */
+		pci_for_each_dev(pdev) {
+			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));
+				ivideo.video_size = (unsigned int)(1 << (pci_data+21));
 				pdev_valid = 1;
-
+	
 				reg = SIS_DATA_BUS_64 << 6;
-				vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE);
+				vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
 				switch (pci_data) {
-				case BRI_DRAM_SIZE_2MB:
+				   case BRI_DRAM_SIZE_2MB:
 					reg |= SIS_DRAM_SIZE_2MB;
 					break;
-				case BRI_DRAM_SIZE_4MB:
+				   case BRI_DRAM_SIZE_4MB:
 					reg |= SIS_DRAM_SIZE_4MB;
 					break;
-				case BRI_DRAM_SIZE_8MB:
+				   case BRI_DRAM_SIZE_8MB:
 					reg |= SIS_DRAM_SIZE_8MB;
 					break;
-				case BRI_DRAM_SIZE_16MB:
+				   case BRI_DRAM_SIZE_16MB:
 					reg |= SIS_DRAM_SIZE_16MB;
 					break;
-				case BRI_DRAM_SIZE_32MB:
+				   case BRI_DRAM_SIZE_32MB:
 					reg |= SIS_DRAM_SIZE_32MB;
 					break;
-				case BRI_DRAM_SIZE_64MB:
+				   case BRI_DRAM_SIZE_64MB:
 					reg |= SIS_DRAM_SIZE_64MB;
 					break;
 				}
-				vgawb (SEQ_DATA, reg);
+				vgawb(SEQ_DATA, reg);
 				break;
-			}
-		}
-
+			}  
+		}   
+	
 		if (!pdev_valid)
 			return -1;
 	}
-
 	return 0;
 }
 
-static void sisfb_detect_VB_connect_300(void)
+static void sisfb_detect_VB_connect_300()
 {
 	u8 sr16, sr17, cr32, temp;
 
-	vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_17);
-	sr17 = vgarb (SEQ_DATA);
-	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR32);
-	cr32 = vgarb (CRTC_DATA);
+	vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_17);
+	sr17 = vgarb(SEQ_DATA);
+	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR32);
+	cr32 = vgarb(CRTC_DATA);
 
 	ivideo.TV_plug = ivideo.TV_type = 0;
 	if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
@@ -735,25 +827,29 @@
 				sisfb_crt1off = 0;
 		}
 
-		if (sr17 & 0x08)
+		if (sisfb_crt2type != -1)
+			/* TW: override detected CRT2 type */
+			ivideo.disp_state = sisfb_crt2type;
+		else if (sr17 & 0x08 )
 			ivideo.disp_state = DISPTYPE_CRT2;
 		else if (sr17 & 0x02)
 			ivideo.disp_state = DISPTYPE_LCD;
-		else if (sr17 & 0x04) {
+		else if (sr17 & 0x04)
 			ivideo.disp_state = DISPTYPE_TV;
-			if (sr17 & 0x20)
-				ivideo.TV_plug = TVPLUG_SVIDEO;
-			else if (sr17 & 0x10)
-				ivideo.TV_plug = TVPLUG_COMPOSITE;
-
-			vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_16);
-			sr16 = vgarb (SEQ_DATA);
-			if (sr16 & 0x20)
-				ivideo.TV_type = TVMODE_PAL;
-			else
-				ivideo.TV_type = TVMODE_NTSC;
-		} else
+		else
 			ivideo.disp_state = 0;
+
+		if (sr17 & 0x20)
+			ivideo.TV_plug = TVPLUG_SVIDEO;
+		else if (sr17 & 0x10)
+			ivideo.TV_plug = TVPLUG_COMPOSITE;
+
+		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_16);
+		sr16 = vgarb(SEQ_DATA);
+		if (sr16 & 0x20)
+			ivideo.TV_type = TVMODE_PAL;
+		else
+			ivideo.TV_type = TVMODE_NTSC;
 	} else {
 		if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
 			sisfb_crt1off = 0;
@@ -764,79 +860,97 @@
 				sisfb_crt1off = 0;
 		}
 
-		if (cr32 & SIS_VB_CRT2)
+		if (sisfb_crt2type != -1)
+			/* TW: override detected CRT2 type */
+			ivideo.disp_state = sisfb_crt2type;
+		else if (cr32 & SIS_VB_CRT2)
 			ivideo.disp_state = DISPTYPE_CRT2;
 		else if (cr32 & SIS_VB_LCD)
 			ivideo.disp_state = DISPTYPE_LCD;
-		else if (cr32 & SIS_VB_TV) {
+		else if (cr32 & SIS_VB_TV)
 			ivideo.disp_state = DISPTYPE_TV;
-			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;
+		else
+			ivideo.disp_state = 0;
 
-			if (ivideo.TV_type == 0) {
-				// Eden Chen
-				//temp = *((u8 *)(sishw_ext.VirtualRomBase+0x52));
-				//if (temp&0x40) {
-				//      temp=*((u8 *)(sishw_ext.VirtualRomBase+0x53));
+		/* TW: Detect TV plug & type anyway */
+		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) {
+			// Eden Chen
+			//temp = *((u8 *)(sishw_ext.VirtualRomBase+0x52));
+			//if (temp&0x40) {
+			//	temp=*((u8 *)(sishw_ext.VirtualRomBase+0x53));
 				//} else {
-				vgawb (SEQ_ADR, IND_SIS_POWER_ON_TRAP);
-				temp = vgarb (SEQ_DATA);
-				//}
-				// ~Eden Chen
-				if (temp & 0x01)
-					ivideo.TV_type = TVMODE_PAL;
-				else
-					ivideo.TV_type = TVMODE_NTSC;
-			}
-		} else
-			ivideo.disp_state = 0;
+			vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP);
+			temp = vgarb(SEQ_DATA);
+			//}
+			// ~Eden Chen
+			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) {
+		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_17);
+    		sr17 = vgarb(SEQ_DATA);
+    		if (sisfb_forcecrt1) {
+			sisfb_crt1off=0;
+			sr17 |= 0x80;
+		} else {
+			sisfb_crt1off=1;
+			sr17 &= ~0x80;
+		}
+		vgawb(SEQ_DATA, sr17);
+    	}
 }
 
-static void sisfb_get_VB_type_300 (void)
+static void sisfb_get_VB_type_300(void)
 {
 	u8 reg;
 
 	if (ivideo.chip != SIS_300) {
-		if (!sisfb_has_VB_300 ()) {
-			vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR37);
-			reg = vgarb (CRTC_DATA);
+		if (!sisfb_has_VB_300()) {
+			vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR37);
+			reg = vgarb(CRTC_DATA);
 
 			switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
-			case SIS_EXTERNAL_CHIP_SIS301:
+			   case SIS_EXTERNAL_CHIP_SIS301:
 				ivideo.hasVB = HASVB_301;
 				break;
-			case SIS_EXTERNAL_CHIP_LVDS:
+			   case SIS_EXTERNAL_CHIP_LVDS:
 				ivideo.hasVB = HASVB_LVDS;
 				break;
-			case SIS_EXTERNAL_CHIP_TRUMPION:
+			   case SIS_EXTERNAL_CHIP_TRUMPION:
 				ivideo.hasVB = HASVB_TRUMPION;
 				break;
-			case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
+			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
 				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
 				break;
-			case SIS_EXTERNAL_CHIP_CHRONTEL:
+			   case SIS_EXTERNAL_CHIP_CHRONTEL:
 				ivideo.hasVB = HASVB_CHRONTEL;
 				break;
-			default:
+			   default:
 				break;
 			}
 		}
 	} else {
-		sisfb_has_VB_300 ();
+		sisfb_has_VB_300();
 	}
-
-	//sishw_ext.hasVB = ivideo.hasVB;
 }
 
-static int sisfb_has_VB_300 (void)
+static int sisfb_has_VB_300(void)
 {
 	// Eden Chen
 	//u8 sr38, sr39, vb_chipid;
@@ -846,146 +960,201 @@
 	//sr38 = vgarb(SEQ_DATA);
 	//vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP2);
 	//sr39 = vgarb(SEQ_DATA);
-	vgawb (VB_PART4_ADR, 0x0);
-	vb_chipid = vgarb (VB_PART4_DATA);
+	vgawb(VB_PART4_ADR, 0x0);
+	vb_chipid = vgarb(VB_PART4_DATA);
 
 	switch (vb_chipid) {
-	case 0x01:
+	   case 0x01:
 		ivideo.hasVB = HASVB_301;
 		break;
-	case 0x02:
+	   case 0x02:
 		ivideo.hasVB = HASVB_302;
 		break;
-	case 0x03:
+	   case 0x03:
 		ivideo.hasVB = HASVB_303;
 		break;
-	default:
+	   default:
 		ivideo.hasVB = HASVB_NONE;
 		return FALSE;
 	}
 	return TRUE;
-}
 
-#endif				/* CONFIG_FB_SIS_300 */
+	//if (
+	//	( (ivideo.chip == SIS_300) && (sr38 & 0x20) )
+	//	||
+	//	( (ivideo.chip == SIS_540) && (sr38 & 0x20) && (!(sr39 & 0x80)) )
+	//	||
+	//	( (ivideo.chip == SIS_630 ) && (sr38 & 0x20) && (!(sr39 & 0x80)) && 
+	//		((ivideo.revision_id & 0xf0) < 0x30) && (vb_chipid == 1) ) 
+	//	||
+	//	( (ivideo.chip == SIS_630 ) && ((ivideo.revision_id & 0xf0) >= 0x30) && 
+	//		(vb_chipid == 1) ) 
+	//	||
+	//	( (ivideo.chip == SIS_730) && (vb_chipid == 1) ) /* 730 */
+	//) {
+	//	ivideo.hasVB = HASVB_301;
+	//	return TRUE;
+	//} else {
+	//	ivideo.hasVB = HASVB_NONE;
+	//	return FALSE;
+	//}
 
-#ifdef CONFIG_FB_SIS_315	/* for SiS 315H/315 */
-static int sisfb_get_dram_size_315 (void)
+	// ~Eden Chen
+}
+#endif  /* CONFIG_FB_SIS_300 */
+
+#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740 */
+static int sisfb_get_dram_size_315(void)
 {
-#ifdef LINUXBIOS
 	struct pci_dev *pdev = NULL;
 	int pdev_valid = 0;
-	u8 pci_data;
-#endif
-	u8 reg = 0;
+	u8  pci_data;
+	u8  reg = 0;
 
-	if (ivideo.chip == SIS_550) {
+	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650) {
 #ifdef LINUXBIOS
-		pci_for_each_dev (pdev) {
-			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_for_each_dev(pdev) {
+			if ( (pdev->vendor == PCI_VENDOR_ID_SI)
+				&& ( (pdev->device == PCI_DEVICE_ID_SI_550)
+				  || (pdev->device == PCI_DEVICE_ID_SI_650))) {
+				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));
+				    (unsigned int)(1 << (pci_data+21));
 				pdev_valid = 1;
 
-				vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE);
-				reg = vgarb (SEQ_DATA) & 0xC0;
+				/* TW: Initialize SR14 "by hand" */
+				vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
+				reg = vgarb(SEQ_DATA) & 0xC0;
 
 				switch (pci_data) {
-					//case BRI_DRAM_SIZE_2MB:
-					//      reg |= (SIS315_DRAM_SIZE_2MB << 4); break;
-				case BRI_DRAM_SIZE_4MB:
+				//case BRI_DRAM_SIZE_2MB:
+				//	reg |= (SIS315_DRAM_SIZE_2MB << 4); break;
+				   case BRI_DRAM_SIZE_4MB:
 					reg |= SIS550_DRAM_SIZE_4MB;
 					break;
-				case BRI_DRAM_SIZE_8MB:
+				   case BRI_DRAM_SIZE_8MB:
 					reg |= SIS550_DRAM_SIZE_8MB;
 					break;
-				case BRI_DRAM_SIZE_16MB:
+				   case BRI_DRAM_SIZE_16MB:
 					reg |= SIS550_DRAM_SIZE_16MB;
 					break;
-				case BRI_DRAM_SIZE_32MB:
+				   case BRI_DRAM_SIZE_32MB:
 					reg |= SIS550_DRAM_SIZE_32MB;
 					break;
-				case BRI_DRAM_SIZE_64MB:
+				   case BRI_DRAM_SIZE_64MB:
 					reg |= SIS550_DRAM_SIZE_64MB;
 					break;
-					/* case BRI_DRAM_SIZE_128MB:
-					   reg |= (SIS315_DRAM_SIZE_128MB << 4); break; */
+				   /* case BRI_DRAM_SIZE_128MB:
+					reg |= (SIS315_DRAM_SIZE_128MB << 4); break; */
 				}
 
-				/* TODO : set Dual channel and bus width bits here */
+			        /* TODO : set Dual channel and bus width bits here */
 
-				vgawb (SEQ_DATA, reg);
+				vgawb(SEQ_DATA, reg);
 				break;
-			}
+			}  
 		}
-
+	
 		if (!pdev_valid)
 			return -1;
 #else
-		vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE);
-		reg = vgarb (SEQ_DATA);
+		vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
+		reg = vgarb(SEQ_DATA);
 		switch (reg & SIS550_DRAM_SIZE_MASK) {
-		case SIS550_DRAM_SIZE_4MB:
-			ivideo.video_size = 0x400000;
-			break;
-		case SIS550_DRAM_SIZE_8MB:
-			ivideo.video_size = 0x800000;
-			break;
-		case SIS550_DRAM_SIZE_16MB:
-			ivideo.video_size = 0x1000000;
-			break;
-		case SIS550_DRAM_SIZE_24MB:
-			ivideo.video_size = 0x1800000;
-			break;
-		case SIS550_DRAM_SIZE_32MB:
-			ivideo.video_size = 0x2000000;
-			break;
-		case SIS550_DRAM_SIZE_64MB:
-			ivideo.video_size = 0x4000000;
-			break;
-		case SIS550_DRAM_SIZE_96MB:
-			ivideo.video_size = 0x6000000;
-			break;
-		case SIS550_DRAM_SIZE_128MB:
-			ivideo.video_size = 0x8000000;
-			break;
-		case SIS550_DRAM_SIZE_256MB:
-			ivideo.video_size = 0x10000000;
-			break;
-		default:
-			return -1;
+		   case SIS550_DRAM_SIZE_4MB:
+			ivideo.video_size = 0x400000;   break;
+		   case SIS550_DRAM_SIZE_8MB:
+			ivideo.video_size = 0x800000;   break;
+		   case SIS550_DRAM_SIZE_16MB:
+			ivideo.video_size = 0x1000000;  break;
+		   case SIS550_DRAM_SIZE_24MB:
+			ivideo.video_size = 0x1800000;  break;
+		   case SIS550_DRAM_SIZE_32MB:
+			ivideo.video_size = 0x2000000;	break;
+		   case SIS550_DRAM_SIZE_64MB:
+			ivideo.video_size = 0x4000000;	break;
+		   case SIS550_DRAM_SIZE_96MB:
+			ivideo.video_size = 0x6000000;	break;
+		   case SIS550_DRAM_SIZE_128MB:
+			ivideo.video_size = 0x8000000;	break;
+		   case SIS550_DRAM_SIZE_256MB:
+			ivideo.video_size = 0x10000000;	break;
+		   default:
+		        /* TW: Some 550 BIOSes don't seem to initialize SR14 correctly (if at all),
+			 *     do it the hard way ourselves in this case. Unfortunately, we don't
+			 *     support 24, 48, 96 and other "odd" amounts here.
+			 */
+		        printk(KERN_INFO
+			       "sisfb: Warning: Could not determine memory size, "
+			       "now reading from PCI config\n");
+			pdev_valid = 0;
+			pci_for_each_dev(pdev) {
+			   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;
+				ivideo.video_size = (unsigned int)(1 << (pci_data+21));
+				pdev_valid = 1;
+				/* TW: Initialize SR14=IND_SIS_DRAM_SIZE */
+				vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
+				reg = vgarb(SEQ_DATA) & 0xC0;
+				switch (pci_data) {
+				   case BRI_DRAM_SIZE_4MB:
+					reg |= SIS550_DRAM_SIZE_4MB;  break;
+				   case BRI_DRAM_SIZE_8MB:
+					reg |= SIS550_DRAM_SIZE_8MB;  break;
+				   case BRI_DRAM_SIZE_16MB:
+					reg |= SIS550_DRAM_SIZE_16MB; break;
+				   case BRI_DRAM_SIZE_32MB:
+					reg |= SIS550_DRAM_SIZE_32MB; break;
+				   case BRI_DRAM_SIZE_64MB:
+					reg |= SIS550_DRAM_SIZE_64MB; break;
+				   /* case BRI_DRAM_SIZE_128MB:
+					reg |= (SIS315_DRAM_SIZE_128MB << 4); break; */
+				   default:
+				   	printk(KERN_INFO "sisfb: Unable to determine memory size, giving up.\n");
+					return -1;
+				}
+				vgawb(SEQ_DATA, reg);
+			   }
+			}
+			if (!pdev_valid) {
+				printk(KERN_INFO "sisfb: Total confusion - No SiS PCI VGA device found?!\n");
+				return -1;
+			}
+			return 0;
 		}
 #endif
 		return 0;
-	} else {
-		vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE);
-		reg = vgarb (SEQ_DATA);
+	} else {	/* 315 */
+		vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
+		reg = vgarb(SEQ_DATA);
 		switch ((reg & SIS315_DRAM_SIZE_MASK) >> 4) {
-		case SIS315_DRAM_SIZE_2MB:
+		   case SIS315_DRAM_SIZE_2MB:
 			ivideo.video_size = 0x200000;
 			break;
-		case SIS315_DRAM_SIZE_4MB:
+		   case SIS315_DRAM_SIZE_4MB:
 			ivideo.video_size = 0x400000;
 			break;
-		case SIS315_DRAM_SIZE_8MB:
+		   case SIS315_DRAM_SIZE_8MB:
 			ivideo.video_size = 0x800000;
 			break;
-		case SIS315_DRAM_SIZE_16MB:
+		   case SIS315_DRAM_SIZE_16MB:
 			ivideo.video_size = 0x1000000;
 			break;
-		case SIS315_DRAM_SIZE_32MB:
+		   case SIS315_DRAM_SIZE_32MB:
 			ivideo.video_size = 0x2000000;
 			break;
-		case SIS315_DRAM_SIZE_64MB:
+		   case SIS315_DRAM_SIZE_64MB:
 			ivideo.video_size = 0x4000000;
 			break;
-		case SIS315_DRAM_SIZE_128MB:
+		   case SIS315_DRAM_SIZE_128MB:
 			ivideo.video_size = 0x8000000;
 			break;
-		default:
+		   default:
 			return -1;
 		}
 	}
@@ -993,209 +1162,318 @@
 	reg &= SIS315_DUAL_CHANNEL_MASK;
 	reg >>= 2;
 	switch (reg) {
-	case SIS315_SINGLE_CHANNEL_2_RANK:
+	   case SIS315_SINGLE_CHANNEL_2_RANK:
 		ivideo.video_size <<= 1;
 		break;
-	case SIS315_DUAL_CHANNEL_1_RANK:
+	   case SIS315_DUAL_CHANNEL_1_RANK:
 		ivideo.video_size <<= 1;
 		break;
+	   case SIS315_ASYM_DDR:		/* TW: DDR asymentric */
+		ivideo.video_size += (ivideo.video_size/2);
+		break;
 	}
 
 	return 0;
 }
 
-static void sisfb_detect_VB_connect_315 (void)
+static void sisfb_detect_VB_connect_315(void)
 {
-	u8 cr32, temp;
+	u8 sr17, cr32, temp;
 
-	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR32);
-	cr32 = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR32);
+	cr32 = vgarb(CRTC_DATA);
 
 	ivideo.TV_plug = ivideo.TV_type = 0;
 	if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
 		sisfb_crt1off = 0;
 	else {
-		if (cr32 & 0x5F)
+		if (cr32 & 0x5F)   
 			sisfb_crt1off = 1;
 		else
 			sisfb_crt1off = 0;
 	}
 
-	if (cr32 & SIS_VB_CRT2)
+	if (sisfb_crt2type != -1)
+		/* TW: Override with option */
+		ivideo.disp_state = sisfb_crt2type;
+	else if (cr32 & SIS_VB_CRT2)
 		ivideo.disp_state = DISPTYPE_CRT2;
 	else if (cr32 & SIS_VB_LCD)
 		ivideo.disp_state = DISPTYPE_LCD;
-	else if (cr32 & SIS_VB_TV) {
+	else if (cr32 & SIS_VB_TV)
 		ivideo.disp_state = DISPTYPE_TV;
+	else
+		ivideo.disp_state = 0;
 
-		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 (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) {
+	    /* TW: PAL/NTSC changed for 315/650 */
+	    if(ivideo.chip <= SIS_315PRO) {
+#if 0
+		vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP);
+		temp = vgarb(SEQ_DATA);
+#endif
+                vgawb(CRTC_ADR, 0x38);
+		temp = vgarb(CRTC_DATA);
+		if (temp & 0x10)
+			ivideo.TV_type = TVMODE_PAL;
+		else
+			ivideo.TV_type = TVMODE_NTSC;
+	    } else {
+	        vgawb(CRTC_ADR, 0x79);
+		temp = vgarb(CRTC_DATA);
+		if (temp & 0x20)
+			ivideo.TV_type = TVMODE_PAL;
+		else
+			ivideo.TV_type = TVMODE_NTSC;
+	    }
+	}
 
-		if (ivideo.TV_type == 0) {
-			vgawb (SEQ_ADR, IND_SIS_POWER_ON_TRAP);
-			temp = vgarb (SEQ_DATA);
+	/* TW: Copy forceCRT1 option to CRT1off if option is given */
+    	if (sisfb_forcecrt1 != -1) {
+		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_17);
+    		sr17 = vgarb(SEQ_DATA);
+    		if (sisfb_forcecrt1) {
+			sisfb_crt1off=0;
+			sr17 |= 0x80;
+		} else {
+			sisfb_crt1off=1;
+			sr17 &= ~0x80;
+		}
+		vgawb(SEQ_DATA, sr17);
+    	}
+}
 
-			if (temp & 0x01)
-				ivideo.TV_type = TVMODE_PAL;
-			else
-				ivideo.TV_type = TVMODE_NTSC;
+static void sisfb_get_VB_type_315(void)
+{
+	u8 reg;
+
+		if (!sisfb_has_VB_315()) {
+			vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR37);
+			reg = vgarb(CRTC_DATA);
+
+			/* TW: CR37 changed on 310/325 series */
+			switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
+			   case SIS_EXTERNAL_CHIP_SIS301:
+				ivideo.hasVB = HASVB_301;
+				break;
+			   case SIS310_EXTERNAL_CHIP_LVDS:
+				ivideo.hasVB = HASVB_LVDS;
+				break;
+			   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
+				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
+				break;
+			   default:
+				break;
+			}
 		}
-	} else
-		ivideo.disp_state = 0;
 }
 
-static void sisfb_get_VB_type_315 (void)
+
+static int sisfb_has_VB_315(void)
 {
 	u8 vb_chipid;
 
-	vgawb (VB_PART4_ADR, 0x0);
-	vb_chipid = vgarb (VB_PART4_DATA);
+	vgawb(VB_PART4_ADR, 0x00);
+	vb_chipid = vgarb(VB_PART4_DATA);
 
 	switch (vb_chipid) {
-	case 0x01:
+	   case 0x01:
 		ivideo.hasVB = HASVB_301;
 		break;
-	case 0x02:
+	   case 0x02:
 		ivideo.hasVB = HASVB_302;
 		break;
-	case 0x03:
+	   case 0x03:
 		ivideo.hasVB = HASVB_303;
 		break;
-	default:
+	   default:
 		ivideo.hasVB = HASVB_NONE;
+		return FALSE;
 	}
-	// Eden Chen
-	//sishw_ext.hasVB = ivideo.hasVB;
-	// ~Eden Chen
+	return TRUE;
 }
-#endif				/* CONFIG_FB_SIS_315 */
+
+#endif   /* CONFIG_FB_SIS_315 */
 
 /* --------------------- Heap Routines ------------------------------- */
 
-static int sisfb_heap_init (void)
+static int sisfb_heap_init(void)
 {
 	SIS_OH *poh;
-	u8 temp = 0;
+	u8 temp=0;
 #ifdef CONFIG_FB_SIS_315
-	int agp_enabled = 1;
-	u32 agp_size;
+	int            agp_enabled = 1;
+	u32            agp_size;
 	unsigned long *cmdq_baseport = 0;
 	unsigned long *read_port = 0;
 	unsigned long *write_port = 0;
-	SIS_CMDTYPE cmd_type;
+	SIS_CMDTYPE    cmd_type;
 #ifndef AGPOFF
-	agp_kern_info *agp_info;
-	agp_memory *agp;
-	u32 agp_phys;
+	agp_kern_info  *agp_info;
+	agp_memory     *agp;
+	u32            agp_phys;
 #endif
 #endif
-	/*karl:10/01/2001 */
-	if (!sisfb_mem) {
-
-		if (ivideo.video_size > 0x800000)
-			sisfb_heap_start =
-			    (unsigned long) ivideo.video_vbase + 0x800000;
-		else
-			sisfb_heap_start =
-			    (unsigned long) ivideo.video_vbase + 0x400000;
-	} else
-		sisfb_heap_start =
-		    (unsigned long) (ivideo.video_vbase + sisfb_mem * 0x100000);
+/* TW: The heap start is either set manually using the "mem" parameter, or
+ *     defaults as follows:
+ *     -) If more than 16MB videoRAM available, let our heap start at 12MB.
+ *     -) If more than  8MB videoRAM available, let our heap start at  8MB.
+ *     -) If 4MB or less is available, let it start at 4MB.
+ *     This is for avoiding a clash with X driver which uses the beginning
+ *     of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
+ *     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.
+ */
+     if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
+        if (ivideo.video_size > 0x1000000) {
+	        ivideo.heapstart = 0xc00000;
+	} else if (ivideo.video_size > 0x800000) {
+	        ivideo.heapstart = 0x800000;
+	} else {
+		ivideo.heapstart = 0x400000;
+	}
+     } else {
+           ivideo.heapstart = sisfb_mem * 1024;
+     }
+     sisfb_heap_start =
+	       (unsigned long) (ivideo.video_vbase + ivideo.heapstart);
+     printk(KERN_INFO "sisfb: Memory heap starting at %dK\n",
+     					(int)(ivideo.heapstart / 1024));
 
-	sisfb_heap_end = (unsigned long) ivideo.video_vbase + ivideo.video_size;
-	sisfb_heap_size = sisfb_heap_end - sisfb_heap_start;
+     sisfb_heap_end = (unsigned long) ivideo.video_vbase + ivideo.video_size;
+     sisfb_heap_size = sisfb_heap_end - sisfb_heap_start;
 
 #ifdef CONFIG_FB_SIS_315
+     if (sisvga_engine == SIS_315_VGA) {
+        /* TW: Now initialize the 310 series' command queue mode.
+	 * On 310, 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
+	 *    on. This is the one comparable to the 300 series.
+	 * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
+	 *    have to do queue management himself. Register 0x85c4 will
+	 *    hold the location of the next free queue slot, 0x85c8
+	 *    is the "queue read pointer" whose way of working is
+	 *    unknown to me. Anyway, this mode would require a
+	 *    translation of the MMIO commands to some kind of
+	 *    accelerator assembly and writing these commands
+	 *    to the memory location pointed to by 0x85c4.
+	 *    We will not use this, as nobody knows how this
+	 *    "assembly" works, and as it would require a complete
+	 *    re-write of the accelerator code.
+	 * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
+	 *    queue in AGP memory space.
+	 *
+	 * SR26 bit 4 is called "Bypass H/W queue".
+	 * SR26 bit 1 is called "Enable Command Queue Auto Correction"
+	 * SR26 bit 0 resets the queue
+	 * Size of queue memory is encoded in bits 3:2 like this:
+	 *    00  (0x00)  512K
+	 *    01  (0x04)  1M
+	 *    10  (0x08)  2M
+	 *    11  (0x0C)  4M
+	 * The queue location is to be written to 0x85C0.
+	 *
+         */
+	cmdq_baseport = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_PHYBASE);
+	write_port    = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_WRITEPORT);
+	read_port     = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_READPORT);
 
-	cmdq_baseport =
-	    (unsigned long *) (ivideo.mmio_vbase + MMIO_QUEUE_PHYBASE);
-	write_port =
-	    (unsigned long *) (ivideo.mmio_vbase + MMIO_QUEUE_WRITEPORT);
-	read_port = (unsigned long *) (ivideo.mmio_vbase + MMIO_QUEUE_READPORT);
+	DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
 
-	DPRINTK ("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport,
-		 read_port, write_port);
-
-	agp_size = COMMAND_QUEUE_AREA_SIZE;
+	agp_size  = COMMAND_QUEUE_AREA_SIZE;
 
 #ifndef AGPOFF
-
-	agp_info = vmalloc (sizeof (agp_kern_info));
-	memset ((void *) agp_info, 0x00, sizeof (agp_kern_info));
-	agp_copy_info (agp_info);
-
-	agp_backend_acquire ();
-
-	agp =
-	    agp_allocate_memory (COMMAND_QUEUE_AREA_SIZE / PAGE_SIZE,
-				 AGP_NORMAL_MEMORY);
-	if (agp == NULL) {
-		DPRINTK ("Allocate AGP buffer failed.\n");
-		agp_enabled = 0;
-	} else {
-		if (agp_bind_memory (agp, agp->pg_start) != 0) {
-			DPRINTK ("AGP : can not bind memory\n");
+	if (sisfb_queuemode == AGP_CMD_QUEUE) {
+		agp_info = vmalloc(sizeof(agp_kern_info));
+		memset((void*)agp_info, 0x00, sizeof(agp_kern_info));
+		agp_copy_info(agp_info);
+
+		agp_backend_acquire();
+
+		agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE/PAGE_SIZE,
+					  AGP_NORMAL_MEMORY);
+		if (agp == NULL) {
+			DPRINTK("sisfb: Allocating AGP buffer failed.\n");
 			agp_enabled = 0;
 		} else {
-			agp_enable (0);
+			if (agp_bind_memory(agp, agp->pg_start) != 0) {
+				DPRINTK("sisfb: AGP: Failed to bind memory\n");
+				/* TODO: Free AGP memory here */
+				agp_enabled = 0;
+			} else {
+				agp_enable(0);
+			}
 		}
 	}
-
 #else
-	agp_enabled = 0;
+	agp_enabled= 0;
 #endif
-	if (agp_enabled)
+
+	/* TW: Now select the queue mode */
+
+	if ((agp_enabled) && (sisfb_queuemode == AGP_CMD_QUEUE)) {
 		cmd_type = AGP_CMD_QUEUE;
-	else if (sisfb_heap_size >= COMMAND_QUEUE_AREA_SIZE)
+		printk(KERN_INFO "sisfb: Using AGP queue mode\n");
+/*	} else if (sisfb_heap_size >= COMMAND_QUEUE_AREA_SIZE)  */
+        } else if (sisfb_queuemode == VM_CMD_QUEUE) {
 		cmd_type = VM_CMD_QUEUE;
-	else
+		printk(KERN_INFO "sisfb: Using VRAM queue mode\n");
+	} else {
+		printk(KERN_INFO "sisfb: Using MMIO queue mode\n");
 		cmd_type = MMIO_CMD;
+	}
 
 	switch (agp_size) {
-	case 0x80000:
+	   case 0x80000:
 		temp = SIS_CMD_QUEUE_SIZE_512k;
 		break;
-	case 0x100000:
+	   case 0x100000:
 		temp = SIS_CMD_QUEUE_SIZE_1M;
 		break;
-	case 0x200000:
+	   case 0x200000:
 		temp = SIS_CMD_QUEUE_SIZE_2M;
 		break;
-	case 0x400000:
+	   case 0x400000:
 		temp = SIS_CMD_QUEUE_SIZE_4M;
 		break;
 	}
 
 	switch (cmd_type) {
-	case AGP_CMD_QUEUE:
+	   case AGP_CMD_QUEUE:
 #ifndef AGPOFF
-		DPRINTK ("AGP buffer base:0x%lx, offset:0x%x, size is %dK\n",
-			 agp_info->aper_base, agp->physical, agp_size / 1024);
+		DPRINTK("sisfb: AGP buffer base:0x%lx, offset:0x%x, size: %dK\n",
+			agp_info->aper_base, agp->physical, agp_size/1024);
 
 		agp_phys = agp_info->aper_base + agp->physical;
 
-		vgawb (CRTC_ADR, IND_SIS_AGP_IO_PAD);
-		vgawb (CRTC_DATA, 0);
-		vgawb (CRTC_DATA, SIS_AGP_2X);
+		vgawb(CRTC_ADR, IND_SIS_AGP_IO_PAD);
+		vgawb(CRTC_DATA, 0);
+		vgawb(CRTC_DATA, SIS_AGP_2X);
 
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
-		vgawb (SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
+		vgawb(SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
 
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb (SEQ_DATA, SIS_CMD_QUEUE_RESET);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, SIS_CMD_QUEUE_RESET);
 
 		*write_port = *read_port;
 
 		temp |= SIS_AGP_CMDQUEUE_ENABLE;
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb (SEQ_DATA, temp);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, temp);
 
 		*cmdq_baseport = agp_phys;
 
@@ -1203,94 +1481,124 @@
 #endif
 		break;
 
-	case VM_CMD_QUEUE:
+	   case VM_CMD_QUEUE:
 		sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
 		sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
 
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
-		vgawb (SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
+		vgawb(SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
 
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb (SEQ_DATA, SIS_CMD_QUEUE_RESET);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, SIS_CMD_QUEUE_RESET);
 
 		*write_port = *read_port;
 
 		temp |= SIS_VRAM_CMDQUEUE_ENABLE;
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb (SEQ_DATA, temp);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, temp);
 
 		*cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;
 
 		sisfb_caps |= VM_CMD_QUEUE_CAP;
 
-		DPRINTK ("VM Cmd Queue offset = 0x%lx, size is %dK\n",
-			 *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE / 1024);
+		DPRINTK("sisfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
+			*cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
 		break;
-	default:
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb (SEQ_DATA, SIS_MMIO_CMD_ENABLE);
+
+	   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;
+
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
+		vgawb(SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
+
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, SIS_CMD_QUEUE_RESET);
+
+		*write_port = *read_port;
+
+		/* TW: Set Auto_Correction bit; this works in sisfb lite,
+		 * so why not.
+		 */
+		temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, temp);
+
+		*cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;
+
+		DPRINTK("sisfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n",
+			*cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
 		break;
 	}
-
+     } /* sisvga_engine = 315 */
 #endif
 
 #ifdef CONFIG_FB_SIS_300
-	if (sisfb_heap_size >= TURBO_QUEUE_AREA_SIZE) {
-		unsigned int tqueue_pos;
+     if (sisvga_engine == SIS_300_VGA) {
+  	    /* TW: Now initialize TurboQueue. TB is always located at the very
+	     * top of the video RAM. */
+	    if (sisfb_heap_size >= TURBO_QUEUE_AREA_SIZE) {
+		unsigned int  tqueue_pos;
 		u8 tq_state;
 
-		tqueue_pos =
-		    (ivideo.video_size - TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
+		tqueue_pos = (ivideo.video_size -
+		       TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
 		temp = (u8) (tqueue_pos & 0xff);
-		vgawb (SEQ_ADR, IND_SIS_TURBOQUEUE_SET);
-		tq_state = vgarb (SEQ_DATA);
+		vgawb(SEQ_ADR, IND_SIS_TURBOQUEUE_SET);
+		tq_state = vgarb(SEQ_DATA);
 		tq_state |= 0xf0;
 		tq_state &= 0xfc;
 		tq_state |= (u8) (tqueue_pos >> 8);
-		vgawb (SEQ_DATA, tq_state);
-		vgawb (SEQ_ADR, IND_SIS_TURBOQUEUE_ADR);
-		vgawb (SEQ_DATA, temp);
+		vgawb(SEQ_DATA, tq_state);
+		vgawb(SEQ_ADR, IND_SIS_TURBOQUEUE_ADR);
+		vgawb(SEQ_DATA, temp);
 
 		sisfb_caps |= TURBO_QUEUE_CAP;
 
 		sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE;
 		sisfb_heap_size -= TURBO_QUEUE_AREA_SIZE;
-		DPRINTK ("Turbo Queue: start at 0x%lx, size is %dK\n",
-			 sisfb_heap_end, TURBO_QUEUE_AREA_SIZE / 1024);
-	}
-#endif
-
-	if (sisfb_heap_size >= HW_CURSOR_AREA_SIZE) {
-		sisfb_heap_end -= HW_CURSOR_AREA_SIZE;
-		sisfb_heap_size -= HW_CURSOR_AREA_SIZE;
+		DPRINTK("sisfb: TurboQueue start at 0x%lx, size is %dK\n",
+			sisfb_heap_end, TURBO_QUEUE_AREA_SIZE/1024);
+	    }
+     }
+#endif
+        /* TW: Now reserve memory for the HWCursor. It is always located at the very
+               top of the videoRAM, right below the TB memory area (if used). */
+	if (sisfb_heap_size >= sisfb_hwcursor_size) {
+		sisfb_heap_end -= sisfb_hwcursor_size;
+		sisfb_heap_size -= sisfb_hwcursor_size;
 		sisfb_hwcursor_vbase = sisfb_heap_end;
 
 		sisfb_caps |= HW_CURSOR_CAP;
 
-		DPRINTK ("Hardware Cursor: start at 0x%lx, size is %dK\n",
-			 sisfb_heap_end, HW_CURSOR_AREA_SIZE / 1024);
+		DPRINTK("sisfb: Hardware Cursor start at 0x%lx, size is %dK\n",
+			sisfb_heap_end, sisfb_hwcursor_size/1024);
 	}
 
 	sisfb_heap.poha_chain = NULL;
 	sisfb_heap.poh_freelist = NULL;
 
-	poh = sisfb_poh_new_node ();
+	poh = sisfb_poh_new_node();
 
 	if (poh == NULL)
 		return 1;
-
+	
 	poh->poh_next = &sisfb_heap.oh_free;
 	poh->poh_prev = &sisfb_heap.oh_free;
 	poh->size = sisfb_heap_end - sisfb_heap_start + 1;
 	poh->offset = sisfb_heap_start - (unsigned long) ivideo.video_vbase;
 
-	DPRINTK ("sisfb:Heap start:0x%p, end:0x%p, len=%dk\n",
-		 (char *) sisfb_heap_start, (char *) sisfb_heap_end,
-		 (unsigned int) poh->size / 1024);
-
-	DPRINTK ("sisfb:First Node offset:0x%x, size:%dk\n",
-		 (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
+	DPRINTK("sisfb: Heap start:0x%p, end:0x%p, len=%dk\n",
+		(char *) sisfb_heap_start, (char *) sisfb_heap_end,
+		(unsigned int) poh->size / 1024);
 
+	DPRINTK("sisfb: First Node offset:0x%x, size:%dk\n",
+		(unsigned int) poh->offset, (unsigned int) poh->size / 1024);
+	
 	sisfb_heap.oh_free.poh_next = poh;
 	sisfb_heap.oh_free.poh_prev = poh;
 	sisfb_heap.oh_free.size = 0;
@@ -1303,7 +1611,7 @@
 	return 0;
 }
 
-static SIS_OH *sisfb_poh_new_node (void)
+static SIS_OH *sisfb_poh_new_node(void)
 {
 	int i;
 	unsigned long cOhs;
@@ -1311,14 +1619,16 @@
 	SIS_OH *poh;
 
 	if (sisfb_heap.poh_freelist == NULL) {
-		poha = kmalloc (OH_ALLOC_SIZE, GFP_KERNEL);
+		poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
+		if(!poha)
+		    return NULL;
 
 		poha->poha_next = sisfb_heap.poha_chain;
 		sisfb_heap.poha_chain = poha;
 
 		cOhs =
 		    (OH_ALLOC_SIZE -
-		     sizeof (SIS_OHALLOC)) / sizeof (SIS_OH) + 1;
+		     sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
 
 		poh = &poha->aoh[0];
 		for (i = cOhs - 1; i != 0; i--) {
@@ -1336,15 +1646,15 @@
 	return (poh);
 }
 
-static SIS_OH *sisfb_poh_allocate (unsigned long size)
+static SIS_OH *sisfb_poh_allocate(unsigned long size)
 {
 	SIS_OH *pohThis;
 	SIS_OH *pohRoot;
 	int bAllocated = 0;
 
 	if (size > sisfb_heap.max_freesize) {
-		DPRINTK ("sisfb: Can't allocate %dk size on offscreen\n",
-			 (unsigned int) size / 1024);
+		DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",
+			(unsigned int) size / 1024);
 		return (NULL);
 	}
 
@@ -1359,16 +1669,16 @@
 	}
 
 	if (!bAllocated) {
-		DPRINTK ("sisfb: Can't allocate %dk size on offscreen\n",
-			 (unsigned int) size / 1024);
+		DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",
+			(unsigned int) size / 1024);
 		return (NULL);
 	}
 
 	if (size == pohThis->size) {
 		pohRoot = pohThis;
-		sisfb_delete_node (pohThis);
+		sisfb_delete_node(pohThis);
 	} else {
-		pohRoot = sisfb_poh_new_node ();
+		pohRoot = sisfb_poh_new_node();
 
 		if (pohRoot == NULL) {
 			return (NULL);
@@ -1384,16 +1694,17 @@
 	sisfb_heap.max_freesize -= size;
 
 	pohThis = &sisfb_heap.oh_used;
-	sisfb_insert_node (pohThis, pohRoot);
+	sisfb_insert_node(pohThis, pohRoot);
 
 	return (pohRoot);
 }
 
-static void sisfb_delete_node (SIS_OH * poh)
+static void sisfb_delete_node(SIS_OH *poh)
 {
 	SIS_OH *poh_prev;
 	SIS_OH *poh_next;
 
+
 	poh_prev = poh->poh_prev;
 	poh_next = poh->poh_next;
 
@@ -1403,7 +1714,7 @@
 	return;
 }
 
-static void sisfb_insert_node (SIS_OH * pohList, SIS_OH * poh)
+static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
 {
 	SIS_OH *pohTemp;
 
@@ -1416,9 +1727,8 @@
 	poh->poh_next = pohTemp;
 }
 
-static SIS_OH *sisfb_poh_free (unsigned long base)
+static SIS_OH *sisfb_poh_free(unsigned long base)
 {
-
 	SIS_OH *pohThis;
 	SIS_OH *poh_freed;
 	SIS_OH *poh_prev;
@@ -1452,41 +1762,43 @@
 	while (pohThis != &sisfb_heap.oh_free) {
 		if (pohThis->offset == ulUpper) {
 			poh_next = pohThis;
-		} else if ((pohThis->offset + pohThis->size) == ulLower) {
+		}
+			else if ((pohThis->offset + pohThis->size) ==
+				 ulLower) {
 			poh_prev = pohThis;
 		}
 		pohThis = pohThis->poh_next;
 	}
 
-	sisfb_delete_node (poh_freed);
+	sisfb_delete_node(poh_freed);
 
 	if (poh_prev && poh_next) {
 		poh_prev->size += (poh_freed->size + poh_next->size);
-		sisfb_delete_node (poh_next);
-		sisfb_free_node (poh_freed);
-		sisfb_free_node (poh_next);
+		sisfb_delete_node(poh_next);
+		sisfb_free_node(poh_freed);
+		sisfb_free_node(poh_next);
 		return (poh_prev);
 	}
 
 	if (poh_prev) {
 		poh_prev->size += poh_freed->size;
-		sisfb_free_node (poh_freed);
+		sisfb_free_node(poh_freed);
 		return (poh_prev);
 	}
 
 	if (poh_next) {
 		poh_next->size += poh_freed->size;
 		poh_next->offset = poh_freed->offset;
-		sisfb_free_node (poh_freed);
+		sisfb_free_node(poh_freed);
 		return (poh_next);
 	}
 
-	sisfb_insert_node (&sisfb_heap.oh_free, poh_freed);
+	sisfb_insert_node(&sisfb_heap.oh_free, poh_freed);
 
 	return (poh_freed);
 }
 
-static void sisfb_free_node (SIS_OH * poh)
+static void sisfb_free_node(SIS_OH *poh)
 {
 	if (poh == NULL) {
 		return;
@@ -1498,20 +1810,20 @@
 	return;
 }
 
-void sis_malloc (struct sis_memreq *req)
+void sis_malloc(struct sis_memreq *req)
 {
 	SIS_OH *poh;
 
-	poh = sisfb_poh_allocate (req->size);
+	poh = sisfb_poh_allocate(req->size);
 
 	if (poh == NULL) {
 		req->offset = 0;
 		req->size = 0;
-		DPRINTK ("sisfb: VMEM Allocation Failed\n");
+		DPRINTK("sisfb: Video RAM allocation failed\n");
 	} else {
-		DPRINTK ("sisfb: VMEM Allocation Successed : 0x%p\n",
-			 (char *) (poh->offset +
-				   (unsigned long) ivideo.video_vbase));
+		DPRINTK("sisfb: Video RAM allocation succeeded: 0x%p\n",
+			(char *) (poh->offset +
+				  (unsigned long) ivideo.video_vbase));
 
 		req->offset = poh->offset;
 		req->size = poh->size;
@@ -1519,280 +1831,294 @@
 
 }
 
-void sis_free (unsigned long base)
+void sis_free(unsigned long base)
 {
 	SIS_OH *poh;
 
-	poh = sisfb_poh_free (base);
+	poh = sisfb_poh_free(base);
 
 	if (poh == NULL) {
-		DPRINTK ("sisfb: sisfb_poh_free() failed at base 0x%x\n",
-			 (unsigned int) base);
+		DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",
+			(unsigned int) base);
 	}
 }
 
 /* ------------------ SetMode Routines ------------------------------- */
 
-static void sisfb_pre_setmode (void)
+static void sisfb_pre_setmode(void)
 {
 	u8 cr30 = 0, cr31 = 0;
 
-	vgawb (CRTC_ADR, 0x31);
-	cr31 = vgarb (CRTC_DATA) & ~0x60;
+	vgawb(CRTC_ADR, 0x31);
+	cr31 = vgarb(CRTC_DATA) & ~0x60;
 
 	switch (ivideo.disp_state & DISPTYPE_DISP2) {
-	case DISPTYPE_CRT2:
+	   case DISPTYPE_CRT2:
+		printk(KERN_INFO "sisfb: CRT2 type is VGA\n");
 		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);
+	   case DISPTYPE_LCD:
+		printk(KERN_INFO "sisfb: CRT2 type is LCD\n");
+		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		cr31 |= SIS_DRIVER_MODE;
 		break;
-	case DISPTYPE_TV:
+	   case DISPTYPE_TV:
+		printk(KERN_INFO "sisfb: CRT2 type is TV\n");
 		if (ivideo.TV_type == TVMODE_HIVISION)
-			cr30 =
-			    (SIS_VB_OUTPUT_HIVISION |
-			     SIS_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_HIVISION | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		else if (ivideo.TV_plug == TVPLUG_SVIDEO)
-			cr30 =
-			    (SIS_VB_OUTPUT_SVIDEO |
-			     SIS_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		else if (ivideo.TV_plug == TVPLUG_COMPOSITE)
-			cr30 =
-			    (SIS_VB_OUTPUT_COMPOSITE |
-			     SIS_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		else if (ivideo.TV_plug == TVPLUG_SCART)
-			cr30 =
-			    (SIS_VB_OUTPUT_SCART |
-			     SIS_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		cr31 |= SIS_DRIVER_MODE;
-
-		/*karl */
-		if (sisfb_tvmode == 1)
+		/* cr31 &= ~0x04; */ /* TW @@@ 5/5/02 */ /* TW: No NotSimuMode by default  */
+                /*karl*/
+	        if (sisfb_tvmode == 1 || ivideo.TV_type == TVMODE_PAL)
 			cr31 |= 0x1;
-		if (sisfb_tvmode == 2)
-			cr31 &= ~0x1;
-
+                if (sisfb_tvmode == 2 || ivideo.TV_type == TVMODE_NTSC)
+                        cr31 &= ~0x1;
 		break;
-	default:
+	   default:	/* CRT2 disable */
+		printk(KERN_INFO "sisfb: CRT2 is disabled\n");
 		cr30 = 0x00;
 		cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
 	}
 
-	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR30);
-	vgawb (CRTC_DATA, cr30);
-	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR31);
-	vgawb (CRTC_DATA, cr31);
-	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR33);
-	vgawb (CRTC_DATA, sisfb_rate_idx & 0x0F);
+	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR30);
+	vgawb(CRTC_DATA, cr30);
+	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR31);
+	vgawb(CRTC_DATA, cr31);
+
+	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR33);
+/*
+	if (ivideo.disp_state & DISPTYPE_CRT2) {
+		sisfb_rate_idx &= 0x0F;
+		sisfb_rate_idx |= (sisfb_rate_idx << 4);
+		vgawb(CRTC_DATA, sisfb_rate_idx);
+	} else {
+		vgawb(CRTC_DATA, sisfb_rate_idx & 0x0F);
+	}
+*/
+	vgawb(CRTC_DATA, sisfb_rate_idx & 0x0F);
 }
 
-static void sisfb_post_setmode (void)
+static void sisfb_post_setmode(void)
 {
 	u8 reg;
 
-	vgawb (CRTC_ADR, 0x17);
-	reg = vgarb (CRTC_DATA);
+	/* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
+	if ((ivideo.hasVB == HASVB_LVDS) || (ivideo.hasVB == HASVB_LVDS_CHRONTEL)) {
+		if (ivideo.video_bpp == 8) {
+			sisfb_crt1off = 0;
+		}
+	}
 
-	if ((ivideo.hasVB == HASVB_LVDS)
-	    || (ivideo.hasVB == HASVB_LVDS_CHRONTEL)) if (ivideo.video_bpp == 8)
+	/* TW: We can't switch off CRT1 on 630+301B in 8bpp Modes */
+	if ( (sishw_ext.ujVBChipID == VB_CHIP_301B) && (sisvga_engine == SIS_300_VGA) &&
+	     (ivideo.disp_state & DISPTYPE_LCD) ) {
+	        if (ivideo.video_bpp == 8) {
 			sisfb_crt1off = 0;
+	        }
+	}
 
-	if (sisfb_crt1off)
+	/* TW: We can't switch off CRT1 if bridge is in slave mode */
+	vgawb(VB_PART1_ADR,0x00);
+	reg = vgarb(VB_PART1_DATA);
+	if(sisvga_engine == SIS_300_VGA) {
+		if((reg & 0xa0) == 0x20) {
+			sisfb_crt1off = 0;
+		}
+	}
+	if(sisvga_engine == SIS_315_VGA) {
+		if((reg & 0x50) == 0x10) {
+			sisfb_crt1off = 0;
+		}
+	}
+
+	vgawb(CRTC_ADR, 0x17);
+	reg = vgarb(CRTC_DATA);
+	if (sisfb_crt1off)	  
 		reg &= ~0x80;
-	else
+	else 	      
 		reg |= 0x80;
-	vgawb (CRTC_DATA, reg);
-
-	vgawb (SEQ_ADR, IND_SIS_RAMDAC_CONTROL);
-	reg = vgarb (SEQ_DATA);
+	vgawb(CRTC_DATA, reg);
+	
+	vgawb(SEQ_ADR, IND_SIS_RAMDAC_CONTROL);
+	reg = vgarb(SEQ_DATA);
 	reg &= ~0x04;
-	vgawb (SEQ_DATA, reg);
+	vgawb(SEQ_DATA, reg);
 
 	if ((ivideo.disp_state & DISPTYPE_TV) && (ivideo.hasVB == HASVB_301)) {
-		/*karl */
-		vgawb (VB_PART4_ADR, 0x01);
-		reg = vgarb (VB_PART4_DATA);
-
-		if ((reg != 0xB1) && (reg != 0xB0)) {	/*301B Revision ID */
-			// Eden Chen
-			switch (ivideo.video_width) {
-			case 320:
-				filter_tb =
-				    (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12;
-				break;
-			case 640:
-				filter_tb =
-				    (ivideo.TV_type == TVMODE_NTSC) ? 5 : 13;
-				break;
-			case 720:
-				filter_tb =
-				    (ivideo.TV_type == TVMODE_NTSC) ? 6 : 14;
-				break;
-			case 800:
-				filter_tb =
-				    (ivideo.TV_type == TVMODE_NTSC) ? 7 : 15;
-				break;
-			default:
-				filter = -1;
-				break;
-			}
-			// ~Eden Chen
 
-			// Eden Chen
-			//vgawb(VB_PART1_ADR,  0x24);
-			vgawb (VB_PART1_ADR, IND_SIS_CRT2_WRITE_ENABLE);
-			// ~Eden Chen
-			vgawb (VB_PART1_DATA, 0x1);
-
-			// Eden Chen for Debug
-			// ~Eden Chen
+	   vgawb(VB_PART4_ADR,0x01);
+	   reg = vgarb(VB_PART4_DATA);
+	   if (reg < 0xB0)        	/* 301B Revision ID */
+           {	
+		// Eden Chen
+		switch (ivideo.video_width) {
+		   case 320:
+			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12;
+			break;
+		   case 640:
+			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 5 : 13;
+			break;
+		   case 720:
+			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 6 : 14;
+			break;
+		   case 800:
+			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 7 : 15;
+			break;
+		   default:
+			filter = -1;
+			break;
+		}
+		// ~Eden Chen
 
-			if (ivideo.TV_type == TVMODE_NTSC) {
-				vgawb (VB_PART2_ADR, 0x3A);
-				reg = vgarb (VB_PART2_DATA);
-				reg &= 0x1F;
-				vgawb (VB_PART2_DATA, reg);
-
-				if (ivideo.TV_plug == TVPLUG_SVIDEO) {
-					vgawb (VB_PART2_ADR, 0x30);
-					reg = vgarb (VB_PART2_DATA);
-					reg &= 0xDF;
-					vgawb (VB_PART2_DATA, reg);
-				} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
-					vgawb (VB_PART2_ADR, 0x30);
-					reg = vgarb (VB_PART2_DATA);
-					reg |= 0x20;
-					vgawb (VB_PART2_DATA, reg);
-
-					switch (ivideo.video_width) {
-					case 640:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xEB);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0x04);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x25);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0x18);
-						break;
-					case 720:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xEE);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0x0C);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x22);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0x08);
-						break;
-					case 800:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xEB);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0x15);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x25);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0xF6);
-						break;
-					}
-				}
-			} else if (ivideo.TV_type == TVMODE_PAL) {
-				vgawb (VB_PART2_ADR, 0x3A);
-				reg = vgarb (VB_PART2_DATA);
-				reg &= 0x1F;
-				vgawb (VB_PART2_DATA, reg);
-
-				if (ivideo.TV_plug == TVPLUG_SVIDEO) {
-					vgawb (VB_PART2_ADR, 0x30);
-					reg = vgarb (VB_PART2_DATA);
-					reg &= 0xDF;
-					vgawb (VB_PART2_DATA, reg);
-				} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
-					vgawb (VB_PART2_ADR, 0x30);
-					reg = vgarb (VB_PART2_DATA);
-					reg |= 0x20;
-					vgawb (VB_PART2_DATA, reg);
-
-					switch (ivideo.video_width) {
-					case 640:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xF1);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0xF7);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x1F);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0x32);
-						break;
-					case 720:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xF3);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0x00);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x1D);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0x20);
-						break;
-					case 800:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xFC);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0xFB);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x14);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0x2A);
-						break;
-					}
+		// Eden Chen
+		//vgawb(VB_PART1_ADR,  0x24);
+		vgawb(VB_PART1_ADR,  sisfb_CRT2_write_enable);
+		// ~Eden Chen
+		vgawb(VB_PART1_DATA, 0x01);
+		
+		if (ivideo.TV_type == TVMODE_NTSC) {
+			vgawb(VB_PART2_ADR, 0x3A);
+			reg = vgarb(VB_PART2_DATA);
+			reg &= 0x1F;
+			vgawb(VB_PART2_DATA, reg);
+
+			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
+				vgawb(VB_PART2_ADR, 0x30);
+				reg = vgarb(VB_PART2_DATA);
+				reg &= 0xDF;
+				vgawb(VB_PART2_DATA, reg);
+			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
+				vgawb(VB_PART2_ADR, 0x30);
+				reg = vgarb(VB_PART2_DATA);
+				reg |= 0x20;
+				vgawb(VB_PART2_DATA, reg);
+
+				switch (ivideo.video_width) {
+				case 640:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xEB);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0x04);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x25);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0x18);
+					break;
+				case 720:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xEE);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0x0C);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x22);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0x08);
+					break;
+				case 800:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xEB);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0x15);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x25);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0xF6);
+					break;
 				}
 			}
-			// Eden 
-			if ((filter >= 0) && (filter <= 7)) {
-				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],
-				     sis_TV_filter[filter_tb].filter[filter][3]
-				    );
-				vgawb (VB_PART2_ADR, 0x35);
-				vgawb (VB_PART2_DATA,
-				       sis_TV_filter[filter_tb].
-				       filter[filter][0]);
-				vgawb (VB_PART2_ADR, 0x36);
-				vgawb (VB_PART2_DATA,
-				       sis_TV_filter[filter_tb].
-				       filter[filter][1]);
-				vgawb (VB_PART2_ADR, 0x37);
-				vgawb (VB_PART2_DATA,
-				       sis_TV_filter[filter_tb].
-				       filter[filter][2]);
-				vgawb (VB_PART2_ADR, 0x38);
-				vgawb (VB_PART2_DATA,
-				       sis_TV_filter[filter_tb].
-				       filter[filter][3]);
+		} else if (ivideo.TV_type == TVMODE_PAL) {
+			vgawb(VB_PART2_ADR, 0x3A);
+			reg = vgarb(VB_PART2_DATA);
+			reg &= 0x1F;
+			vgawb(VB_PART2_DATA, reg);
+
+			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
+				vgawb(VB_PART2_ADR, 0x30);
+				reg = vgarb(VB_PART2_DATA);
+				reg &= 0xDF;
+				vgawb(VB_PART2_DATA, reg);
+			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
+				vgawb(VB_PART2_ADR, 0x30);
+				reg = vgarb(VB_PART2_DATA);
+				reg |= 0x20;
+				vgawb(VB_PART2_DATA, reg);
+
+				switch (ivideo.video_width) {
+				case 640:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xF1);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0xF7);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x1F);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0x32);
+					break;
+				case 720:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xF3);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0x00);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x1D);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0x20);
+					break;
+				case 800:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xFC);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0xFB);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x14);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0x2A);
+					break;
+				}
 			}
-			// ~Eden 
 		}
+
+		// Eden 
+		if ((filter >= 0) && (filter <=7)) {
+			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],
+				sis_TV_filter[filter_tb].filter[filter][3]
+			);
+			vgawb(VB_PART2_ADR,  0x35);
+			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][0]);
+			vgawb(VB_PART2_ADR,  0x36);
+			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][1]);
+			vgawb(VB_PART2_ADR,  0x37);
+			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][2]);
+			vgawb(VB_PART2_ADR,  0x38);
+			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][3]);
+		}
+		// ~Eden 
+	     }
+	  
 	}
 
 }
 
-static void sisfb_crtc_to_var (struct fb_var_screeninfo *var)
+static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
 {
 	u16 VRE, VBE, VRS, VBS, VDE, VT;
 	u16 HRE, HBE, HRS, HBS, HDE, HT;
-	u8 sr_data, cr_data, cr_data2, cr_data3, mr_data;
+	u8  sr_data, cr_data, cr_data2, cr_data3, mr_data;
 	int A, B, C, D, E, F, temp;
 	double hrate, drate;
 
-	vgawb (SEQ_ADR, IND_SIS_COLOR_MODE);
-	sr_data = vgarb (SEQ_DATA);
+	vgawb(SEQ_ADR, IND_SIS_COLOR_MODE);
+	sr_data = vgarb(SEQ_DATA);
 
 	if (sr_data & SIS_INTERLACED_MODE)
 		var->vmode = FB_VMODE_INTERLACED;
@@ -1800,25 +2126,25 @@
 		var->vmode = FB_VMODE_NONINTERLACED;
 
 	switch ((sr_data & 0x1C) >> 2) {
-	case SIS_8BPP_COLOR_MODE:
+	   case SIS_8BPP_COLOR_MODE:
 		var->bits_per_pixel = 8;
 		break;
-	case SIS_16BPP_COLOR_MODE:
+	   case SIS_16BPP_COLOR_MODE:
 		var->bits_per_pixel = 16;
 		break;
-	case SIS_32BPP_COLOR_MODE:
+	   case SIS_32BPP_COLOR_MODE:
 		var->bits_per_pixel = 32;
 		break;
 	}
 
 	switch (var->bits_per_pixel) {
-	case 8:
+	   case 8:
 		var->red.length = 6;
 		var->green.length = 6;
 		var->blue.length = 6;
 		video_cmap_len = 256;
 		break;
-	case 16:
+	   case 16:
 		var->red.offset = 11;
 		var->red.length = 5;
 		var->green.offset = 5;
@@ -1828,9 +2154,8 @@
 		var->transp.offset = 0;
 		var->transp.length = 0;
 		video_cmap_len = 16;
-
 		break;
-	case 24:
+	   case 24:
 		var->red.offset = 16;
 		var->red.length = 8;
 		var->green.offset = 8;
@@ -1841,7 +2166,7 @@
 		var->transp.length = 0;
 		video_cmap_len = 16;
 		break;
-	case 32:
+	   case 32:
 		var->red.offset = 16;
 		var->red.length = 8;
 		var->green.offset = 8;
@@ -1854,47 +2179,45 @@
 		break;
 	}
 
-	vgawb (SEQ_ADR, 0xA);
-	sr_data = vgarb (SEQ_DATA);
+	vgawb(SEQ_ADR, 0xA);
+	sr_data = vgarb(SEQ_DATA);
 
-	vgawb (CRTC_ADR, 0x6);
-	cr_data = vgarb (CRTC_DATA);
-	vgawb (CRTC_ADR, 0x7);
-	cr_data2 = vgarb (CRTC_DATA);
-	VT =
-	    (cr_data & 0xFF) | ((u16) (cr_data2 & 0x01) << 8) |
-	    ((u16) (cr_data2 & 0x20) << 4) | ((u16) (sr_data & 0x01) << 10);
+	vgawb(CRTC_ADR, 0x6);
+	cr_data = vgarb(CRTC_DATA);
+	vgawb(CRTC_ADR, 0x7);
+	cr_data2 = vgarb(CRTC_DATA);
+	VT = (cr_data & 0xFF) | ((u16) (cr_data2 & 0x01) << 8) |
+	     ((u16) (cr_data2 & 0x20) << 4) | ((u16) (sr_data & 0x01) <<
+					      10);
 	A = VT + 2;
 
-	vgawb (CRTC_ADR, 0x12);
-	cr_data = vgarb (CRTC_DATA);
-	VDE =
-	    (cr_data & 0xff) | ((u16) (cr_data2 & 0x02) << 7) |
-	    ((u16) (cr_data2 & 0x40) << 3) | ((u16) (sr_data & 0x02) << 9);
+	vgawb(CRTC_ADR, 0x12);
+	cr_data = vgarb(CRTC_DATA);
+	VDE = (cr_data & 0xff) | ((u16) (cr_data2 & 0x02) << 7) |
+	      ((u16) (cr_data2 & 0x40) << 3) | ((u16) (sr_data & 0x02) << 9);
 	E = VDE + 1;
 
-	vgawb (CRTC_ADR, 0x10);
-	cr_data = vgarb (CRTC_DATA);
-	VRS =
-	    (cr_data & 0xff) | ((u16) (cr_data2 & 0x04) << 6) |
-	    ((u16) (cr_data2 & 0x80) << 2) | ((u16) (sr_data & 0x08) << 7);
+	vgawb(CRTC_ADR, 0x10);
+	cr_data = vgarb(CRTC_DATA);
+	VRS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x04) << 6) |
+	      ((u16) (cr_data2 & 0x80) << 2) | ((u16) (sr_data & 0x08) << 7);
 	F = VRS + 1 - E;
 
-	vgawb (CRTC_ADR, 0x15);
-	cr_data = vgarb (CRTC_DATA);
-	vgawb (CRTC_ADR, 0x9);
-	cr_data3 = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x15);
+	cr_data = vgarb(CRTC_DATA);
+	vgawb(CRTC_ADR, 0x9);
+	cr_data3 = vgarb(CRTC_DATA);
 	VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |
-	    ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
+	      ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
 
-	vgawb (CRTC_ADR, 0x16);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x16);
+	cr_data = vgarb(CRTC_DATA);
 	VBE = (cr_data & 0xff) | ((u16) (sr_data & 0x10) << 4);
 	temp = VBE - ((E - 1) & 511);
 	B = (temp > 0) ? temp : (temp + 512);
 
-	vgawb (CRTC_ADR, 0x11);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x11);
+	cr_data = vgarb(CRTC_DATA);
 	VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
 	temp = VRE - ((E + F - 1) & 31);
 	C = (temp > 0) ? temp : (temp + 32);
@@ -1902,41 +2225,46 @@
 	D = B - F - C;
 
 	var->yres = var->yres_virtual = E;
+	/* TW: We have to report the physical dimension to the console! */
+	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+		var->yres <<= 1;
+		var->yres_virtual <<=1;
+	}
+	/* TW end */
 	var->upper_margin = D;
 	var->lower_margin = F;
 	var->vsync_len = C;
 
-	vgawb (SEQ_ADR, 0xb);
-	sr_data = vgarb (SEQ_DATA);
+	vgawb(SEQ_ADR, 0xb);
+	sr_data = vgarb(SEQ_DATA);
 
-	vgawb (CRTC_ADR, 0x0);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x0);
+	cr_data = vgarb(CRTC_DATA);
 	HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);
 	A = HT + 5;
 
-	vgawb (CRTC_ADR, 0x1);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x1);
+	cr_data = vgarb(CRTC_DATA);
 	HDE = (cr_data & 0xff) | ((u16) (sr_data & 0x0C) << 6);
 	E = HDE + 1;
 
-	vgawb (CRTC_ADR, 0x4);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x4);
+	cr_data = vgarb(CRTC_DATA);
 	HRS = (cr_data & 0xff) | ((u16) (sr_data & 0xC0) << 2);
 	F = HRS - E - 3;
 
-	vgawb (CRTC_ADR, 0x2);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x2);
+	cr_data = vgarb(CRTC_DATA);
 	HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);
 
-	vgawb (SEQ_ADR, 0xc);
-	sr_data = vgarb (SEQ_DATA);
-	vgawb (CRTC_ADR, 0x3);
-	cr_data = vgarb (CRTC_DATA);
-	vgawb (CRTC_ADR, 0x5);
-	cr_data2 = vgarb (CRTC_DATA);
-	HBE =
-	    (cr_data & 0x1f) | ((u16) (cr_data2 & 0x80) >> 2) |
-	    ((u16) (sr_data & 0x03) << 6);
+	vgawb(SEQ_ADR, 0xc);
+	sr_data = vgarb(SEQ_DATA);
+	vgawb(CRTC_ADR, 0x3);
+	cr_data = vgarb(CRTC_DATA);
+	vgawb(CRTC_ADR, 0x5);
+	cr_data2 = vgarb(CRTC_DATA);
+	HBE = (cr_data & 0x1f) | ((u16) (cr_data2 & 0x80) >> 2) |
+	      ((u16) (sr_data & 0x03) << 6);
 	HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
 
 	temp = HBE - ((E - 1) & 255);
@@ -1956,7 +2284,7 @@
 
 	var->sync = 0;
 
-	mr_data = vgarb (0x1C);
+	mr_data = vgarb(0x1C);
 	if (mr_data & 0x80)
 		var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
 	else
@@ -1978,21 +2306,24 @@
 
 /* ------------------ Public Routines -------------------------------- */
 
-static int sisfb_get_fix (struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
+static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info)
 {
-	memset (fix, 0, sizeof (struct fb_fix_screeninfo));
-	strcpy (fix->id, fb_info.modename);
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id, fb_info.modename);
 
 	fix->smem_start = ivideo.video_base;
-
-	/*karl:10/01/2001 */
-	if (!sisfb_mem) {
-		if (ivideo.video_size > 0x800000)
-			fix->smem_len = 0x800000;
-		else
-			fix->smem_len = 0x400000;
-	} else
-		fix->smem_len = sisfb_mem * 0x100000;
+        
+        /*karl:10/01/2001*/ /* 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;
+        } else
+		fix->smem_len = sisfb_mem * 1024;
 
 	fix->type = video_type;
 	fix->type_aux = 0;
@@ -2012,98 +2343,121 @@
 	fix->reserved[2] = sisfb_caps;
 
 	return 0;
-
 }
 
-static int sisfb_get_var (struct fb_var_screeninfo *var, int con, struct fb_info *info)
+static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
 {
 	if (con == -1)
-		memcpy (var, &default_var, sizeof (struct fb_var_screeninfo));
+		memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
 	else
 		*var = fb_display[con].var;
 
+	/* JennyLee 2001126: for FSTN */
+	if (var->xres == 320 && var->yres == 480)
+		var->yres = 240;
+	/* ~JennyLee */
+
 	return 0;
 }
 
-static int sisfb_set_var (struct fb_var_screeninfo *var, int con, struct fb_info *info)
+static int sisfb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
 {
 	int err;
 	unsigned int cols, rows;
 
 	fb_display[con].var.activate = FB_ACTIVATE_NOW;
-
-	if (sisfb_do_set_var (var, con == info->currcon, info)) {
-		sisfb_crtc_to_var (var);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
+	if (sisfb_do_set_var(var, con == info->currcon, info)) {
+#else
+        if (sisfb_do_set_var(var, con == currcon, info)) {
+#endif
+		sisfb_crtc_to_var(var);
 		return -EINVAL;
 	}
 
-	sisfb_crtc_to_var (var);
-
-	sisfb_set_disp (con, var);
+	sisfb_crtc_to_var(var);
+	
+	sisfb_set_disp(con, var);
 
 	if (info->changevar)
 		(*info->changevar) (con);
 
-	if ((err = fb_alloc_cmap (&fb_display[con].cmap, 0, 0)))
+	if ((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0)))
 		return err;
 
-	sisfb_do_install_cmap (con, info);
-
+	sisfb_do_install_cmap(con, info);
+	
 	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);
+	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
 
 	return 0;
-
 }
 
-static int sisfb_get_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
+static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
 {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
 	if (con == info->currcon)
-		return fb_get_cmap (cmap, kspc, sis_getcolreg, info);
-	else if (fb_display[con].cmap.len)
-		fb_copy_cmap (&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+#else
+        if (con == currcon)
+#endif
+		return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
+	else if (fb_display[con].cmap.len)	
+		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
 	else
-		fb_copy_cmap (fb_default_cmap (video_cmap_len), cmap,
-			      kspc ? 0 : 2);
+		fb_copy_cmap(fb_default_cmap(video_cmap_len), cmap, kspc ? 0 : 2);
 
 	return 0;
 }
 
-static int sisfb_set_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
+static int sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
 {
 	int err;
 
 	if (!fb_display[con].cmap.len) {
-		err = fb_alloc_cmap (&fb_display[con].cmap, video_cmap_len, 0);
+		err = fb_alloc_cmap(&fb_display[con].cmap, video_cmap_len, 0);
 		if (err)
 			return err;
 	}
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
 	if (con == info->currcon)
-		return fb_set_cmap (cmap, kspc, info);
+		return fb_set_cmap(cmap, kspc, info);
+#else
+        if (con == currcon)
+		return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
+#endif
 	else
-		fb_copy_cmap (cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
 	return 0;
 }
 
-static int sisfb_ioctl (struct inode *inode, struct file *file,
-	     unsigned int cmd, unsigned long arg, int con, struct fb_info *info)
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg, int con,
+		       struct fb_info *info)
 {
 	switch (cmd) {
-	case FBIO_ALLOC:
-		if (!capable (CAP_SYS_RAWIO))
+	   case FBIO_ALLOC:
+		if (!capable(CAP_SYS_RAWIO))
 			return -EPERM;
-		sis_malloc ((struct sis_memreq *) arg);
+		sis_malloc((struct sis_memreq *) arg);
 		break;
-	case FBIO_FREE:
-		if (!capable (CAP_SYS_RAWIO))
+	   case FBIO_FREE:
+		if (!capable(CAP_SYS_RAWIO))
 			return -EPERM;
-		sis_free (*(unsigned long *) arg);
+		sis_free(*(unsigned long *) arg);
 		break;
-	case FBIOGET_GLYPH:
-		sis_get_glyph (info, (SIS_GLYINFO *) arg);
+	   case FBIOGET_GLYPH:
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
+		sis_get_glyph((SIS_GLYINFO *) arg);
+#else
+                sis_get_glyph(info,(SIS_GLYINFO *) arg);
+#endif
 		break;
-	case FBIOGET_HWCINFO:
+	   case FBIOGET_HWCINFO:
 		{
 			unsigned long *hwc_offset = (unsigned long *) arg;
 
@@ -2115,32 +2469,47 @@
 
 			break;
 		}
-	case FBIOPUT_MODEINFO:
+	   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;
-
-			break;
+			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;
+			
+			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;
+	                break;
 		}
-	case FBIOGET_DISPINFO:
-		sis_dispinfo ((struct ap_data *) arg);
-		break;
-	default:
+	   default:
 		return -EINVAL;
 	}
 	return 0;
 
 }
 
-static int sisfb_mmap (struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int sisfb_mmap(struct fb_info *info, struct file *file,
+		      struct vm_area_struct *vma)
 {
 	struct fb_var_screeninfo var;
 	unsigned long start;
@@ -2150,17 +2519,21 @@
 	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
 		return -EINVAL;
 	off = vma->vm_pgoff << PAGE_SHIFT;
-
+	
 	start = (unsigned long) ivideo.video_base;
-	len = PAGE_ALIGN ((start & ~PAGE_MASK) + ivideo.video_size);
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.video_size);
 
 	if (off >= len) {
 		off -= len;
-		sisfb_get_var (&var, info->currcon, info);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
+		sisfb_get_var(&var, info->currcon, info);
+#else
+		sisfb_get_var(&var, currcon, info);
+#endif
 		if (var.accel_flags)
 			return -EINVAL;
 		start = (unsigned long) ivideo.mmio_base;
-		len = PAGE_ALIGN ((start & ~PAGE_MASK) + sisfb_mmio_size);
+		len = PAGE_ALIGN((start & ~PAGE_MASK) + sisfb_mmio_size);
 	}
 
 	start &= PAGE_MASK;
@@ -2169,11 +2542,17 @@
 	off += start;
 	vma->vm_pgoff = off >> PAGE_SHIFT;
 
-#if defined(__i386__)
+#if defined(__i386__) || defined(__x86_64__)
 	if (boot_cpu_data.x86 > 3)
-		pgprot_val (vma->vm_page_prot) |= _PAGE_PCD;
+		pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
+#else	/* TW: 2.5 API */
+	if (io_remap_page_range(vma, vma->vm_start, off, vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
 #endif
-	if (io_remap_page_range(vma, vma->vm_start, off, vma->vm_end - vma->vm_start, vma->vm_page_prot)) 
 		return -EAGAIN;
 	return 0;
 
@@ -2186,69 +2565,85 @@
 	fb_set_var:	sisfb_set_var,
 	fb_get_cmap:	sisfb_get_cmap,
 	fb_set_cmap:	sisfb_set_cmap,
-	fb_setcolreg:	sisfb_setcolreg,
-	fb_blank:	sisfb_blank,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
+        fb_setcolreg:   sisfb_setcolreg,
+        fb_blank:       sisfb_blank,
+#endif
 	fb_ioctl:	sisfb_ioctl,
 	fb_mmap:	sisfb_mmap,
 };
 
 /* ------------ Interface to the low level console driver -------------*/
 
-static int sisfb_update_var (int con, struct fb_info *info)
+static int sisfb_update_var(int con, struct fb_info *info)
 {
 	return 0;
 }
 
-static int sisfb_switch (int con, struct fb_info *info)
+static int sisfb_switch(int con, struct fb_info *info)
 {
 	int cols, rows;
 
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
 	if (fb_display[info->currcon].cmap.len)
-		fb_get_cmap (&fb_display[info->currcon].cmap, 1, sis_getcolreg, info);
+		fb_get_cmap(&fb_display[info->currcon].cmap, 1, sis_getcolreg, info);
+#else
+        if (fb_display[currcon].cmap.len)
+		fb_get_cmap(&fb_display[currcon].cmap, 1, sis_getcolreg, info);
+#endif
 
 	fb_display[con].var.activate = FB_ACTIVATE_NOW;
 
-	if (!memcmp(&fb_display[con].var, &fb_display[info->currcon].var, sizeof (struct fb_var_screeninfo))) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
+	if (!memcmp(&fb_display[con].var, &fb_display[info->currcon].var,
+	                           sizeof(struct fb_var_screeninfo))) {
 		info->currcon = con;
 		return 1;
 	}
 
 	info->currcon = con;
+#else
+	if (!memcmp(&fb_display[con].var, &fb_display[currcon].var,
+	                           sizeof(struct fb_var_screeninfo))) {
+		currcon = con;
+		return 1;
+	}
 
-	sisfb_do_set_var (&fb_display[con].var, 1, info);
+	currcon = con;
+#endif
 
-	sisfb_set_disp (con, &fb_display[con].var);
+	sisfb_do_set_var(&fb_display[con].var, 1, info);
 
-	sisfb_do_install_cmap (con, info);
+	sisfb_set_disp(con, &fb_display[con].var);
+	
+	sisfb_do_install_cmap(con, info);
 
 	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);
+	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
 
-	sisfb_update_var (con, info);
+	sisfb_update_var(con, info);
 
 	return 1;
-
 }
 
-static int sisfb_blank(int blank, struct fb_info *info)
+static void sisfb_blank(int blank, struct fb_info *info)
 {
 	u8 reg;
 
-	vgawb (CRTC_ADR, 0x17);
-	reg = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x17);
+	reg = vgarb(CRTC_DATA);
 
-	if (blank > 0)
+	if (blank > 0)		
 		reg &= 0x7f;
-	else
+	else			
 		reg |= 0x80;
 
-	vgawb (CRTC_ADR, 0x17);
-	vgawb (CRTC_DATA, reg);
-	return 0;
+	vgawb(CRTC_ADR, 0x17);
+	vgawb(CRTC_DATA, reg);
 }
 
-int sisfb_setup (char *options)
+int sisfb_setup(char *options)
 {
 	char *this_opt;
 
@@ -2258,46 +2653,60 @@
 	if (!options || !*options)
 		return 0;
 
-	while ((this_opt = strsep (&options, ",")) != NULL) {
+	while((this_opt = strsep(&options, ",")) != NULL) {
 		if (!*this_opt)
 			continue;
 
-		if (!strcmp (this_opt, "inverse")) {
+		if (!strcmp(this_opt, "inverse")) {
 			sisfb_inverse = 1;
-			fb_invert_cmaps ();
-		} else if (!strncmp (this_opt, "font:", 5)) {
-			strcpy (fb_info.fontname, this_opt + 5);
-		} else if (!strncmp (this_opt, "mode:", 5)) {
-			sisfb_search_mode (this_opt + 5);
-		} else if (!strncmp (this_opt, "vrate:", 6)) {
+			fb_invert_cmaps();
+		} else if (!strncmp(this_opt, "font:", 5)) {
+			strcpy(fb_info.fontname, this_opt + 5);
+		} else if (!strncmp(this_opt, "mode:", 5)) {
+			sisfb_search_mode(this_opt + 5);
+		} else if (!strncmp(this_opt, "vrate:", 6)) {
 			ivideo.refresh_rate =
-			    simple_strtoul (this_opt + 6, NULL, 0);
-		} else if (!strncmp (this_opt, "off", 3)) {
+			    simple_strtoul(this_opt + 6, NULL, 0);
+		} else if (!strncmp(this_opt, "rate:", 5)) {
+			ivideo.refresh_rate =
+			    simple_strtoul(this_opt + 5, NULL, 0);
+		} else if (!strncmp(this_opt, "off", 3)) {
 			sisfb_off = 1;
-		} else if (!strncmp (this_opt, "crt1off", 7)) {
+		} else if (!strncmp(this_opt, "crt1off", 7)) {
 			sisfb_crt1off = 1;
-		} else if (!strncmp (this_opt, "filter:", 7)) {
-			filter = (int) simple_strtoul (this_opt + 7, NULL, 0);
-		}
-		/*karl */
-		else if (!strncmp (this_opt, "tvmode:", 7)) {
-			if (!strncmp (this_opt + 7, "pal", 3))
-				sisfb_tvmode = 1;
-			if (!strncmp (this_opt + 7, "ntsc", 4))
-				sisfb_tvmode = 2;
+		} else if (!strncmp(this_opt, "filter:", 7)) {
+			filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
+		} else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
+			sisfb_search_crt2type(this_opt + 14);
+		} else if (!strncmp(this_opt, "forcecrt1:", 10)) {
+			sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
+                } else if (!strncmp(this_opt, "tvmode:",7)) {
+                        if (!strncmp(this_opt + 7, "pal",3))
+                         	sisfb_tvmode = 1;
+                        if (!strncmp(this_opt + 7, "ntsc",4))
+                         	sisfb_tvmode = 2;
+                } else if (!strncmp(this_opt, "mem:",4)) {
+		        sisfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
+                } else if (!strncmp(this_opt, "dstn:", 5)) {
+			enable_dstn = simple_strtoul(this_opt + 5, NULL, 0);
+			/* TW: DSTN overrules forcecrt2type */
+			if (enable_dstn) sisfb_crt2type = DISPTYPE_LCD;
+		} else if (!strncmp(this_opt, "queuemode:", 10)) {
+			sisfb_search_queuemode(this_opt + 10);
+		} else if (!strncmp(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 {
+			printk(KERN_INFO "sisfb: Invalid parameter %s\n", this_opt);
 		}
-		/*karl:10/01/2001 */
-		else if (!strncmp (this_opt, "mem:", 4)) {
-
-			sisfb_mem = simple_strtoul (this_opt + 4, NULL, 0);
-
-		} else
-			DPRINTK ("invalid parameter %s\n", this_opt);
 	}
 	return 0;
 }
 
-int __init sisfb_init (void)
+int __init sisfb_init(void)
 {
 	struct pci_dev *pdev = NULL;
 	struct board *b;
@@ -2305,493 +2714,689 @@
 	//unsigned long rom_vbase;
 	u32 reg32;
 	u16 reg16;
-	u8 reg;
-	int nRes;
+	u8  reg;
+	int temp1, temp2;
 
-	outb (0x77, 0x80);
+	outb(0x77, 0x80);
+
+#if 0 	
+	/* for DOC VB */
+	sisfb_set_reg4(0xcf8,0x800000e0);
+	reg32 = sisfb_get_reg3(0xcfc);
+	reg32 = reg32 | 0x00001000;
+	sisfb_set_reg4(0xcfc,reg32);
+	}
+#endif
 
 	if (sisfb_off)
 		return -ENXIO;
 
-	pci_for_each_dev (pdev)
-	{
+	if (enable_dstn)
+		SetEnableDstn();
+
+	pci_for_each_dev(pdev) {
 		for (b = sisdev_list; b->vendor; b++) {
 			if ((b->vendor == pdev->vendor)
 			    && (b->device == pdev->device)) {
 				pdev_valid = 1;
-				strcpy (fb_info.modename, b->name);
+				strcpy(fb_info.modename, b->name);
 				ivideo.chip_id = pdev->device;
-				pci_read_config_byte (pdev, PCI_REVISION_ID,
-						      &ivideo.revision_id);
-				pci_read_config_word (pdev, PCI_COMMAND, &reg16);
-				// Eden Chen
-				//sishw_ext.uRevisionID = ivideo.revision_id;
+				pci_read_config_byte(pdev, PCI_REVISION_ID,
+				                     &ivideo.revision_id);
+				pci_read_config_word(pdev, PCI_COMMAND, &reg16);
 				sishw_ext.jChipRevision = ivideo.revision_id;
-				// ~Eden Chen
 				sisvga_enabled = reg16 & 0x1;
 				break;
 			}
 		}
-	
+
 		if (pdev_valid)
 			break;
 	}
-	
+
 	if (!pdev_valid)
 		return -1;
-	
-	// Eden Chen
+
+// Eden Chen
 	switch (ivideo.chip_id) {
-	case PCI_DEVICE_ID_SI_300:
+	   case PCI_DEVICE_ID_SI_300:
 		ivideo.chip = SIS_300;
 		sisvga_engine = SIS_300_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
 		break;
-	case PCI_DEVICE_ID_SI_630_VGA:
-	{
-		sisfb_set_reg4 (0xCF8, 0x80000000);
-		reg32 = sisfb_get_reg3 (0xCFC);
-		if (reg32 == 0x07301039) {
-			ivideo.chip = SIS_730;
-			strcpy (fb_info.modename, "SIS 730");
-		} else
-			ivideo.chip = SIS_630;
-
-		sisvga_engine = SIS_300_VGA;
-		break;
-	}
-	case PCI_DEVICE_ID_SI_540_VGA:
+	   case PCI_DEVICE_ID_SI_630_VGA:
+		{
+			sisfb_set_reg4(0xCF8, 0x80000000);
+			reg32 = sisfb_get_reg3(0xCFC);
+			if (reg32 == 0x07301039) {
+				ivideo.chip = SIS_730;
+				strcpy(fb_info.modename, "SIS 730");
+			} else
+				ivideo.chip = SIS_630;
+
+			sisvga_engine = SIS_300_VGA;
+			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300;
+			sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
+			break;
+		}
+	   case PCI_DEVICE_ID_SI_540_VGA:
 		ivideo.chip = SIS_540;
 		sisvga_engine = SIS_300_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
 		break;
-	case PCI_DEVICE_ID_SI_315H:
+	   case PCI_DEVICE_ID_SI_315H:
 		ivideo.chip = SIS_315H;
 		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
-	case PCI_DEVICE_ID_SI_315:
+	   case PCI_DEVICE_ID_SI_315:
 		ivideo.chip = SIS_315;
 		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
-	case PCI_DEVICE_ID_SI_315PRO:
+	   case PCI_DEVICE_ID_SI_315PRO:
 		ivideo.chip = SIS_315PRO;
 		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
-	case PCI_DEVICE_ID_SI_550_VGA:
+	   case PCI_DEVICE_ID_SI_550_VGA:
 		ivideo.chip = SIS_550;
 		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
+		break;
+	   case PCI_DEVICE_ID_SI_650_VGA:
+		ivideo.chip = SIS_650;
+		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
 	}
-
-	// Eden Chen
-	//sishw_ext.jChipID = ivideo.chip;
 	sishw_ext.jChipType = ivideo.chip;
 	// for Debug
-	if ((sishw_ext.jChipType == SIS_315PRO)
-	    || (sishw_ext.jChipType == SIS_315))
+	if ((sishw_ext.jChipType == SIS_315PRO) 
+	   || (sishw_ext.jChipType == SIS_315) )
 		sishw_ext.jChipType = SIS_315H;
-		// ~Eden Chen
 
-	DPRINTK ("%s is used as %s device(VGA Engine %d).\n",
-		 fb_info.modename, sisvga_enabled ? "primary" : "secondary",
-		 sisvga_engine);
-	
-	ivideo.video_base = pci_resource_start (pdev, 0);
-	ivideo.mmio_base = pci_resource_start (pdev, 1);
-	// Eden Chen
-	//sishw_ext.IOAddress = (unsigned short) ivideo.vga_base 
-	//      = pci_resource_start(pdev, 2) + 0x30;
-	sishw_ext.ulIOAddress = (unsigned short) ivideo.vga_base = pci_resource_start (pdev, 2) + 0x30;
-	// ~Eden Chen
+	DPRINTK("%s is used as %s device(VGA Engine %d).\n", 
+		fb_info.modename, sisvga_enabled ? "primary" : "secondary", sisvga_engine);
 
-	sisfb_mmio_size = pci_resource_len (pdev, 1);
+	ivideo.video_base = pci_resource_start(pdev, 0);
+	ivideo.mmio_base = pci_resource_start(pdev, 1);
+	sishw_ext.ulIOAddress = (unsigned short) ivideo.vga_base =
+		                   pci_resource_start(pdev, 2) + 0x30;
+
+	sisfb_mmio_size =  pci_resource_len(pdev, 1);
 
 	if (!sisvga_enabled)
-		if (pci_enable_device (pdev))
-			return -EIO;
+		if (pci_enable_device(pdev))   return -EIO;
+
+// Eden Eden
+//#ifdef LINUXBIOS
+//	sishw_ext.VirtualRomBase = rom_vbase = (unsigned long) rom_data;
+//#else
+//	{
+//	unsigned long rom_base  = 0x000C0000;
+//
+//	request_region(rom_base, 32, "sisfb");
+//	sishw_ext.VirtualRomBase = rom_vbase 
+//		= (unsigned long) ioremap(rom_base, MAX_ROM_SCAN);
+//	}
+//#endif
+// ~Eden Chen
 	
-	vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-	vgawb (SEQ_DATA, SIS_PASSWORD);
+	vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+	vgawb(SEQ_DATA, SIS_PASSWORD);
+
+        /* TW: Debug kernel 2.5 problem */
+	vgawb(SEQ_ADR, 0x14);
+	reg = vgarb(SEQ_DATA);
+	printk("sisfb: SR14 = 0x%02x\n", reg);
+	/* /TW */
 
 #ifdef LINUXBIOS
 #ifdef CONFIG_FB_SIS_300
-	if (sisvga_engine == SIS_300_VGA)
-	{
-		vgawb (SEQ_ADR, 0x28);
-		vgawb (SEQ_DATA, 0x37);
+	if (sisvga_engine == SIS_300_VGA) {
+		vgawb(SEQ_ADR, 0x28);
+		vgawb(SEQ_DATA, 0x37);
 
-		vgawb (SEQ_ADR, 0x29);
-		vgawb (SEQ_DATA, 0x61);
+		vgawb(SEQ_ADR, 0x29);
+		vgawb(SEQ_DATA, 0x61);
 
-		vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
-		reg = vgarb (SEQ_DATA);
+		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
+		reg = vgarb(SEQ_DATA);
 		reg |= SIS_SCRATCH_REG_1A_MASK;
-		vgawb (SEQ_DATA, reg);
+		vgawb(SEQ_DATA, reg);
 	}
 #endif
 #ifdef CONFIG_FB_SIS_315
-	if (ivideo.chip == SIS_550) {
-		vgawb (SEQ_ADR, 0x28);
-		vgawb (SEQ_DATA, 0x5A);
-	
-		vgawb (SEQ_ADR, 0x29);
-		vgawb (SEQ_DATA, 0x64);
+	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650) {
+		vgawb(SEQ_ADR,  0x28);
+		vgawb(SEQ_DATA, 0x5A);
 
-		vgawb (CRTC_ADR, 0x3A);
-		vgawb (CRTC_DATA, 0x00);
+		vgawb(SEQ_ADR,  0x29);
+		vgawb(SEQ_DATA, 0x64);
+
+		vgawb(CRTC_ADR,  0x3A);
+		vgawb(CRTC_DATA, 0x00);
 	}
 #endif
-#endif
+#endif /* LinuxBIOS */
 
 	if (sisvga_engine == SIS_315_VGA) {
 		switch (ivideo.chip) {
-		case SIS_315H:
-		case SIS_315:
+		   case SIS_315H:
+		   case SIS_315:
 			sishw_ext.bIntegratedMMEnabled = TRUE;
 			break;
-		case SIS_550:
+		   case SIS_550:
+		   case SIS_650:
 			// Eden Chen
 			//vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
 			//reg = vgarb(SEQ_DATA);
 			//if (reg & SIS_SCRATCH_REG_1A_MASK)
-			//      sishw_ext.bIntegratedMMEnabled = TRUE;
+			//	sishw_ext.bIntegratedMMEnabled = TRUE;
 			//else
-			//      sishw_ext.bIntegratedMMEnabled = FALSE;
+			//	sishw_ext.bIntegratedMMEnabled = FALSE;
 			//for Debug
 			sishw_ext.bIntegratedMMEnabled = TRUE;
 			// ~Eden Chen
 			break;
-		default:
+		   default:
 			break;
 		}
 	} else if (sisvga_engine == SIS_300_VGA) {
 		if (ivideo.chip == SIS_300) {
 			sishw_ext.bIntegratedMMEnabled = TRUE;
 		} else {
-			vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
-			reg = vgarb (SEQ_DATA);
+			vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
+			reg = vgarb(SEQ_DATA);
 			if (reg & SIS_SCRATCH_REG_1A_MASK)
 				sishw_ext.bIntegratedMMEnabled = TRUE;
 			else
 				sishw_ext.bIntegratedMMEnabled = FALSE;
 		}
 	}
-	// Eden Chen
+
 	sishw_ext.pDevice = NULL;
 	sishw_ext.pjVirtualRomBase = NULL;
 	sishw_ext.pjCustomizedROMImage = NULL;
 	sishw_ext.bSkipDramSizing = 0;
 	sishw_ext.pQueryVGAConfigSpace = &sisfb_query_VGA_config_space;
 	sishw_ext.pQueryNorthBridgeSpace = &sisfb_query_north_bridge_space;
-	strcpy (sishw_ext.szVBIOSVer, "0.84");
+	strcpy(sishw_ext.szVBIOSVer, "0.84");
 
-	sishw_ext.pSR = vmalloc (sizeof (SIS_DSReg) * SR_BUFFER_SIZE);
-	if (sishw_ext.pSR == NULL)
-		printk (KERN_DEBUG "Allocated SRReg space fail.\n");
+	/* TW: Mode numbers for 1280x960 are different for 300 and 310/325 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;
+	}
+
+	sishw_ext.pSR = vmalloc(sizeof(SIS_DSReg) * SR_BUFFER_SIZE);
+	if (sishw_ext.pSR == NULL) {
+		printk(KERN_INFO "sisfb: Fatal error: Allocating SRReg space failed.\n");
+		return -ENODEV;
+	}
 	sishw_ext.pSR[0].jIdx = sishw_ext.pSR[0].jVal = 0xFF;
 
-	sishw_ext.pCR = vmalloc (sizeof (SIS_DSReg) * CR_BUFFER_SIZE);
-	if (sishw_ext.pCR == NULL)
-		printk (KERN_DEBUG "Allocated CRReg space fail.\n");
+	sishw_ext.pCR = vmalloc(sizeof(SIS_DSReg) * CR_BUFFER_SIZE);
+	if (sishw_ext.pCR == NULL) {
+		printk(KERN_INFO "sisfb: Fatal error: Allocating CRReg space failed.\n");
+		return -ENODEV;
+	}
 	sishw_ext.pCR[0].jIdx = sishw_ext.pCR[0].jVal = 0xFF;
-	// ~Eden Chen
 
-	#ifdef CONFIG_FB_SIS_300
+#ifdef CONFIG_FB_SIS_300
 	if (sisvga_engine == SIS_300_VGA) {
 		if (!sisvga_enabled) {
-			// Eden Chen
-			sishw_ext.pjVideoMemoryAddress = ioremap (ivideo.video_base, 0x2000000);
-			//SiSInit300(&sishw_ext);
-			SiSInit (&sishw_ext);
-			vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-			vgawb (SEQ_DATA, SIS_PASSWORD);
-			// ~Eden Chen
+			sishw_ext.pjVideoMemoryAddress
+				= ioremap(ivideo.video_base, 0x2000000);
+			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+				SiSInit(&sishw_ext);
+				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+				vgawb(SEQ_DATA, SIS_PASSWORD);
+			}
 		}
 #ifdef LINUXBIOS
 		else {
-			// Eden Chen
 			sishw_ext.pjVideoMemoryAddress
-			    = ioremap (ivideo.video_base, 0x2000000);
-			//SiSInit300(&sishw_ext);
-			SiSInit (&sishw_ext);
-			vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-			vgawb (SEQ_DATA, SIS_PASSWORD);
-			// ~Eden Chen
+				= ioremap(ivideo.video_base, 0x2000000);
+			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+				SiSInit(&sishw_ext);
+				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+				vgawb(SEQ_DATA, SIS_PASSWORD);
+			}
+		}
+		if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+			vgawb(SEQ_ADR, 0x7);
+			reg = vgarb(SEQ_DATA);
+			reg |= 0x10;
+			vgawb(SEQ_DATA, reg);
 		}
-		vgawb (SEQ_ADR, 0x7);
-		reg = vgarb (SEQ_DATA);
-		reg |= 0x10;
-		vgawb (SEQ_DATA, reg);
 #endif
-		sisfb_get_dram_size_300 ();
+		if (sisfb_get_dram_size_300()) {
+			printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size\n");
+			return -ENODEV;
+		}
 	}
 #endif
 
-	#ifdef CONFIG_FB_SIS_315
+#ifdef CONFIG_FB_SIS_315
 	if (sisvga_engine == SIS_315_VGA) {
 		if (!sisvga_enabled) {
 			/* Mapping Max FB Size for 315 Init */
 			// Eden Chen
 			//sishw_ext.VirtualVideoMemoryAddress 
-			sishw_ext.pjVideoMemoryAddress = ioremap (ivideo.video_base, 0x8000000);
-			//SiSInit310(&sishw_ext);
-			SiSInit (&sishw_ext);
-	
-			vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-			vgawb (SEQ_DATA, SIS_PASSWORD);
-	
-			sishw_ext.bSkipDramSizing = TRUE;
-			vgawb (SEQ_ADR, 0x13);
-			sishw_ext.pSR[0].jIdx = 0x13;
-			sishw_ext.pSR[0].jVal = vgarb (SEQ_DATA);
-			vgawb (SEQ_ADR, 0x14);
-			sishw_ext.pSR[1].jIdx = 0x14;
-			sishw_ext.pSR[1].jVal = vgarb (SEQ_DATA);
-			sishw_ext.pSR[2].jIdx = 0xFF;
-			sishw_ext.pSR[2].jVal = 0xFF;
-			// Eden Chen
+			sishw_ext.pjVideoMemoryAddress 
+				= ioremap(ivideo.video_base, 0x8000000);
+			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+				SiSInit(&sishw_ext);
+
+				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+				vgawb(SEQ_DATA, SIS_PASSWORD);
+
+				sishw_ext.bSkipDramSizing = TRUE;
+				vgawb(SEQ_ADR, 0x13);
+				sishw_ext.pSR[0].jIdx = 0x13;
+				sishw_ext.pSR[0].jVal = vgarb(SEQ_DATA);
+				vgawb(SEQ_ADR, 0x14);
+				sishw_ext.pSR[1].jIdx = 0x14;
+				sishw_ext.pSR[1].jVal = vgarb(SEQ_DATA);
+				sishw_ext.pSR[2].jIdx = 0xFF;
+				sishw_ext.pSR[2].jVal = 0xFF;
+			}
 		}
 #ifdef LINUXBIOS
 		else {
-			sishw_ext.pjVideoMemoryAddress = ioremap (ivideo.video_base, 0x8000000);
-			SiSInit (&sishw_ext);
-			vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-			vgawb (SEQ_DATA, SIS_PASSWORD);
-	
-			sishw_ext.bSkipDramSizing = TRUE;
-			vgawb (SEQ_ADR, 0x13);
-			sishw_ext.pSR[0].jIdx = 0x13;
-			sishw_ext.pSR[0].jVal = vgarb (SEQ_DATA);
-			vgawb (SEQ_ADR, 0x14);
-			sishw_ext.pSR[1].jIdx = 0x14;
-			sishw_ext.pSR[1].jVal = vgarb (SEQ_DATA);
-			sishw_ext.pSR[2].jIdx = 0xFF;
-			sishw_ext.pSR[2].jVal = 0xFF;
-		}
-#endif
-		sisfb_get_dram_size_315 ();
-	}
-#endif
-	//Eden Chen 
-	vgawb (SEQ_ADR, IND_SIS_PCI_ADDRESS_SET);
-	reg = vgarb (SEQ_DATA);
-	reg |= SIS_PCI_ADDR_ENABLE;
-	reg |= SIS_MEM_MAP_IO_ENABLE;
-	vgawb (SEQ_DATA, reg);
-
-	vgawb (SEQ_ADR, IND_SIS_MODULE_ENABLE);
-	reg = vgarb (SEQ_DATA);
-	reg |= SIS_ENABLE_2D;
-	vgawb (SEQ_DATA, reg);
-	//~Eden Chen
+			sishw_ext.pjVideoMemoryAddress
+				= ioremap(ivideo.video_base, 0x8000000);
+			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+				SiSInit(&sishw_ext);
+				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+				vgawb(SEQ_DATA, SIS_PASSWORD);
+
+				sishw_ext.bSkipDramSizing = TRUE;
+				vgawb(SEQ_ADR, 0x13);
+				sishw_ext.pSR[0].jIdx = 0x13;
+				sishw_ext.pSR[0].jVal = vgarb(SEQ_DATA);
+				vgawb(SEQ_ADR, 0x14);
+				sishw_ext.pSR[1].jIdx = 0x14;
+				sishw_ext.pSR[1].jVal = vgarb(SEQ_DATA);
+				sishw_ext.pSR[2].jIdx = 0xFF;
+				sishw_ext.pSR[2].jVal = 0xFF;
+			}
+		}
+#endif
+		if (sisfb_get_dram_size_315()) {
+			printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
+			return -ENODEV;
+		}
+	}
+#endif
+	if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+
+		vgawb(SEQ_ADR, IND_SIS_PCI_ADDRESS_SET);
+		reg = vgarb(SEQ_DATA);
+		reg |= SIS_PCI_ADDR_ENABLE;    	/* Enable PCI_LINEAR_ADDRESSING */
+		reg |= SIS_MEM_MAP_IO_ENABLE;  	/* Enable MMIO_ENABLE */
+		vgawb(SEQ_DATA, reg);
+
+		vgawb(SEQ_ADR, IND_SIS_MODULE_ENABLE);
+		reg = vgarb(SEQ_DATA);
+		reg |= SIS_ENABLE_2D;		/* Enable 2D accelerator engine */
+		vgawb(SEQ_DATA, reg);
+
+	}
 
-	// Eden Chen
 	sishw_ext.ulVideoMemorySize = ivideo.video_size;
-	// ~Eden Chen
-	if (!request_mem_region (ivideo.video_base, ivideo.video_size, "sisfb FB")) {
-		printk (KERN_ERR "sisfb: cannot reserve frame buffer memory\n");
+
+	if(sisfb_pdc) {
+	    sishw_ext.pdc = sisfb_pdc;
+	} else {
+	    sishw_ext.pdc = 0;
+	}
+
+	if (!request_mem_region(ivideo.video_base, ivideo.video_size, "sisfb FB")) {
+		printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n");
+		printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
 		return -ENODEV;
 	}
 
-	if (!request_mem_region (ivideo.mmio_base, sisfb_mmio_size, "sisfb MMIO")) {
-		printk (KERN_ERR "sisfb: cannot reserve MMIO region\n");
-		release_mem_region (ivideo.video_base, ivideo.video_size);
+	if (!request_mem_region(ivideo.mmio_base, sisfb_mmio_size, "sisfb MMIO")) {
+		printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
+		release_mem_region(ivideo.video_base, ivideo.video_size);
 		return -ENODEV;
 	}
-	// Eden Chen
-	//sishw_ext.VirtualVideoMemoryAddress = ivideo.video_vbase 
-	sishw_ext.pjVideoMemoryAddress = ivideo.video_vbase = ioremap (ivideo.video_base, ivideo.video_size);
-	// Eden Chen
-	ivideo.mmio_vbase = ioremap (ivideo.mmio_base, sisfb_mmio_size);
 
-	printk (KERN_INFO
-		"sisfb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
-		ivideo.video_base, ivideo.video_vbase, ivideo.video_size / 1024);
+	sishw_ext.pjVideoMemoryAddress = ivideo.video_vbase
+		= ioremap(ivideo.video_base, ivideo.video_size);
+	ivideo.mmio_vbase = ioremap(ivideo.mmio_base, sisfb_mmio_size);
+
+	printk(KERN_INFO
+	       "sisfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
+	       ivideo.video_base, ivideo.video_vbase,
+	       ivideo.video_size / 1024);
+
+	printk(KERN_INFO
+	       "sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
+	       ivideo.mmio_base, ivideo.mmio_vbase,
+	       sisfb_mmio_size / 1024);
 
-	printk (KERN_INFO
-		"sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
-		ivideo.mmio_base, ivideo.mmio_vbase, sisfb_mmio_size / 1024);
+	if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
 
-	#ifdef CONFIG_FB_SIS_300
-	if (sisvga_engine == SIS_300_VGA) {
-		sisfb_get_VB_type_300 ();
-		if (ivideo.hasVB != HASVB_NONE) {
-			sisfb_detect_VB_connect_300 ();
+#ifdef CONFIG_FB_SIS_300
+		if (sisvga_engine == SIS_300_VGA) {
+			sisfb_get_VB_type_300();
+			if (ivideo.hasVB != HASVB_NONE) {
+				sisfb_detect_VB_connect_300();
+			}
 		}
-	}
 #endif
 
 #ifdef CONFIG_FB_SIS_315
-	if (sisvga_engine == SIS_315_VGA) {
-		sisfb_get_VB_type_315 ();
-		if (ivideo.hasVB != HASVB_NONE) {
-			sisfb_detect_VB_connect_315 ();
+		if (sisvga_engine == SIS_315_VGA) {
+			sisfb_get_VB_type_315();
+			if (ivideo.hasVB != HASVB_NONE) {
+				sisfb_detect_VB_connect_315();
+			}
 		}
-	}
 #endif
 
-	// Eden Chen
-sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
-sishw_ext.usExternalChip = 0;
+		sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
+		sishw_ext.usExternalChip = 0;
 
-	switch (ivideo.hasVB) {
-	case HASVB_301:
-		/*karl */
-		vgawb (VB_PART4_ADR, 0x01);
-		reg = vgarb (VB_PART4_DATA);
-		if ((reg != 0xB1) && (reg != 0xB0))
-			sishw_ext.ujVBChipID = VB_CHIP_301;
-		else
-			sishw_ext.ujVBChipID = VB_CHIP_301B;
-		break;
-	case HASVB_302:
-		sishw_ext.ujVBChipID = VB_CHIP_302;
-		break;
-	case HASVB_303:
-		sishw_ext.ujVBChipID = VB_CHIP_303;
-		break;
-	case HASVB_LVDS:
-		sishw_ext.usExternalChip = 0x1;
-		break;
-	case HASVB_TRUMPION:
-		sishw_ext.usExternalChip = 0x2;
-		break;
-	case HASVB_CHRONTEL:
-		sishw_ext.usExternalChip = 0x4;
-		break;
-	case HASVB_LVDS_CHRONTEL:
-		sishw_ext.usExternalChip = 0x5;
-		break;
-	default:
-		break;
-	}
-
-	// ~Eden Chen
+		switch (ivideo.hasVB) {
 
-	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.disp_state & DISPTYPE_LCD) {
-		vgawb (CRTC_ADR, IND_SIS_LCD_PANEL);
-		reg = vgarb (CRTC_DATA);
-		// Eden Chen
-		switch (reg) {
-		case SIS_LCD_PANEL_800X600:
-			sishw_ext.ulCRT2LCDType = LCD_800x600;
-			break;
-		case SIS_LCD_PANEL_1024X768:
-			sishw_ext.ulCRT2LCDType = LCD_1024x768;
-			break;
-		case SIS_LCD_PANEL_1280X1024:
-			sishw_ext.ulCRT2LCDType = LCD_1280x1024;
+		case HASVB_301:
+			vgawb(VB_PART4_ADR,0x01);
+			reg = vgarb(VB_PART4_DATA);
+			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;
+				printk(KERN_INFO "sisfb: SiS301B bridge detected (revision 0x%02x\n",reg);
+			} else {
+				sishw_ext.ujVBChipID = VB_CHIP_301;
+				printk(KERN_INFO "sisfb: SiS301 bridge detected\n");
+			}
 			break;
-		case SIS_LCD_PANEL_640X480:
-			sishw_ext.ulCRT2LCDType = LCD_640x480;
+		case HASVB_302:
+			vgawb(VB_PART4_ADR,0x01);
+			reg = vgarb(VB_PART4_DATA);
+			if (reg >= 0xD0) {
+				sishw_ext.ujVBChipID = VB_CHIP_302LV;
+				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
+	  		} else if (reg >= 0xB0) {
+			        sishw_ext.ujVBChipID = VB_CHIP_302B;
+				printk(KERN_INFO "sisfb: SiS302B bridge detected (revision 0x%02x)\n",reg);
+			} else {
+			        sishw_ext.ujVBChipID = VB_CHIP_302;
+				printk(KERN_INFO "sisfb: SiS302 bridge detected\n");
+			}
 			break;
-		case SIS_LCD_PANEL_1280X960:
-			sishw_ext.ulCRT2LCDType = LCD_1280x960;
+		case HASVB_303:
+			sishw_ext.ujVBChipID = VB_CHIP_303;
+			printk(KERN_INFO "sisfb: SiS303 bridge detected (not supported)\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:
-			sishw_ext.ulCRT2LCDType = LCD_1024x768;
+			printk(KERN_INFO "sisfb: No or unknown bridge type detected\n");
 			break;
 		}
-	// ~Eden Chen
-	}
 
-	if (sisfb_mode_idx >= 0)
-		sisfb_validate_mode ();
-	
-	if (sisfb_mode_idx < 0) {
-		switch (ivideo.disp_state & DISPTYPE_DISP2) {
-		case DISPTYPE_LCD:
-			sisfb_mode_idx = DEFAULT_LCDMODE;
-			break;
-		case DISPTYPE_TV:
-			sisfb_mode_idx = DEFAULT_TVMODE;
-			break;
-		default:
-			sisfb_mode_idx = DEFAULT_MODE;
-			break;
+		/* TW: Determine and detect attached TV's on Chrontel */
+		if (sishw_ext.usExternalChip == 0x04 || sishw_ext.usExternalChip == 0x05) {
+		    SiSRegInit(sishw_ext.ulIOAddress);
+		    if(ivideo.chip < SIS_315H) {    /* TW: Chrontel 7005 */
+#ifdef CONFIG_FB_SIS_300
+                       SiS_IF_DEF_CH70xx = 1;
+		       temp1=SiS_GetCH700x(0x25);
+		       if ((temp1 >= 50) && (temp1 <= 100)) {
+	    		   /* TW: Read power status */
+	    		   temp1 = SiS_GetCH700x(0x0e);
+	    		   if ((temp1&0x03)!=0x03) {
+		        	/* TW: Power all outputs */
+	        		SiS_SetCH70xxANDOR(0x030E,0xF8);
+	    		   }
+			   /* TW: Sense connected TV devices */
+	    		   SiS_SetCH700x(0x0110);
+	    		   SiS_SetCH700x(0x0010);
+	    		   temp1 = SiS_GetCH700x(0x10);
+	    		   if (!(temp1 & 0x08)) {
+				/* TW: So we can be sure that there IS a SVHS output */
+				printk(KERN_INFO
+				   "sisfb: Chrontel: Detected TV connected to SVHS output\n");
+				ivideo.TV_plug = TVPLUG_SVIDEO;
+				vgawb(CRTC_ADR, 0x32);
+				temp2 = vgarb(CRTC_DATA) | 0x02;
+				vgawb(CRTC_DATA, temp2);
+			   } else if (!(temp1 & 0x02)) {
+				/* TW: So we can be sure that there IS a CVBS output */
+				printk(KERN_INFO
+				   "sisfb: Chrontel: Detected TV connected to CVBS output\n");
+				ivideo.TV_plug = TVPLUG_COMPOSITE;
+				vgawb(CRTC_ADR, 0x32);
+				temp2 = vgarb(CRTC_DATA) | 0x01;
+				vgawb(CRTC_DATA, temp2);
+	    		   } else {
+		    		SiS_SetCH70xxANDOR(0x010E,0xF8);
+	    		   }
+		       } else if (temp1==0) {
+	    		        SiS_SetCH70xxANDOR(0x010E,0xF8);
+	    	       }
+#endif
+		   } else {  /* TW: Chrontel 7019 */
+#ifdef CONFIG_FB_SIS_315
+			SiS_IF_DEF_CH70xx = 2;
+                        temp1 = SiS_GetCH701x(0x49);
+			SiS_SetCH701x(0x2049);
+			SiS_DDC2Delay(0x96);
+			temp2 = SiS_GetCH701x(0x20);
+			temp2 |= 0x01;
+			SiS_SetCH701x((temp2 << 8) | 0x20);
+			SiS_DDC2Delay(0x96);
+			temp2 ^= 0x01;
+			SiS_SetCH701x((temp2 << 8) | 0x20);
+			SiS_DDC2Delay(0x96);
+			temp2 = SiS_GetCH701x(0x20);
+			SiS_SetCH701x((temp1 << 8) | 0x49);
+                        temp1 = 0;
+			if(temp2 & 0x02) temp1 |= 0x01;
+			if(temp2 & 0x10) temp1 |= 0x01;
+			if(temp2 & 0x04) temp1 |= 0x02;
+			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;
+			     vgawb(CRTC_ADR, 0x32);
+                             temp2 = vgarb(CRTC_DATA) | 0x01;
+			     vgawb(CRTC_DATA, temp2);
+                             break;
+			case 0x02:
+			     printk(KERN_INFO
+				"sisfb: Chrontel: Detected TV connected to SVHS output\n");
+			     ivideo.TV_plug = TVPLUG_SVIDEO;
+			     vgawb(CRTC_ADR, 0x32);
+			     temp2 = vgarb(CRTC_DATA) | 0x02;
+			     vgawb(CRTC_DATA, temp2);
+                             break;
+			case 0x04:
+			     /* TW: This should not happen */
+			     printk(KERN_INFO
+				"sisfb: Chrontel: Detected TV connected to SCART output!?\n");
+                             break;
+			}
+#endif
+		   }
+	    	}
+
+		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;
 		}
-	}
-	
-	sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
-	
-	if (ivideo.refresh_rate != 0)
-		sisfb_search_refresh_rate (ivideo.refresh_rate);
 
-	if (sisfb_rate_idx == 0) {
-		sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
-		ivideo.refresh_rate = 60;
-	}
+		if (ivideo.disp_state & DISPTYPE_LCD) {
+		    if (!enable_dstn) {
+			vgawb(CRTC_ADR, IND_SIS_LCD_PANEL);
+			reg = vgarb(CRTC_DATA) & 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;
+		    }
+		}
 
-	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;
-	video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
-
-	printk (KERN_INFO "sisfb: mode is %dx%dx%d, linelength=%d\n",
-		ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
-		video_linelength);
+		if (sisfb_mode_idx >= 0)
+			sisfb_validate_mode();
+
+		if (sisfb_mode_idx < 0) {
+			switch (ivideo.disp_state & DISPTYPE_DISP2) {
+			   case DISPTYPE_LCD:
+				sisfb_mode_idx = DEFAULT_LCDMODE;
+				break;
+			   case DISPTYPE_TV:
+				sisfb_mode_idx = DEFAULT_TVMODE;
+				break;
+			   default:
+				sisfb_mode_idx = DEFAULT_MODE;
+				break;
+			}
+		}
 
-	// Eden Chen
-	// Check interface correction  For Debug
-	DPRINTK ("VM Adr=0x%p\n", sishw_ext.pjVideoMemoryAddress);
-	DPRINTK ("VM Size=%ldK\n", sishw_ext.ulVideoMemorySize / 1024);
-	DPRINTK ("IO Adr=0x%lx\n", sishw_ext.ulIOAddress);
-	DPRINTK ("Chip=%d\n", sishw_ext.jChipType);
-	DPRINTK ("ChipRevision=%d\n", sishw_ext.jChipRevision);
-	DPRINTK ("VBChip=%d\n", sishw_ext.ujVBChipID);
-	DPRINTK ("ExtVB=%d\n", sishw_ext.usExternalChip);
-	DPRINTK ("LCD=%ld\n", sishw_ext.ulCRT2LCDType);
-	DPRINTK ("bIntegratedMMEnabled=%d\n", sishw_ext.bIntegratedMMEnabled);
-	// ~Eden Chen
+		sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
 
-	sisfb_pre_setmode ();
+		if (ivideo.refresh_rate != 0)
+			sisfb_search_refresh_rate(ivideo.refresh_rate);
 
-	if (SiSSetMode (&sishw_ext, sisfb_mode_no) == 0) {
-		DPRINTK ("set mode[0x%x]: failed\n", sisfb_mode_no);
-		return -1;
-	}
-	vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-	vgawb (SEQ_DATA, SIS_PASSWORD);
-	// Eden Chen
+		if (sisfb_rate_idx == 0) {
+			sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
+			ivideo.refresh_rate = 60;
+		}
 
-	sisfb_post_setmode ();
+		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;
+		video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
 
-	sisfb_crtc_to_var (&default_var);
+		printk(KERN_INFO "sisfb: Mode is %dx%dx%d (%dHz), linelength=%d\n",
+	       		ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
+			ivideo.refresh_rate, video_linelength);
 
-	fb_info.changevar = NULL;
-	fb_info.node = NODEV;
-	fb_info.fbops = &sisfb_ops;
-	fb_info.screen_base = ivideo.video_vbase;
-	fb_info.disp = &disp;
-	fb_info.currcon = -1;
-	fb_info.switch_con = &sisfb_switch;
-	fb_info.updatevar = &sisfb_update_var;
-	fb_info.flags = FBINFO_FLAG_DEFAULT;
+		// Eden Chen
+		// Check interface correction  For Debug
+		DPRINTK("VM Adr=0x%p\n", sishw_ext.pjVideoMemoryAddress);
+		DPRINTK("VM Size=%ldK\n", sishw_ext.ulVideoMemorySize/1024);
+		DPRINTK("IO Adr=0x%lx\n", sishw_ext.ulIOAddress);
+		DPRINTK("Chip=%d\n", sishw_ext.jChipType);
+		DPRINTK("ChipRevision=%d\n", sishw_ext.jChipRevision);
+		DPRINTK("VBChip=%d\n", sishw_ext.ujVBChipID);
+		DPRINTK("ExtVB=%d\n", sishw_ext.usExternalChip);
+		DPRINTK("LCD=%ld\n", sishw_ext.ulCRT2LCDType);
+		DPRINTK("bIntegratedMMEnabled=%d\n", sishw_ext.bIntegratedMMEnabled);
+		// ~Eden Chen
 
-	sisfb_set_disp (-1, &default_var);
+		sisfb_pre_setmode();
 
-	if (sisfb_heap_init ()) {
-		DPRINTK ("sisfb: Failed to enable offscreen heap\n");
-	}
-	
-	/*H.C. */
-	nRes = 	mtrr_add ((unsigned int) ivideo.video_base, (unsigned int) ivideo.video_size,  MTRR_TYPE_WRCOMB, 1);
-	vc_resize_con (1, 1, 0);
+		if (SiSSetMode(&sishw_ext, sisfb_mode_no) == 0) {
+			printk("sisfb: Setting mode[0x%x] failed, using default mode\n", sisfb_mode_no);
+			return -1;
+		}
 
-	if (register_framebuffer (&fb_info) < 0)
-		return -EINVAL;
+		vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+		vgawb(SEQ_DATA, SIS_PASSWORD);
 
-	printk (KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
-		GET_FB_IDX (fb_info.node), fb_info.modename, VER_MAJOR, VER_MINOR,
-		VER_LEVEL);
+		sisfb_post_setmode();
 
+		sisfb_crtc_to_var(&default_var);
+
+		fb_info.changevar = NULL;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+		fb_info.node = -1;
+#else
+		fb_info.node = NODEV;
+#endif
+		fb_info.fbops = &sisfb_ops;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
+		fb_info.screen_base = ivideo.video_vbase;
+		fb_info.currcon = -1;
+#endif
+		fb_info.disp = &disp;
+		fb_info.switch_con = &sisfb_switch;
+		fb_info.updatevar = &sisfb_update_var;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
+		fb_info.blank = &sisfb_blank;
+#endif
+		fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+		sisfb_set_disp(-1, &default_var);
+
+	} /* TW: if mode = "none" */
+
+	if (sisfb_heap_init()) {
+		printk("sisfb: Failed to initialize offscreen memory heap\n");
+	}
+
+        ivideo.mtrr = (unsigned int) 0;
+	if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+         	/*H.C.*/
+		ivideo.mtrr = mtrr_add((unsigned int) ivideo.video_base,
+				(unsigned int) ivideo.video_size,
+				MTRR_TYPE_WRCOMB, 1);
+		/*
+		if (ivideo.mtrr >= 0) {
+           	    printk(KERN_INFO "Succeed to turn on Write-Combining on VideoMemory %08XH, Size: %08XH\n",
+					ivideo.video_base, ivideo.video_size);
+      		} else	{
+           	    printk(KERN_INFO "Fail to turn on Write-Combining on Video Memory 0x%08X, Size: 0x%08X\n",
+					ivideo.video_base, ivideo.video_size);
+      		}
+		*/
+		vc_resize_con(1, 1, 0);
+
+		if (register_framebuffer(&fb_info) < 0)
+			return -EINVAL;
+
+		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
+	       		GET_FB_IDX(fb_info.node), fb_info.modename, VER_MAJOR, VER_MINOR,
+	       		VER_LEVEL);
+
+		printk(KERN_INFO "sisfb: Added SISFB_GET_INFO ioctl = %x\n", SISFB_GET_INFO);
+
+	}	/* TW: if mode = "none" */
 	return 0;
 }
 
@@ -2799,38 +3404,151 @@
 
 static char *mode = NULL;
 static unsigned int rate = 0;
-static unsigned int crt1 = 1;
+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;
+static int pdc = 0;
+
+MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740 framebuffer driver");
+MODULE_LICENSE("GPL");    /* TW (Code is officially open says SiS) */
+MODULE_AUTHOR("Various; SiS; Thomas Winischhofer <thomas@winischhofer.net>");
+
+MODULE_PARM(mode, "s");
+MODULE_PARM_DESC(mode,
+       "Selects the desired display mode in the format [X]x[Y]x[Depth], eg. 800x600x16 "
+       "(default: none; this leaves the console untouched and the driver will only do "
+       "the video memory management for eg. DRM/DRI)");
+
+MODULE_PARM(rate, "i");
+MODULE_PARM_DESC(rate,
+	"Selects the desired vertical refresh rate for CRT1 (external VGA) in Hz. "
+	"(default: 60)");
+
+MODULE_PARM(crt1off,   "i");
+MODULE_PARM_DESC(crt1off,
+	"If this option is set, the driver will switch off CRT1 (external VGA). "
+	"(Deprecated, please use forcecrt1)");
+
+MODULE_PARM(filter, "i");
+MODULE_PARM_DESC(filter,
+	"Selects TV flicker filter type (only for SiS30x video bridges). "
+	"(Possible values 0-7, default: [no filter])");
+
+MODULE_PARM(dstn,   "i"); /* JennyLee 20011211 */
+MODULE_PARM_DESC(dstn,
+	"Selects DSTN/FSTN display mode for SiS550. This sets CRT2 type to LCD and "
+	"overrides forcecrt2type setting. (1=ON, 0=OFF) (default: 0)");
+
+MODULE_PARM(queuemode,   "s");
+MODULE_PARM_DESC(queuemode,
+	"Selects the queue mode on 315/550/650/740. Possible choices are AGP, VRAM "
+	"or MMIO. AGP is only available if the kernel has AGP support. "
+	"The queue mode is important to programs using the 2D/3D accelerator of "
+	"the SiS chip. The modes require a totally different way of programming "
+	"the engines. On 300/540/630/730, this option is ignored. (default: MMIO)");
+
+/* TW: "Import" the options from the X driver */
+MODULE_PARM(mem,    "i");
+MODULE_PARM_DESC(mem,
+	"Determines the beginning of the video memory heap in KB. This heap is used for "
+	"video RAM management for eg. DRM/DRI. The default depends on the amount of video "
+	"memory available. If 8MB of video RAM or less is available, "
+	"the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB, otherwise at 12288MB."
+	"The value is to be specified without 'KB' and should match MaxXFBMem setting for "
+	"XFree 4.x (x>=2). See http://www.winischhofer.net/linuxsis630.shtml for a closer description.");
+
+MODULE_PARM(forcecrt2type, "s");
+MODULE_PARM_DESC(forcecrt2type,
+	"If this option is omitted, the driver autodetects CRT2 output devices, such as LCD, "
+	"TV or secondary VGA (in this order; so if eg. an LCD is there, it will be used regardless "
+	"of a connected TV set). With this option, this autodetection can be overridden. "
+	"Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2 and makes it "
+	"possible to use higher resolutions on CRT1 than eg. your LCD panel supports. TV "
+	"selects TV output (only resolutions 640x480 and 800x600 are supported for TV!). "
+	"VGA refers to _secondary_ VGA which is unlikely to be available; the VGA plug found "
+	"on most machines is CRT1. (default: [autodetected])");
+
+MODULE_PARM(forcecrt1, "i");
+MODULE_PARM_DESC(forcecrt1,
+	"Normally, the driver autodetects whether or not CRT1 (external VGA) is connected. "
+	"With this option, the detection can be overridden (1=CRT1 ON, 0=CRT1 off) "
+	"(default: [autodetected])");
+
+MODULE_PARM(pdc, "i");
+MODULE_PARM_DESC(pdc,
+        "(300 series only) This is for manually selecting the LCD panel delay compensation. The "
+	"driver should detect this correctly in most cases; however, sometimes this is not possible. If "
+	"you see 'small waves' on the LCD, try setting this to 4, 32 or 24. If the problem persists, "
+	"try other values between 4 and 60 in steps of 4. "
+	"(default: [autodetected])");
 
-MODULE_PARM (mode, "s");
-MODULE_PARM (rate, "i");
-MODULE_PARM (crt1, "i");
-MODULE_PARM (filter, "i");
 
-int init_module (void)
+int init_module(void)
 {
 	if (mode)
-		sisfb_search_mode (mode);
+		sisfb_search_mode(mode);
+	else  /* TW: set mode=none if no mode parameter is given */
+		sisfb_mode_idx = MODE_INDEX_NONE;
 
 	ivideo.refresh_rate = rate;
 
-	if (crt1 == 0)
+	if (forcecrt2type)
+		sisfb_search_crt2type(forcecrt2type);
+
+	if (crt1off == 0)
 		sisfb_crt1off = 1;
 	else
 		sisfb_crt1off = 0;
 
-	sisfb_init ();
+	sisfb_forcecrt1 = forcecrt1;
+	if (forcecrt1 == 1)
+		sisfb_crt1off = 0;
+	else if (forcecrt1 == 0)
+		sisfb_crt1off = 1;
+
+	if (mem)
+		sisfb_mem = mem;
+
+	enable_dstn = dstn; /* JennyLee 20011211 */
+	/* TW: DSTN overrules forcecrt2type */
+	if (enable_dstn) sisfb_crt2type = DISPTYPE_LCD;
+
+	if (queuemode)
+		sisfb_search_queuemode(queuemode);
+
+        if(pdc) {
+	   if(!(pdc & ~0x3c)) {
+	        sisfb_pdc = pdc & 0x3c;
+	   }
+	}
+
+	sisfb_init();
 
 	return 0;
 }
 
-void cleanup_module (void)
+void cleanup_module(void)
 {
-	unregister_framebuffer (&fb_info);
+	/* TW: Release mem regions */
+	release_mem_region(ivideo.video_base, ivideo.video_size);
+	release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
+	/* TW: Release MTRR region */
+	if (ivideo.mtrr) mtrr_del(ivideo.mtrr, 
+			      (unsigned int)ivideo.video_base,
+	                      (unsigned int)ivideo.video_size);
+	/* Unregister the framebuffer */
+	unregister_framebuffer(&fb_info);
+	printk(KERN_INFO "sisfb: Module unloaded\n");
 }
+
 #endif
 
-EXPORT_SYMBOL (sis_malloc);
-EXPORT_SYMBOL (sis_free);
-EXPORT_SYMBOL (sis_dispinfo);
+EXPORT_SYMBOL(sis_malloc);
+EXPORT_SYMBOL(sis_free);
+EXPORT_SYMBOL(sis_dispinfo);
 
-EXPORT_SYMBOL (ivideo);
+EXPORT_SYMBOL(ivideo);
+                                                                                           
diff -Nru a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
--- a/drivers/video/sis/sis_main.h	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/sis/sis_main.h	Wed Jul 24 14:03:37 2002
@@ -1,18 +1,25 @@
 #ifndef _SISFB_MAIN
 #define _SISFB_MAIN
 
+/* Comments and changes marked with "TW" by Thomas Winischhofer <tw@webit.com> */
+
 /* ------------------- Constant Definitions ------------------------- */
 
-#undef LINUXBIOS		/* turn on when use LINUXBIOS */
-#define AGPOFF			/* default is turn off AGP */
+#undef LINUXBIOS   /* turn on when use LINUXBIOS */
+#define AGPOFF     /* default is turn off AGP */
 
 #define VER_MAJOR                 1
-#define VER_MINOR                 3
-#define VER_LEVEL                 9
+#define VER_MINOR                 4
+#define VER_LEVEL                 1
 
-#define DEFAULT_MODE              0
-#define DEFAULT_LCDMODE           9
-#define DEFAULT_TVMODE            9
+/* TW: To be included in pci_ids.h */
+#ifndef PCI_DEVICE_ID_SI_650_VGA
+#define PCI_DEVICE_ID_SI_650_VGA  0x6325
+#endif
+#ifndef PCI_DEVICE_ID_SI_650
+#define PCI_DEVICE_ID_SI_650      0x0650
+#endif
+/* TW end */
 
 #define MAX_ROM_SCAN              0x10000
 
@@ -23,17 +30,19 @@
 
 /* For 300 series */
 #ifdef CONFIG_FB_SIS_300
-#define TURBO_QUEUE_AREA_SIZE     0x80000	/* 512K */
-#define HW_CURSOR_AREA_SIZE       0x1000	/* 4K */
+#define TURBO_QUEUE_AREA_SIZE     0x80000 /* 512K */
 #endif
 
 /* For 315 series */
 #ifdef CONFIG_FB_SIS_315
-#define COMMAND_QUEUE_AREA_SIZE   0x80000	/* 512K */
-#define HW_CURSOR_AREA_SIZE       0x4000	/* 16K */
+#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 */
+
 #define OH_ALLOC_SIZE             4000
 #define SENTINEL                  0x7fffffff
 
@@ -54,7 +63,7 @@
 #define VB_PART4_ADR              (0x14-0x30)
 #define VB_PART4_DATA             (0x15-0x30)
 
-#define IND_SIS_PASSWORD          0x05	/* SRs */
+#define IND_SIS_PASSWORD          0x05  /* SRs */
 #define IND_SIS_COLOR_MODE        0x06
 #define IND_SIS_RAMDAC_CONTROL    0x07
 #define IND_SIS_DRAM_SIZE         0x14
@@ -70,7 +79,7 @@
 #define IND_SIS_CMDQUEUE_SET      0x26
 #define IND_SIS_CMDQUEUE_THRESHOLD  0x27
 
-#define IND_SIS_SCRATCH_REG_CR30  0x30	/* CRs */
+#define IND_SIS_SCRATCH_REG_CR30  0x30  /* CRs */
 #define IND_SIS_SCRATCH_REG_CR31  0x31
 #define IND_SIS_SCRATCH_REG_CR32  0x32
 #define IND_SIS_SCRATCH_REG_CR33  0x33
@@ -78,28 +87,24 @@
 #define IND_SIS_SCRATCH_REG_CR37  0x37
 #define IND_SIS_AGP_IO_PAD        0x48
 
-#define IND_BRI_DRAM_STATUS       0x63
+#define IND_BRI_DRAM_STATUS       0x63 /* PCI config memory size offset */
 
 #define MMIO_QUEUE_PHYBASE        0x85C0
 #define MMIO_QUEUE_WRITEPORT      0x85C4
 #define MMIO_QUEUE_READPORT       0x85C8
 
-// Eden Chen
-#ifdef CONFIG_FB_SIS_300
-#define IND_SIS_CRT2_WRITE_ENABLE 0x24
-#endif
-#ifdef CONFIG_FB_SIS_315
-#define IND_SIS_CRT2_WRITE_ENABLE 0x2F
-#endif
-// ~Eden Chen
-
-#define SIS_PASSWORD              0x86	/* SR05 */
-#define SIS_INTERLACED_MODE       0x20	/* SR06 */
-#define SIS_8BPP_COLOR_MODE       0x0
-#define SIS_15BPP_COLOR_MODE      0x1
-#define SIS_16BPP_COLOR_MODE      0x2
-#define SIS_32BPP_COLOR_MODE      0x4
-#define SIS_DRAM_SIZE_MASK        0x3F	/* SR14 */
+/* Eden Chen; TW */
+#define IND_SIS_CRT2_WRITE_ENABLE_300 0x24
+#define IND_SIS_CRT2_WRITE_ENABLE_315 0x2F
+/* ~Eden Chen; TW */
+
+#define SIS_PASSWORD              0x86  /* SR05 */
+#define SIS_INTERLACED_MODE       0x20  /* SR06 */
+#define SIS_8BPP_COLOR_MODE       0x0 
+#define SIS_15BPP_COLOR_MODE      0x1 
+#define SIS_16BPP_COLOR_MODE      0x2 
+#define SIS_32BPP_COLOR_MODE      0x4 
+#define SIS_DRAM_SIZE_MASK        0x3F  /* SR14 */
 #define SIS_DRAM_SIZE_1MB         0x00
 #define SIS_DRAM_SIZE_2MB         0x01
 #define SIS_DRAM_SIZE_4MB         0x03
@@ -111,7 +116,8 @@
 #define SIS_DATA_BUS_32           0x00
 #define SIS_DATA_BUS_64           0x01
 #define SIS_DATA_BUS_128          0x02
-#define SIS315_DRAM_SIZE_MASK     0xF0	/* 315 SR14 */
+
+#define SIS315_DRAM_SIZE_MASK     0xF0  /* 315 SR14 */
 #define SIS315_DRAM_SIZE_2MB      0x01
 #define SIS315_DRAM_SIZE_4MB      0x02
 #define SIS315_DRAM_SIZE_8MB      0x03
@@ -123,10 +129,12 @@
 #define SIS315_DATA_BUS_64        0x00
 #define SIS315_DATA_BUS_128       0x01
 #define SIS315_DUAL_CHANNEL_MASK  0x0C
-#define SIS315_SINGLE_CHANNEL_1_RANK  0x0
-#define SIS315_SINGLE_CHANNEL_2_RANK  0x1
-#define SIS315_DUAL_CHANNEL_1_RANK    0x3
-#define SIS550_DRAM_SIZE_MASK     0x3F	/* 550 SR14 */
+#define SIS315_SINGLE_CHANNEL_1_RANK  	0x0
+#define SIS315_SINGLE_CHANNEL_2_RANK  	0x1
+#define SIS315_ASYM_DDR		  	0x02
+#define SIS315_DUAL_CHANNEL_1_RANK    	0x3
+
+#define SIS550_DRAM_SIZE_MASK     0x3F  /* 550/650/740 SR14 */
 #define SIS550_DRAM_SIZE_4MB      0x00
 #define SIS550_DRAM_SIZE_8MB      0x01
 #define SIS550_DRAM_SIZE_16MB     0x03
@@ -138,10 +146,13 @@
 #define SIS550_DRAM_SIZE_256MB    0x3F
 
 #define SIS_SCRATCH_REG_1A_MASK   0x10
-#define SIS_ENABLE_2D             0x40	/* SR1E */
-#define SIS_MEM_MAP_IO_ENABLE     0x01	/* SR20 */
+
+#define SIS_ENABLE_2D             0x40  /* SR1E */
+
+#define SIS_MEM_MAP_IO_ENABLE     0x01  /* SR20 */
 #define SIS_PCI_ADDR_ENABLE       0x80
-#define SIS_AGP_CMDQUEUE_ENABLE   0x80	/* 315 SR26 */
+
+#define SIS_AGP_CMDQUEUE_ENABLE   0x80  /* 315/650/740 SR26 */
 #define SIS_VRAM_CMDQUEUE_ENABLE  0x40
 #define SIS_MMIO_CMD_ENABLE       0x20
 #define SIS_CMD_QUEUE_SIZE_512k   0x00
@@ -149,7 +160,9 @@
 #define SIS_CMD_QUEUE_SIZE_2M     0x08
 #define SIS_CMD_QUEUE_SIZE_4M     0x0C
 #define SIS_CMD_QUEUE_RESET       0x01
-#define SIS_SIMULTANEOUS_VIEW_ENABLE  0x01	/* CR30 */
+#define SIS_CMD_AUTO_CORR	  0x02
+
+#define SIS_SIMULTANEOUS_VIEW_ENABLE  0x01  /* CR30 */
 #define SIS_MODE_SELECT_CRT2      0x02
 #define SIS_VB_OUTPUT_COMPOSITE   0x04
 #define SIS_VB_OUTPUT_SVIDEO      0x08
@@ -157,9 +170,11 @@
 #define SIS_VB_OUTPUT_LCD         0x20
 #define SIS_VB_OUTPUT_CRT2        0x40
 #define SIS_VB_OUTPUT_HIVISION    0x80
-#define SIS_VB_OUTPUT_DISABLE     0x20	/* CR31 */
+
+#define SIS_VB_OUTPUT_DISABLE     0x20  /* CR31 */
 #define SIS_DRIVER_MODE           0x40
-#define SIS_VB_COMPOSITE          0x01	/* CR32 */
+
+#define SIS_VB_COMPOSITE          0x01  /* CR32 */
 #define SIS_VB_SVIDEO             0x02
 #define SIS_VB_SCART              0x04
 #define SIS_VB_LCD                0x08
@@ -167,21 +182,21 @@
 #define SIS_CRT1                  0x20
 #define SIS_VB_HIVISION           0x40
 #define SIS_VB_DVI                0x80
-#define SIS_VB_TV                 (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | SIS_VB_SCART | SIS_VB_HIVISION)
-#define SIS_LCD_PANEL_800X600     0x1	/* CR36 */
-#define SIS_LCD_PANEL_1024X768    0x2
-#define SIS_LCD_PANEL_1280X1024   0x3
-#define SIS_LCD_PANEL_1280X960    0x4
-#define SIS_LCD_PANEL_640X480     0x5
-#define SIS_EXTERNAL_CHIP_MASK    0x0E	/* CR37 */
-#define SIS_EXTERNAL_CHIP_SIS301        0x01
-#define SIS_EXTERNAL_CHIP_LVDS          0x02
-#define SIS_EXTERNAL_CHIP_TRUMPION      0x03
-#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04
-#define SIS_EXTERNAL_CHIP_CHRONTEL      0x05
-#define SIS_AGP_2X                0x20	/* CR48 */
+#define SIS_VB_TV                 (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
+                                   SIS_VB_SCART | SIS_VB_HIVISION)
+
+#define SIS_EXTERNAL_CHIP_MASK    	   0x0E  /* CR37 */
+#define SIS_EXTERNAL_CHIP_SIS301           0x01  /* in CR37 << 1 ! */
+#define SIS_EXTERNAL_CHIP_LVDS             0x02  /* in CR37 << 1 ! */
+#define SIS_EXTERNAL_CHIP_TRUMPION         0x03  /* in CR37 << 1 ! */
+#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL    0x04  /* in CR37 << 1 ! */
+#define SIS_EXTERNAL_CHIP_CHRONTEL         0x05  /* in CR37 << 1 ! */
+#define SIS310_EXTERNAL_CHIP_LVDS          0x02  /* in CR37 << 1 ! */
+#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03  /* in CR37 << 1 ! */
+
+#define SIS_AGP_2X                0x20  /* CR48 */
 
-#define BRI_DRAM_SIZE_MASK        0x70	/* PCI bridge */
+#define BRI_DRAM_SIZE_MASK        0x70  /* PCI bridge config data */
 #define BRI_DRAM_SIZE_2MB         0x00
 #define BRI_DRAM_SIZE_4MB         0x01
 #define BRI_DRAM_SIZE_8MB         0x02
@@ -190,7 +205,7 @@
 #define BRI_DRAM_SIZE_64MB        0x05
 
 // Eden Chen
-#define HW_DEVICE_EXTENSION	    SIS_HW_DEVICE_INFO
+#define HW_DEVICE_EXTENSION	  SIS_HW_DEVICE_INFO
 #define PHW_DEVICE_EXTENSION      PSIS_HW_DEVICE_INFO
 
 #define SR_BUFFER_SIZE            5
@@ -207,19 +222,33 @@
 static int video_cmap_len;
 static struct display_switch sisfb_sw;
 static struct fb_var_screeninfo default_var = {
-	0, 0, 0, 0,
-	0, 0,
-	0,
-	0,
-	{0, 8, 0},
-	{0, 8, 0},
-	{0, 8, 0},
-	{0, 0, 0},
-	0,
-	FB_ACTIVATE_NOW, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0,
-	0,
-	FB_VMODE_NONINTERLACED,
-	{0, 0, 0, 0, 0, 0}
+	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,
+	reserved:       {0, 0, 0, 0, 0, 0}
 };
 
 static struct {
@@ -240,11 +269,14 @@
 /* display status */
 static int sisfb_off = 0;
 static int sisfb_crt1off = 0;
+static int sisfb_forcecrt1 = -1;
 static int sisfb_inverse = 0;
 static int sisvga_enabled = 0;
-/*karl*/
+static int currcon = 0;
 static int sisfb_tvmode = 0;
 static int sisfb_mem = 0;
+static int sisfb_pdc = 0;
+static int enable_dstn = 0;
 
 static enum _VGA_ENGINE {
 	UNKNOWN_VGA = 0,
@@ -252,22 +284,28 @@
 	SIS_315_VGA,
 } sisvga_engine = UNKNOWN_VGA;
 
-/* mode-related variables */
-int sisfb_mode_idx = -1;
-u8 sisfb_mode_no = 0;
-u8 sisfb_rate_idx = 0;
+/* TW: These are to adapted according to VGA_ENGINE type */
+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_queuemode = -1; 	/* TW: Use MMIO queue mode by default (310 series only) */
 
 /* data for sis components*/
 struct video_info ivideo;
 
-// Eden Chen
+/* TW: For ioctl SISFB_GET_INFO */
+sisfb_info sisfbinfo;
+
+/* TW: Hardware extension; contains data on hardware */
 HW_DEVICE_EXTENSION sishw_ext = {
 	NULL, NULL, NULL, NULL,
 	0, 0, 0, 0, 0, 0, 0, 0, 0,
 	NULL, NULL, NULL, NULL,
-	{0, 0, 0, 0}
+	{0, 0, 0, 0},
+	0
 };
-// ~Eden Chen
 
 /* card parameters */
 static unsigned long sisfb_mmio_size = 0;
@@ -284,19 +322,19 @@
 	u16 vendor, device;
 	const char *name;
 } sisdev_list[] = {
-	{
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300, "SIS 300"}, {
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, "SIS 540"}, {
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, "SIS 630"}, {
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H, "SIS 315H"}, {
-	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"}, {
-	0, 0, NULL}
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300,     "SIS 300"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, "SIS 540"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, "SIS 630/730"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H,    "SIS 315H"},
+	{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"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650/M650/740 VGA"},
+	{0, 0, NULL}
 };
 
 /* mode table */
-static const struct _sisbios_mode {
+struct _sisbios_mode {
 	char name[15];
 	u8 mode_no;
 	u16 xres;
@@ -306,32 +344,131 @@
 	u16 cols;
 	u16 rows;
 } sisbios_mode[] = {
-	{
-	"640x480x8", 0x2E, 640, 480, 8, 1, 80, 30}, {
-	"640x480x16", 0x44, 640, 480, 16, 1, 80, 30}, {
-	"640x480x32", 0x62, 640, 480, 32, 1, 80, 30}, {
-	"720x480x8", 0x31, 720, 480, 8, 1, 90, 30}, {
-	"720x480x16", 0x33, 720, 480, 16, 1, 90, 30}, {
-	"720x480x32", 0x35, 720, 480, 32, 1, 90, 30}, {
-	"720x576x8", 0x32, 720, 576, 8, 1, 90, 36}, {
-	"720x576x16", 0x34, 720, 576, 16, 1, 90, 36}, {
-	"720x576x32", 0x36, 720, 576, 32, 1, 90, 36}, {
-	"800x600x8", 0x30, 800, 600, 8, 2, 100, 37}, {
-	"800x600x16", 0x47, 800, 600, 16, 2, 100, 37}, {
-	"800x600x32", 0x63, 800, 600, 32, 2, 100, 37}, {
-	"1024x768x8", 0x38, 1024, 768, 8, 2, 128, 48}, {
-	"1024x768x16", 0x4A, 1024, 768, 16, 2, 128, 48}, {
-	"1024x768x32", 0x64, 1024, 768, 32, 2, 128, 48}, {
-	"1280x1024x8", 0x3A, 1280, 1024, 8, 2, 160, 64}, {
-	"1280x1024x16", 0x4D, 1280, 1024, 16, 2, 160, 64}, {
-	"1280x1024x32", 0x65, 1280, 1024, 32, 2, 160, 64}, {
-	"1600x1200x8", 0x3C, 1600, 1200, 8, 1, 200, 75}, {
-	"1600x1200x16", 0x3D, 1600, 1200, 16, 1, 200, 75}, {
-	"1600x1200x32", 0x66, 1600, 1200, 32, 1, 200, 75}, {
-	"1920x1440x8", 0x68, 1920, 1440, 8, 1, 240, 75}, {
-	"1920x1440x16", 0x69, 1920, 1440, 16, 1, 240, 75}, {
-	"1920x1440x32", 0x6B, 1920, 1440, 32, 1, 240, 75}, {
-	"\0", 0x00, 0, 0, 0, 0, 0, 0}
+#define MODE_INDEX_NONE           0  /* TW: index for mode=none */
+	{"none",         0xFF,    0,    0,  0, 0,   0,  0},  /* TW: for mode "none" */
+	{"320x240x16",   0x56,  320,  240, 16, 1,  40, 15},
+	{"320x480x8",    0x5A,  320,  480,  8, 1,  40, 30},  /* TW: FSTN */
+	{"320x480x16",   0x5B,  320,  480, 16, 1,  40, 30},  /* TW: FSTN */
+	{"640x480x8",    0x2E,  640,  480,  8, 1,  80, 30},
+	{"640x480x16",   0x44,  640,  480, 16, 1,  80, 30},
+	{"640x480x24",   0x62,  640,  480, 32, 1,  80, 30},  /* TW: That's for people who mix up color- and fb depth */
+	{"640x480x32",   0x62,  640,  480, 32, 1,  80, 30},
+	{"720x480x8",    0x31,  720,  480,  8, 1,  90, 30},
+	{"720x480x16",   0x33,  720,  480, 16, 1,  90, 30},
+	{"720x480x24",   0x35,  720,  480, 32, 1,  90, 30},
+	{"720x480x32",   0x35,  720,  480, 32, 1,  90, 30},
+	{"720x576x8",    0x32,  720,  576,  8, 1,  90, 36},
+	{"720x576x16",   0x34,  720,  576, 16, 1,  90, 36},
+	{"720x576x24",   0x36,  720,  576, 32, 1,  90, 36},
+	{"720x576x32",   0x36,  720,  576, 32, 1,  90, 36},
+	{"800x480x8",    0x70,  800,  480,  8, 1, 100, 30},  /* TW: 310/325 series only */
+	{"800x480x16",   0x7a,  800,  480, 16, 1, 100, 30},
+	{"800x480x24",   0x76,  800,  480, 32, 1, 100, 30},
+	{"800x480x32",   0x76,  800,  480, 32, 1, 100, 30},
+#define DEFAULT_MODE              20 /* TW: index for 800x600x8 */
+#define DEFAULT_LCDMODE           20 /* TW: index for 800x600x8 */
+#define DEFAULT_TVMODE            20 /* TW: index for 800x600x8 */
+	{"800x600x8",    0x30,  800,  600,  8, 2, 100, 37},
+	{"800x600x16",   0x47,  800,  600, 16, 2, 100, 37},
+	{"800x600x24",   0x63,  800,  600, 32, 2, 100, 37},
+	{"800x600x32",   0x63,  800,  600, 32, 2, 100, 37},
+	{"1024x576x8",   0x71, 1024,  576,  8, 1, 128, 36},  /* TW: 310/325 series only */
+	{"1024x576x16",  0x74, 1024,  576, 16, 1, 128, 36},
+	{"1024x576x24",  0x77, 1024,  576, 32, 1, 128, 36},
+	{"1024x576x32",  0x77, 1024,  576, 32, 1, 128, 36},
+	{"1024x600x8",   0x20, 1024,  600,  8, 1, 128, 37},  /* TW: 300 series only */
+	{"1024x600x16",  0x21, 1024,  600, 16, 1, 128, 37},
+	{"1024x600x24",  0x22, 1024,  600, 32, 1, 128, 37},
+	{"1024x600x32",  0x22, 1024,  600, 32, 1, 128, 37},
+	{"1024x768x8",   0x38, 1024,  768,  8, 2, 128, 48},
+	{"1024x768x16",  0x4A, 1024,  768, 16, 2, 128, 48},
+	{"1024x768x24",  0x64, 1024,  768, 32, 2, 128, 48},
+	{"1024x768x32",  0x64, 1024,  768, 32, 2, 128, 48},
+	{"1152x768x8",   0x23, 1152,  768,  8, 1, 144, 48},  /* TW: 300 series only */
+	{"1152x768x16",  0x24, 1152,  768, 16, 1, 144, 48},
+	{"1152x768x24",  0x25, 1152,  768, 32, 1, 144, 48},
+	{"1152x768x32",  0x25, 1152,  768, 32, 1, 144, 48},
+	{"1280x720x8",   0x79, 1280,  720,  8, 1, 160, 45},  /* TW: 310/325 series only */
+	{"1280x720x16",  0x75, 1280,  720, 16, 1, 160, 45},
+	{"1280x720x24",  0x78, 1280,  720, 32, 1, 160, 45},
+	{"1280x720x32",  0x78, 1280,  720, 32, 1, 160, 45},
+	{"1280x768x8",   0x23, 1280,  768,  8, 1, 160, 48},  /* TW: 3107325 series only */
+	{"1280x768x16",  0x24, 1280,  768, 16, 1, 160, 48},
+	{"1280x768x24",  0x25, 1280,  768, 32, 1, 160, 48},
+	{"1280x768x32",  0x25, 1280,  768, 32, 1, 160, 48},
+#define MODEINDEX_1280x960 48
+	{"1280x960x8",   0x7C, 1280,  960,  8, 1, 160, 60},  /* TW: Modenumbers being patched */
+	{"1280x960x16",  0x7D, 1280,  960, 16, 1, 160, 60},
+	{"1280x960x24",  0x7E, 1280,  960, 32, 1, 160, 60},
+	{"1280x960x32",  0x7E, 1280,  960, 32, 1, 160, 60},
+	{"1280x1024x8",  0x3A, 1280, 1024,  8, 2, 160, 64},
+	{"1280x1024x16", 0x4D, 1280, 1024, 16, 2, 160, 64},
+	{"1280x1024x24", 0x65, 1280, 1024, 32, 2, 160, 64},
+	{"1280x1024x32", 0x65, 1280, 1024, 32, 2, 160, 64},
+	{"1400x1050x8",  0x26, 1400, 1050,  8, 1, 175, 65},  /* TW: 310/325 series only */
+	{"1400x1050x16", 0x27, 1400, 1050, 16, 1, 175, 65},
+	{"1400x1050x24", 0x28, 1400, 1050, 32, 1, 175, 65},
+	{"1400x1050x32", 0x28, 1400, 1050, 32, 1, 175, 65},
+	{"1600x1200x8",  0x3C, 1600, 1200,  8, 1, 200, 75},
+	{"1600x1200x16", 0x3D, 1600, 1200, 16, 1, 200, 75},
+	{"1600x1200x24", 0x66, 1600, 1200, 32, 1, 200, 75},
+	{"1600x1200x32", 0x66, 1600, 1200, 32, 1, 200, 75},
+	{"1920x1440x8",  0x68, 1920, 1440,  8, 1, 240, 75},
+	{"1920x1440x16", 0x69, 1920, 1440, 16, 1, 240, 75},
+	{"1920x1440x24", 0x6B, 1920, 1440, 32, 1, 240, 75},
+	{"1920x1440x32", 0x6B, 1920, 1440, 32, 1, 240, 75},
+	{"2048x1536x8",  0x6c, 2048, 1536,  8, 1, 256, 96},  /* TW: 310/325 series only */
+	{"2048x1536x16", 0x6d, 2048, 1536, 16, 1, 256, 96},
+	{"2048x1536x24", 0x6e, 2048, 1536, 32, 1, 256, 96},
+	{"2048x1536x32", 0x6e, 2048, 1536, 32, 1, 256, 96},
+	{"\0", 0x00, 0, 0, 0, 0, 0, 0}
+};
+
+/* mode-related variables */
+int sisfb_mode_idx = MODE_INDEX_NONE;
+u8  sisfb_mode_no = 0;
+u8  sisfb_rate_idx = 0;
+
+/* TW: CR36 evaluation */
+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 };
+
+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 };
+
+static const struct _sis_crt2type {
+	char name[6];
+	int type_no;
+} sis_crt2type[] = {
+	{"NONE", 0},
+	{"LCD",  DISPTYPE_LCD},
+	{"TV",   DISPTYPE_TV},
+	{"VGA",  DISPTYPE_CRT2},
+	{"none", 0},	/* TW: make it fool-proof */
+	{"lcd",  DISPTYPE_LCD},
+	{"tv",   DISPTYPE_TV},
+	{"vga",  DISPTYPE_CRT2},
+	{"\0",  -1}
+};
+
+/* Queue mode selection for 310 series */
+static const struct _sis_queuemode {
+	char name[6];
+	int type_no;
+} sis_queuemode[] = {
+	{"AGP",  AGP_CMD_QUEUE},
+	{"VRAM", VM_CMD_QUEUE},
+	{"MMIO", MMIO_CMD},
+	{"agp",  AGP_CMD_QUEUE},
+	{"vram", VM_CMD_QUEUE},
+	{"mmio", MMIO_CMD},
+	{"\0",  -1}
 };
 
 static struct _sis_vrate {
@@ -340,43 +477,32 @@
 	u16 yres;
 	u16 refresh;
 } 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, 50}, {
-	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, 1280, 1024, 43}, {
-	2, 1280, 1024, 60}, {
-	3, 1280, 1024, 75}, {
-	4, 1280, 1024, 85}, {
-	1, 1600, 1200, 60}, {
-	2, 1600, 1200, 65}, {
-	3, 1600, 1200, 70}, {
-	4, 1600, 1200, 75}, {
-	5, 1600, 1200, 85}, {
-	1, 1920, 1440, 60}, {
-	0, 0, 0, 0}
+	{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,  65}, {3, 1024,  576,  75},
+	{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, 60},
+	{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},
+	/* TW: Clock values for 1920x1440 guessed (except for the first one) */
+	{1, 1920, 1440, 60}, {2, 1920, 1440,  70}, {3, 1920, 1440,  75}, {4, 1920, 1440,  85},
+	{5, 1920, 1440,100}, {6, 1920, 1440, 120},
+	/* TW: Clock values for 2048x1536 guessed */
+	{1, 2048, 1536, 60}, {2, 2048, 1536,  70}, {3, 2048, 1536,  75}, {4, 2048, 1536,  85},
+	{5, 2048, 1536,100},
+	{0, 0, 0, 0}
 };
 
 /* Offscreen layout */
@@ -419,167 +545,150 @@
 static struct _sis_TV_filter {
 	u8 filter[9][4];
 } sis_TV_filter[] = {
-	{ { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_0 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_1 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_2 */
-	{
-	0xF5, 0xEE, 0x1B, 0x44}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xEB, 0x04, 0x25, 0x18}, {
-	0xF1, 0x05, 0x1F, 0x16}, {
-	0xF6, 0x06, 0x1A, 0x14}, {
-	0xFA, 0x06, 0x16, 0x14}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_3 */
-	{
-	0xF1, 0x04, 0x1F, 0x18}, {
-	0xEE, 0x0D, 0x22, 0x06}, {
-	0xF7, 0x06, 0x19, 0x14}, {
-	0xF4, 0x0B, 0x1C, 0x0A}, {
-	0xFA, 0x07, 0x16, 0x12}, {
-	0xF9, 0x0A, 0x17, 0x0C}, {
-	0x00, 0x07, 0x10, 0x12}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_4 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_5 */
-	{
-	0xF5, 0xEE, 0x1B, 0x44}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xEB, 0x04, 0x25, 0x18}, {
-	0xF1, 0x05, 0x1F, 0x16}, {
-	0xF6, 0x06, 0x1A, 0x14}, {
-	0xFA, 0x06, 0x16, 0x14}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_6 */
-	{
-	0xEB, 0x04, 0x25, 0x18}, {
-	0xE7, 0x0E, 0x29, 0x04}, {
-	0xEE, 0x0C, 0x22, 0x08}, {
-	0xF6, 0x0B, 0x1A, 0x0A}, {
-	0xF9, 0x0A, 0x17, 0x0C}, {
-	0xFC, 0x0A, 0x14, 0x0C}, {
-	0x00, 0x08, 0x10, 0x10}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_7 */
-	{
-	0xEC, 0x02, 0x24, 0x1C}, {
-	0xF2, 0x04, 0x1E, 0x18}, {
-	0xEB, 0x15, 0x25, 0xF6}, {
-	0xF4, 0x10, 0x1C, 0x00}, {
-	0xF8, 0x0F, 0x18, 0x02}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0x01, 0x06, 0x0F, 0x14}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_0 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_1 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_2 */
-	{
-	0xF5, 0xEE, 0x1B, 0x44}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xF1, 0xF7, 0x01, 0x32}, {
-	0xF5, 0xFB, 0x1B, 0x2A}, {
-	0xF9, 0xFF, 0x17, 0x22}, {
-	0xFB, 0x01, 0x15, 0x1E}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_3 */
-	{
-	0xF5, 0xFB, 0x1B, 0x2A}, {
-	0xEE, 0xFE, 0x22, 0x24}, {
-	0xF3, 0x00, 0x1D, 0x20}, {
-	0xF9, 0x03, 0x17, 0x1A}, {
-	0xFB, 0x02, 0x14, 0x1E}, {
-	0xFB, 0x04, 0x15, 0x18}, {
-	0x00, 0x06, 0x10, 0x14}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_4 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_5 */
-	{
-	0xF5, 0xEE, 0x1B, 0x44}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xF1, 0xF7, 0x1F, 0x32}, {
-	0xF5, 0xFB, 0x1B, 0x2A}, {
-	0xF9, 0xFF, 0x17, 0x22}, {
-	0xFB, 0x01, 0x15, 0x1E}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_6 */
-	{
-	0xF5, 0xEE, 0x1B, 0x2A}, {
-	0xEE, 0xFE, 0x22, 0x24}, {
-	0xF3, 0x00, 0x1D, 0x20}, {
-	0xF9, 0x03, 0x17, 0x1A}, {
-	0xFB, 0x02, 0x14, 0x1E}, {
-	0xFB, 0x04, 0x15, 0x18}, {
-	0x00, 0x06, 0x10, 0x14}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_7 */
-	{
-	0xF5, 0xEE, 0x1B, 0x44}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0xEB, 0x05, 0x25, 0x16}, {
-	0xF1, 0x05, 0x1F, 0x16}, {
-	0xFA, 0x07, 0x16, 0x12}, {
-	0x00, 0x07, 0x10, 0x12}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_0 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_1 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_2 */
+	   {0xF5,0xEE,0x1B,0x44},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xEB,0x04,0x25,0x18},
+	   {0xF1,0x05,0x1F,0x16},
+	   {0xF6,0x06,0x1A,0x14},
+	   {0xFA,0x06,0x16,0x14},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_3 */
+	   {0xF1,0x04,0x1F,0x18},
+	   {0xEE,0x0D,0x22,0x06},
+	   {0xF7,0x06,0x19,0x14},
+	   {0xF4,0x0B,0x1C,0x0A},
+	   {0xFA,0x07,0x16,0x12},
+	   {0xF9,0x0A,0x17,0x0C},
+	   {0x00,0x07,0x10,0x12}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_4 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_5 */
+	   {0xF5,0xEE,0x1B,0x44},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xEB,0x04,0x25,0x18},
+	   {0xF1,0x05,0x1F,0x16},
+	   {0xF6,0x06,0x1A,0x14},
+	   {0xFA,0x06,0x16,0x14},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_6 */
+	   {0xEB,0x04,0x25,0x18},
+	   {0xE7,0x0E,0x29,0x04},
+	   {0xEE,0x0C,0x22,0x08},
+	   {0xF6,0x0B,0x1A,0x0A},
+	   {0xF9,0x0A,0x17,0x0C},
+	   {0xFC,0x0A,0x14,0x0C},
+	   {0x00,0x08,0x10,0x10}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_7 */
+	   {0xEC,0x02,0x24,0x1C},
+	   {0xF2,0x04,0x1E,0x18},
+	   {0xEB,0x15,0x25,0xF6},
+	   {0xF4,0x10,0x1C,0x00},
+	   {0xF8,0x0F,0x18,0x02},
+	   {0x00,0x04,0x10,0x18},
+	   {0x01,0x06,0x0F,0x14}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_0 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_1 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_2 */
+	   {0xF5,0xEE,0x1B,0x44},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xF1,0xF7,0x01,0x32},
+	   {0xF5,0xFB,0x1B,0x2A},
+	   {0xF9,0xFF,0x17,0x22},
+	   {0xFB,0x01,0x15,0x1E},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_3 */
+	   {0xF5,0xFB,0x1B,0x2A},
+	   {0xEE,0xFE,0x22,0x24},
+	   {0xF3,0x00,0x1D,0x20},
+	   {0xF9,0x03,0x17,0x1A},
+	   {0xFB,0x02,0x14,0x1E},
+	   {0xFB,0x04,0x15,0x18},
+	   {0x00,0x06,0x10,0x14}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_4 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_5 */
+	   {0xF5,0xEE,0x1B,0x44},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xF1,0xF7,0x1F,0x32},
+	   {0xF5,0xFB,0x1B,0x2A},
+	   {0xF9,0xFF,0x17,0x22},
+	   {0xFB,0x01,0x15,0x1E},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_6 */
+	   {0xF5,0xEE,0x1B,0x2A},
+	   {0xEE,0xFE,0x22,0x24},
+	   {0xF3,0x00,0x1D,0x20},
+	   {0xF9,0x03,0x17,0x1A},
+	   {0xFB,0x02,0x14,0x1E},
+	   {0xFB,0x04,0x15,0x18},
+	   {0x00,0x06,0x10,0x14}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_7 */
+	   {0xF5,0xEE,0x1B,0x44},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0xEB,0x05,0x25,0x16},
+	   {0xF1,0x05,0x1F,0x16},
+	   {0xFA,0x07,0x16,0x12},
+	   {0x00,0x07,0x10,0x12}, 
+	   {0xFF,0xFF,0xFF,0xFF} }}
 };
 
 static int filter = -1;
@@ -589,101 +698,107 @@
 /* ---------------------- Routine Prototype ------------------------- */
 
 /* Interface used by the world */
-int sisfb_setup (char *options);
-static int sisfb_get_fix (struct fb_fix_screeninfo *fix, int con,
+int sisfb_setup(char *options);
+static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info);
+static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
+static int sisfb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
+static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
 			  struct fb_info *info);
-static int sisfb_get_var (struct fb_var_screeninfo *var, int con,
+static int sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
 			  struct fb_info *info);
-static int sisfb_set_var (struct fb_var_screeninfo *var, int con,
-			  struct fb_info *info);
-static int sisfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
-			   struct fb_info *info);
-static int sisfb_setcolreg (unsigned regno, unsigned red, unsigned green,
-			    unsigned blue, unsigned transp,
-			    struct fb_info *fb_info);
-static int sisfb_ioctl (struct inode *inode, struct file *file,
-			unsigned int cmd, unsigned long arg, int con,
-			struct fb_info *info);
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg, int con,
+		       struct fb_info *info);
 
 /* Interface to the low level console driver */
-int sisfb_init (void);
-static int sisfb_update_var (int con, struct fb_info *info);
-static int sisfb_switch (int con, struct fb_info *info);
-static int sisfb_blank(int blank, struct fb_info *info);
+int sisfb_init(void);
+static int sisfb_update_var(int con, struct fb_info *info);
+static int sisfb_switch(int con, struct fb_info *info);
+static void sisfb_blank(int blank, struct fb_info *info);
 
 /* hardware access routines */
-void sisfb_set_reg1 (u16 port, u16 index, u16 data);
-void sisfb_set_reg3 (u16 port, u16 data);
-void sisfb_set_reg4 (u16 port, unsigned long data);
-u8 sisfb_get_reg1 (u16 port, u16 index);
-u8 sisfb_get_reg2 (u16 port);
-u32 sisfb_get_reg3 (u16 port);
-// Eden Chen
-//void sisfb_clear_DAC(u16 port);
-//void sisfb_clear_buffer(PHW_DEVICE_EXTENSION psishw_ext);
-// ~Eden Chen
+void sisfb_set_reg1(u16 port, u16 index, u16 data);
+void sisfb_set_reg3(u16 port, u16 data);
+void sisfb_set_reg4(u16 port, unsigned long data);
+u8   sisfb_get_reg1(u16 port, u16 index);
+u8   sisfb_get_reg2(u16 port);
+u32  sisfb_get_reg3(u16 port);
 
 /* Internal routines */
-static void sisfb_search_mode (const char *name);
-static void sisfb_validate_mode (void);
-static u8 sisfb_search_refresh_rate (unsigned int rate);
-static int sis_getcolreg (unsigned regno, unsigned *red, unsigned *green,
-			  unsigned *blue, unsigned *transp,
-			  struct fb_info *fb_info);
-static int sisfb_do_set_var (struct fb_var_screeninfo *var, int isactive,
-			     struct fb_info *info);
-static void sisfb_set_disp (int con, struct fb_var_screeninfo *var);
+static void sisfb_search_mode(const char *name);
+static void sisfb_validate_mode(void);
+static u8   sisfb_search_refresh_rate(unsigned int rate);
+static int  sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			 unsigned *blue, unsigned *transp,
+			 struct fb_info *fb_info);
+static int  sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			 unsigned blue, unsigned transp,
+			 struct fb_info *fb_info);
+static int  sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
+		      struct fb_info *info);
+static void sisfb_set_disp(int con, struct fb_var_screeninfo *var);
+static void sisfb_do_install_cmap(int con, struct fb_info *info);
 
 /* Chip-dependent Routines */
 #ifdef CONFIG_FB_SIS_300
-static int sisfb_get_dram_size_300 (void);
-//extern BOOLEAN SiSInit300(PHW_DEVICE_EXTENSION HwDeviceExtension);
-static void sisfb_detect_VB_connect_300 (void);
-static void sisfb_get_VB_type_300 (void);
-static int sisfb_has_VB_300 (void);
-//extern BOOLEAN SiSSetMode(PHW_DEVICE_EXTENSION HwDeviceExtension,USHORT ModeNo);
+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);
-//extern BOOLEAN SiSInit310(PHW_DEVICE_EXTENSION HwDeviceExtension);
-static void sisfb_detect_VB_connect_315 (void);
-static void sisfb_get_VB_type_315 (void);
-//extern BOOLEAN SiSSetMode310(PHW_DEVICE_EXTENSION HwDeviceExtension, USHORT ModeNo);
+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
 
-/* SetMode routines */
+/* Routines from init.c/init301.c */
 
-// Eden Chen
-extern BOOLEAN SiSSetMode (PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			   USHORT ModeNo);
-extern BOOLEAN SiSInit (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-// ~Eden Chen
-
-static void sisfb_pre_setmode (void);
-static void sisfb_post_setmode (void);
-static void sisfb_crtc_to_var (struct fb_var_screeninfo *var);
+extern void 	SiSRegInit(USHORT BaseAddr);
+extern BOOLEAN  SiSInit(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN  SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
+extern void     SetEnableDstn(void);
+
+/* TW: Chrontel TV functions */
+extern USHORT   SiS_IF_DEF_CH70xx;
+extern USHORT 	SiS_GetCH700x(USHORT tempbx);
+extern void 	SiS_SetCH700x(USHORT tempbx);
+extern USHORT 	SiS_GetCH701x(USHORT tempbx);
+extern void 	SiS_SetCH701x(USHORT tempbx);
+extern void     SiS_SetCH70xxANDOR(USHORT tempax,USHORT tempbh);
+extern void     SiS_DDC2Delay(USHORT delaytime);
+
+static void sisfb_pre_setmode(void);
+static void sisfb_post_setmode(void);
+static void sisfb_crtc_to_var(struct fb_var_screeninfo *var);
 
 /* Export functions  */
-static void sis_get_glyph (struct fb_info *info, SIS_GLYINFO * gly);
-void sis_dispinfo (struct ap_data *rec);
-void sis_malloc (struct sis_memreq *req);
-void sis_free (unsigned long base);
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
+static void sis_get_glyph(SIS_GLYINFO *gly);
+#else
+static void sis_get_glyph(struct fb_info *info, SIS_GLYINFO *gly);
+#endif
+void sis_dispinfo(struct ap_data *rec);
+void sis_malloc(struct sis_memreq *req);
+void sis_free(unsigned long base);
 
 /* heap routines */
-static int sisfb_heap_init (void);
-static SIS_OH *sisfb_poh_new_node (void);
-static SIS_OH *sisfb_poh_allocate (unsigned long size);
-static void sisfb_delete_node (SIS_OH * poh);
-static void sisfb_insert_node (SIS_OH * pohList, SIS_OH * poh);
-static SIS_OH *sisfb_poh_free (unsigned long base);
-static void sisfb_free_node (SIS_OH * poh);
+static int sisfb_heap_init(void);
+static SIS_OH *sisfb_poh_new_node(void);
+static SIS_OH *sisfb_poh_allocate(unsigned long size);
+static void sisfb_delete_node(SIS_OH *poh);
+static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh);
+static SIS_OH *sisfb_poh_free(unsigned long base);
+static void sisfb_free_node(SIS_OH *poh);
 
 /* routines to access PCI configuration space */
-BOOLEAN sisfb_query_VGA_config_space (PSIS_HW_DEVICE_INFO psishw_ext,
-				      unsigned long offset, unsigned long set,
-				      unsigned long *value);
-BOOLEAN sisfb_query_north_bridge_space (PSIS_HW_DEVICE_INFO psishw_ext,
-					unsigned long offset, unsigned long set,
-					unsigned long *value);
+BOOLEAN sisfb_query_VGA_config_space(PSIS_HW_DEVICE_INFO psishw_ext, 
+	unsigned long offset, unsigned long set, unsigned long *value);
+BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext, 
+	unsigned long offset, unsigned long set, unsigned long *value);
 
 #endif
diff -Nru a/drivers/video/sis/sisfb.h b/drivers/video/sis/sisfb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/sis/sisfb.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,153 @@
+#ifndef _LINUX_SISFB
+#define _LINUX_SISFB
+
+#include <asm/ioctl.h>
+#include <asm/types.h>
+
+#define DISPTYPE_CRT1       0x00000008L
+#define DISPTYPE_CRT2       0x00000004L
+#define DISPTYPE_LCD        0x00000002L
+#define DISPTYPE_TV         0x00000001L
+#define DISPTYPE_DISP1      DISPTYPE_CRT1
+#define DISPTYPE_DISP2      (DISPTYPE_CRT2 | DISPTYPE_LCD | DISPTYPE_TV)
+#define DISPMODE_SINGLE	    0x00000020L
+#define DISPMODE_MIRROR	    0x00000010L
+#define DISPMODE_DUALVIEW   0x00000040L
+
+#define HASVB_NONE      	0x00
+#define HASVB_301       	0x01
+#define HASVB_LVDS      	0x02
+#define HASVB_TRUMPION  	0x04
+#define HASVB_LVDS_CHRONTEL	0x10
+#define HASVB_302       	0x20
+#define HASVB_303       	0x40
+#define HASVB_CHRONTEL  	0x80
+
+/* TW: *Never* change the order of the following enum */
+typedef enum _SIS_CHIP_TYPE {
+	SIS_VGALegacy = 0,
+	SIS_300,
+	SIS_630,
+	SIS_540,
+	SIS_730, 
+	SIS_315H,
+	SIS_315,
+	SIS_550,
+	SIS_315PRO,
+	SIS_640,
+	SIS_740,
+	SIS_650,
+	SIS_330,
+	MAX_SIS_CHIP
+} SIS_CHIP_TYPE;
+
+typedef enum _TVTYPE {
+	TVMODE_NTSC = 0,
+	TVMODE_PAL,
+	TVMODE_HIVISION,
+	TVMODE_TOTAL
+} SIS_TV_TYPE;
+
+typedef enum _TVPLUGTYPE {
+	TVPLUG_Legacy = 0,
+	TVPLUG_COMPOSITE,
+	TVPLUG_SVIDEO,
+	TVPLUG_SCART,
+	TVPLUG_TOTAL
+} SIS_TV_PLUG;
+
+struct sis_memreq {
+	unsigned long offset;
+	unsigned long size;
+};
+
+struct mode_info {
+	int    bpp;
+	int    xres;
+	int    yres;
+	int    v_xres;
+	int    v_yres;
+	int    org_x;
+	int    org_y;
+	unsigned int  vrate;
+};
+
+struct ap_data {
+	struct mode_info minfo;
+	unsigned long iobase;
+	unsigned int  mem_size;
+	unsigned long disp_state;    	
+	SIS_CHIP_TYPE chip;
+	unsigned char hasVB;
+	SIS_TV_TYPE TV_type;
+	SIS_TV_PLUG TV_plug;
+	unsigned long version;
+	char reserved[256];
+};
+
+struct video_info {
+	int    chip_id;
+	unsigned int  video_size;
+	unsigned long video_base;
+	char  *video_vbase;
+	unsigned long mmio_base;
+	char  *mmio_vbase; 
+	unsigned long vga_base;
+	unsigned long mtrr;
+	unsigned long heapstart;
+
+	int    video_bpp;
+	int    video_width;
+	int    video_height;
+	int    video_vwidth;
+	int    video_vheight;
+	int    org_x;
+	int    org_y;
+	unsigned int refresh_rate;
+
+	unsigned long disp_state;
+	unsigned char hasVB;
+	unsigned char TV_type;
+	unsigned char TV_plug;
+
+	SIS_CHIP_TYPE chip;
+	unsigned char revision_id;
+
+	char reserved[256];
+};
+
+
+/* TW: Addtional IOCTL for communication sisfb <> X driver                 */
+/*     If changing this, vgatypes.h must also be changed (for X driver)    */
+
+/* TW: ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISFB_GET_INFO	  _IOR('n',0xF8,sizeof(__u32))
+
+/* TW: Structure argument for SISFB_GET_INFO ioctl  */
+typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
+
+struct _SISFB_INFO {
+	unsigned long sisfb_id;         /* for identifying sisfb */
+#ifndef SISFB_ID
+#define SISFB_ID	  0x53495346    /* Identify myself with 'SISF' */
+#endif
+ 	int    chip_id;			/* PCI ID of detected chip */
+	int    memory;			/* video memory in KB which sisfb manages */
+	int    heapstart;               /* heap start (= sisfb "mem" argument) in KB */
+	unsigned char fbvidmode;	/* current sisfb mode */
+	
+	unsigned char sisfb_version;
+	unsigned char sisfb_revision;
+	unsigned char sisfb_patchlevel;
+
+	char reserved[253]; 		/* for future use */
+};
+
+#ifdef __KERNEL__
+extern struct video_info ivideo;
+
+extern void sis_malloc(struct sis_memreq *req);
+extern void sis_free(unsigned long base);
+extern void sis_dispinfo(struct ap_data *rec);
+#endif
+#endif
diff -Nru a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
--- a/drivers/video/sis/vgatypes.h	Wed Jul 24 14:03:35 2002
+++ b/drivers/video/sis/vgatypes.h	Wed Jul 24 14:03:35 2002
@@ -1,6 +1,14 @@
 #ifndef _VGATYPES_
 #define _VGATYPES_
 
+#ifdef LINUX_XF86
+#include "xf86Pci.h"
+#endif
+
+#ifdef LINUX_KERNEL  /* TW: We don't want the X driver to depend on kernel source */
+#include <linux/ioctl.h>
+#endif
+
 #ifndef TC
 #define far
 #endif
@@ -26,7 +34,7 @@
 #endif
 
 #ifndef LONG
-typedef long LONG;
+typedef long  LONG;
 #endif
 
 #ifndef UCHAR
@@ -68,27 +76,52 @@
 #ifndef bool
 typedef UCHAR bool;
 #endif
-#endif	/* WINCE_HEADER */
+#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,
+#ifdef LINUX_XF86
+    SIS_530,	/* TW */
+    SIS_OLD,	/* TW */
+#endif
+    SIS_300,
+    SIS_630,
+    SIS_730,
+    SIS_540,
+    SIS_315H,   /* SiS 310 */
+    SIS_315,
+    SIS_315PRO, /* SiS 325 */
+    SIS_550,
+    SIS_640,
+    SIS_740,
+    SIS_650,
+    SIS_330, 
+    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_301BLCD,
-	VB_CHIP_301BTV,
-	VB_CHIP_302,
-	VB_CHIP_302B,
-	VB_CHIP_302BLCD,
-	VB_CHIP_302BTV,
-	VB_CHIP_303,
-	VB_CHIP_UNKNOWN,	/* other video bridge or no video bridge */
-	MAX_VB_CHIP
+    VB_CHIP_Legacy = 0,
+    VB_CHIP_301,
+    VB_CHIP_301B,      
+    VB_CHIP_301LV,
+    VB_CHIP_302,
+    VB_CHIP_302B,
+    VB_CHIP_302LV,
+    VB_CHIP_303,
+    VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
+    MAX_VB_CHIP
 } SIS_VB_CHIP_TYPE;
 #endif
 #endif
@@ -96,125 +129,169 @@
 #ifndef WIN2000
 #ifndef SIS_LCD_TYPE
 typedef enum _SIS_LCD_TYPE {
-	LCD_INVALID = 0,
-	LCD_800x600,
-	LCD_1024x768,
-	LCD_1280x1024,
-	LCD_1280x960,
-	LCD_640x480,
-	LCD_1600x1200,
-	LCD_1920x1440,
-	LCD_2048x1536,
-	LCD_UNKNOWN
+    LCD_INVALID = 0,
+    LCD_800x600,
+    LCD_1024x768,
+    LCD_1280x1024,
+    LCD_1280x960,
+    LCD_640x480,
+    LCD_1600x1200,
+    LCD_1920x1440,
+    LCD_2048x1536,
+    LCD_320x480,       /* TW: FSTN */
+    LCD_1400x1050,
+    LCD_1152x864,
+    LCD_1152x768,
+    LCD_1280x768,
+    LCD_1024x600,
+    LCD_UNKNOWN
 } SIS_LCD_TYPE;
 #endif
 #endif
 
-#ifndef WIN2000			/* mark by Paul ,Move definition to sisv.h */
+#ifndef WIN2000 /* mark by Paul, Move definition to sisv.h*/
 #ifndef PSIS_DSReg
-typedef struct _SIS_DSReg {
-	UCHAR jIdx;
-	UCHAR jVal;
+typedef struct _SIS_DSReg
+{
+  UCHAR  jIdx;
+  UCHAR  jVal;
 } SIS_DSReg, *PSIS_DSReg;
 #endif
 
 #ifndef SIS_HW_DEVICE_INFO
 
-typedef struct _SIS_HW_DEVICE_INFO SIS_HW_DEVICE_INFO, *PSIS_HW_DEVICE_INFO;
+typedef struct _SIS_HW_DEVICE_INFO  SIS_HW_DEVICE_INFO, *PSIS_HW_DEVICE_INFO;
+
+typedef BOOLEAN (*PSIS_QUERYSPACE)   (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
+
 
-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
+                                    in each OS or NULL for unused. */
+    UCHAR  *pjVirtualRomBase;    /* base virtual address of VBIOS ROM Space */
+                                 /* or base virtual address of ROM image file. */
+                                 /* if NULL, then read from pjROMImage; */
+                                 /* Note:ROM image file is the file of VBIOS ROM */
+
+ 
+    UCHAR  *pjCustomizedROMImage;/* base virtual address of ROM image file. */
+                                 /* wincE:ROM image file is the file for OEM */
+                                 /*       customized table */
+                                 /* Linux: not used */
+                                 /* NT   : not used  */
+                                 /* Note : pjCustomizedROMImage=NULL if no ROM image file */
+
+    UCHAR  *pjVideoMemoryAddress;/* base virtual memory address */
+                                 /* of Linear VGA memory */
+
+    ULONG  ulVideoMemorySize;    /* size, in bytes, of the memory on the board */
+    ULONG  ulIOAddress;          /* base I/O address of VGA ports (0x3B0) */
+    UCHAR  jChipType;            /* Used to Identify SiS Graphics Chip */
+                                 /* defined in the data structure type  */
+                                 /* "SIS_CHIP_TYPE" */
+
+    UCHAR  jChipRevision;        /* Used to Identify SiS Graphics Chip Revision */
+    UCHAR  ujVBChipID;           /* the ID of video bridge */
+                                 /* defined in the data structure type */
+                                 /* "SIS_VB_CHIP_TYPE" */
+
+    USHORT usExternalChip;       /* NO VB or other video bridge(not  */
+                                 /* SiS video bridge) */
+                                 /* if ujVBChipID = VB_CHIP_UNKNOWN, */
+                                 /* then bit0=1 : LVDS,bit1=1 : trumpion, */
+                                 /* bit2=1 : CH7005 & no video bridge if */
+                                 /* usExternalChip = 0. */
+                                 /* Note: CR37[3:1]: */
+                                 /*             001:SiS 301 */
+                                 /*             010:LVDS */
+                                 /*             011:Trumpion LVDS Scaling Chip */
+                                 /*             100:LVDS(LCD-out)+Chrontel 7005 */
+                                 /*             101:Single Chrontel 7005 */
+
+    ULONG  ulCRT2LCDType;        /* defined in the data structure type */
+                                 /* "SIS_LCD_TYPE" */
+                                     
+    BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
+                                      
+    BOOLEAN bSkipDramSizing;     /* True: Skip video memory sizing. */
+    PSIS_DSReg  pSR;             /* restore SR registers in initial function. */
+                                 /* end data :(idx, val) =  (FF, FF). */
+                                 /* Note : restore SR registers if  */
+                                 /* bSkipDramSizing = TRUE */
+
+    PSIS_DSReg  pCR;             /* restore CR registers in initial function. */
+                                 /* end data :(idx, val) =  (FF, FF) */
+                                 /* Note : restore cR registers if  */
+                                 /* bSkipDramSizing = TRUE */
+
+    PSIS_QUERYSPACE  pQueryVGAConfigSpace; /* Get/Set VGA Configuration  */
+                                           /* space */
+ 
+    PSIS_QUERYSPACE  pQueryNorthBridgeSpace;/* Get/Set North Bridge  */
+                                            /* space  */
 
-struct _SIS_HW_DEVICE_INFO {
-	PVOID pDevice;		/* The pointer to the physical device data structure 
-				   in each OS or NULL for unused. */
-	UCHAR *pjVirtualRomBase;	/* Only for NT, NULL for WinCE & Linux. */
-	/* base virtual address of VBIOS ROM Space */
-	/* or base virtual address of ROM image file. */
-	/* if NULL, then read from pjROMImage; */
-	/* Note:ROM image file is the file of VBIOS ROM */
-
-	UCHAR *pjCustomizedROMImage;	/* base virtual address of ROM image file. */
-	/* wincE:ROM image file is the file for OEM */
-	/*       customized table */
-	/* Linux: not used */
-	/* NT   : not used  */
-	/* Note : pjCustomizedROMImage=NULL if no ROM image file */
-
-	UCHAR *pjVideoMemoryAddress;	/* base virtual memory address */
-	/* of Linear VGA memory */
-
-	ULONG ulVideoMemorySize;	/* size, in bytes, of the memory on the board */
-	ULONG ulIOAddress;	/* base I/O address of VGA ports (0x3B0) */
-	UCHAR jChipType;	/* Used to Identify SiS Graphics Chip */
-	/* defined in the data structure type  */
-	/* "SIS_CHIP_TYPE" */
-
-	UCHAR jChipRevision;	/* Used to Identify SiS Graphics Chip Revision */
-	UCHAR ujVBChipID;	/* the ID of video bridge */
-	/* defined in the data structure type */
-	/* "SIS_VB_CHIP_TYPE" */
-
-	USHORT usExternalChip;	/* NO VB or other video bridge(not  */
-	/* SiS video bridge) */
-	/* if ujVBChipID = VB_CHIP_UNKNOWN, */
-	/* then bit0=1 : LVDS,bit1=1 : trumpion, */
-	/* bit2=1 : CH7005 & no video bridge if */
-	/* usExternalChip = 0. */
-	/* Note: CR37[3:1]: */
-	/*             001:SiS 301 */
-	/*             010:LVDS */
-	/*             011:Trumpion LVDS Scaling Chip */
-	/*             100:LVDS(LCD-out)+Chrontel 7005 */
-	/*             101:Single Chrontel 7005 */
-
-	ULONG ulCRT2LCDType;	/* defined in the data structure type */
-	/* "SIS_LCD_TYPE" */
-
-	BOOLEAN bIntegratedMMEnabled;	/* supporting integration MM enable */
-
-	BOOLEAN bSkipDramSizing;	/* True: Skip video memory sizing. */
-	PSIS_DSReg pSR;		/* restore SR registers in initial function. */
-	/* end data :(idx, val) =  (FF, FF). */
-	/* Note : restore SR registers if  */
-	/* bSkipDramSizing = TRUE */
-
-	PSIS_DSReg pCR;		/* restore CR registers in initial function. */
-	/* end data :(idx, val) =  (FF, FF) */
-	/* Note : restore cR registers if  */
-	/* bSkipDramSizing = TRUE */
+    UCHAR  szVBIOSVer[VBIOS_VER_MAX_LENGTH];
 
-	PSIS_QUERYSPACE pQueryVGAConfigSpace;	/* Get/Set VGA Configuration  */
-	/* space */
+    UCHAR  pdc;			/* TW: PanelDelayCompensation */
 
-	PSIS_QUERYSPACE pQueryNorthBridgeSpace;	/* Get/Set North Bridge  */
-	/* space  */
+#ifdef LINUX_XF86
+    PCITAG PciTag;		/* PCI Tag for Linux XF86 */
+#endif
+};
+#endif
+#endif /*~ mark by Paul ,Move definition to sisv.h  */
+
+
+/* TW: Addtional IOCTL for communication sisfb <> X driver        */
+/*     If changing this, sisfb.h must also be changed (for sisfb) */
+
+#ifdef LINUX_XF86  /* We don't want the X driver to depend on the kernel source */
 
-	UCHAR szVBIOSVer[VBIOS_VER_MAX_LENGTH];
+/* TW: ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISFB_GET_INFO    0x80046ef8  /* Wow, what a terrible hack... */
 
+/* TW: Structure argument for SISFB_GET_INFO ioctl  */
+typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
+
+struct _SISFB_INFO {
+	unsigned long sisfb_id;         /* for identifying sisfb */
+#ifndef SISFB_ID
+#define SISFB_ID	  0x53495346    /* Identify myself with 'SISF' */
+#endif
+ 	int    chip_id;			/* PCI ID of detected chip */
+	int    memory;			/* video memory in KB which sisfb manages */
+	int    heapstart;               /* heap start (= sisfb "mem" argument) in KB */
+	unsigned char fbvidmode;	/* current sisfb mode */
+
+	unsigned char sisfb_version;
+	unsigned char sisfb_revision;
+	unsigned char sisfb_patchlevel;
+
+	char reserved[253]; 		/* for future use */
 };
 #endif
-#endif				/*~ mark by Paul ,Move definition to sisv.h */
 
 #ifndef WIN2000
 #ifndef WINCE_HEADER
 #ifndef BUS_DATA_TYPE
 typedef enum _BUS_DATA_TYPE {
-	ConfigurationSpaceUndefined = -1,
-	Cmos,
-	EisaConfiguration,
-	Pos,
-	CbusConfiguration,
-	PCIConfiguration,
-	VMEConfiguration,
-	NuBusConfiguration,
-	PCMCIAConfiguration,
-	MPIConfiguration,
-	MPSAConfiguration,
-	PNPISAConfiguration,
-	MaximumBusDataType
+    ConfigurationSpaceUndefined = -1,
+    Cmos,
+    EisaConfiguration,
+    Pos,
+    CbusConfiguration,
+    PCIConfiguration,
+    VMEConfiguration,
+    NuBusConfiguration,
+    PCMCIAConfiguration,
+    MPIConfiguration,
+    MPSAConfiguration,
+    PNPISAConfiguration,
+    MaximumBusDataType
 } BUS_DATA_TYPE, *PBUS_DATA_TYPE;
 #endif
-#endif				/* WINCE_HEADER */
+#endif /* WINCE_HEADER */
 
 #ifndef PCI_TYPE0_ADDRESSES
 #define PCI_TYPE0_ADDRESSES             6
@@ -227,41 +304,42 @@
 #ifndef WINCE_HEADER
 #ifndef PCI_COMMON_CONFIG
 typedef struct _PCI_COMMON_CONFIG {
-	USHORT VendorID;	/* (ro)                 */
-	USHORT DeviceID;	/* (ro)                 */
-	USHORT Command;		/* Device control       */
-	USHORT Status;
-	UCHAR RevisionID;	/* (ro)                 */
-	UCHAR ProgIf;		/* (ro)                 */
-	UCHAR SubClass;		/* (ro)                 */
-	UCHAR BaseClass;	/* (ro)                 */
-	UCHAR CacheLineSize;	/* (ro+)                */
-	UCHAR LatencyTimer;	/* (ro+)                */
-	UCHAR HeaderType;	/* (ro)                 */
-	UCHAR BIST;		/* Built in self test   */
-
-	union {
-		struct _PCI_HEADER_TYPE_0 {
-			ULONG BaseAddresses[PCI_TYPE0_ADDRESSES];
-			ULONG CIS;
-			USHORT SubVendorID;
-			USHORT SubSystemID;
-			ULONG ROMBaseAddress;
-			ULONG Reserved2[2];
-
-			UCHAR InterruptLine;	/*                    */
-			UCHAR InterruptPin;	/* (ro)               */
-			UCHAR MinimumGrant;	/* (ro)               */
-			UCHAR MaximumLatency;	/* (ro)               */
-		} type0;
+    USHORT  VendorID;                   /* (ro)                 */
+    USHORT  DeviceID;                   /* (ro)                 */
+    USHORT  Command;                    /* Device control       */
+    USHORT  Status;
+    UCHAR   RevisionID;                 /* (ro)                 */
+    UCHAR   ProgIf;                     /* (ro)                 */
+    UCHAR   SubClass;                   /* (ro)                 */
+    UCHAR   BaseClass;                  /* (ro)                 */
+    UCHAR   CacheLineSize;              /* (ro+)                */
+    UCHAR   LatencyTimer;               /* (ro+)                */
+    UCHAR   HeaderType;                 /* (ro)                 */
+    UCHAR   BIST;                       /* Built in self test   */
+
+    union {
+        struct _PCI_HEADER_TYPE_0 {
+            ULONG   BaseAddresses[PCI_TYPE0_ADDRESSES];
+            ULONG   CIS;
+            USHORT  SubVendorID;
+            USHORT  SubSystemID;
+            ULONG   ROMBaseAddress;
+            ULONG   Reserved2[2];
+
+            UCHAR   InterruptLine;      /*                    */
+            UCHAR   InterruptPin;       /* (ro)               */
+            UCHAR   MinimumGrant;       /* (ro)               */
+            UCHAR   MaximumLatency;     /* (ro)               */
+        } type0;
+
 
-	} u;
+    } u;
 
-	UCHAR DeviceSpecific[192];
+    UCHAR   DeviceSpecific[192];
 
 } PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
 #endif
-#endif				/* WINCE_HEADER */
+#endif /* WINCE_HEADER */
 
 #ifndef FIELD_OFFSET
 #define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
diff -Nru a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
--- a/drivers/video/sis/vstruct.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/sis/vstruct.h	Wed Jul 24 14:03:36 2002
@@ -2,13 +2,15 @@
 #define EXTERN
 #else
 #define EXTERN extern
-#endif				/* _INIT_ */
+#endif /* _INIT_ */
 
-typedef struct _SiS_PanelDelayTblStruct {
-	UCHAR timer[2];
+typedef struct _SiS_PanelDelayTblStruct
+{
+ UCHAR timer[2];
 } SiS_PanelDelayTblStruct;
 
-typedef struct _SiS_LCDDataStruct {
+typedef struct _SiS_LCDDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -17,7 +19,8 @@
 	USHORT LCDVT;
 } SiS_LCDDataStruct;
 
-typedef struct _SiS_TVDataStruct {
+typedef struct _SiS_TVDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -33,32 +36,38 @@
 	UCHAR RY4COE;
 } SiS_TVDataStruct;
 
-typedef struct _SiS_LVDSDataStruct {
+typedef struct _SiS_LVDSDataStruct
+{
 	USHORT VGAHT;
 	USHORT VGAVT;
 	USHORT LCDHT;
 	USHORT LCDVT;
 } SiS_LVDSDataStruct;
 
-typedef struct _SiS_LVDSDesStruct {
+typedef struct _SiS_LVDSDesStruct
+{
 	USHORT LCDHDES;
 	USHORT LCDVDES;
 } SiS_LVDSDesStruct;
 
-typedef struct _SiS_LVDSCRT1DataStruct {
+typedef struct _SiS_LVDSCRT1DataStruct
+{
 	UCHAR CR[15];
 } SiS_LVDSCRT1DataStruct;
 
 /*add for LCDA*/
-typedef struct _SiS_LCDACRT1DataStruct {
+typedef struct _SiS_LCDACRT1DataStruct
+{
 	UCHAR CR[17];
 } SiS_LCDACRT1DataStruct;
 
-typedef struct _SiS_CHTVRegDataStruct {
-	UCHAR Reg[5];
+typedef struct _SiS_CHTVRegDataStruct
+{
+	UCHAR Reg[16];
 } SiS_CHTVRegDataStruct;
 
-typedef struct _SiS_StStruct {
+typedef struct _SiS_StStruct
+{
 	UCHAR St_ModeID;
 	USHORT St_ModeFlag;
 	UCHAR St_StTableIndex;
@@ -69,18 +78,20 @@
 	UCHAR VB_StTVYFilterIndex;
 } SiS_StStruct;
 
-typedef struct _SiS_VBModeStruct {
-	UCHAR ModeID;
-	UCHAR VB_TVDelayIndex;
-	UCHAR VB_TVFlickerIndex;
-	UCHAR VB_TVPhaseIndex;
-	UCHAR VB_TVYFilterIndex;
-	UCHAR VB_LCDDelayIndex;
-	UCHAR _VB_LCDHIndex;
-	UCHAR _VB_LCDVIndex;
+typedef struct _SiS_VBModeStruct
+{
+	UCHAR  ModeID;
+	UCHAR  VB_TVDelayIndex;
+	UCHAR  VB_TVFlickerIndex;
+	UCHAR  VB_TVPhaseIndex;
+	UCHAR  VB_TVYFilterIndex;
+	UCHAR  VB_LCDDelayIndex;
+	UCHAR  _VB_LCDHIndex;
+	UCHAR  _VB_LCDVIndex;
 } SiS_VBModeStruct;
 
-typedef struct _SiS_StandTableStruct {
+typedef struct _SiS_StandTableStruct
+{
 	UCHAR CRT_COLS;
 	UCHAR ROWS;
 	UCHAR CHAR_HEIGHT;
@@ -92,7 +103,8 @@
 	UCHAR GRC[9];
 } SiS_StandTableStruct;
 
-typedef struct _SiS_ExtStruct {
+typedef struct _SiS_ExtStruct
+{
 	UCHAR Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
@@ -106,65 +118,79 @@
 	UCHAR REFindex;
 } SiS_ExtStruct;
 
-typedef struct _SiS_Ext2Struct {
+typedef struct _SiS_Ext2Struct
+{
 	USHORT Ext_InfoFlag;
 	UCHAR Ext_CRT1CRTC;
 	UCHAR Ext_CRTVCLK;
 	UCHAR Ext_CRT2CRTC;
-	UCHAR ModeID;
+	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
 	USHORT ROM_OFFSET;
 } SiS_Ext2Struct;
 
-typedef struct _SiS_CRT1TableStruct {
+typedef struct _SiS_Part2PortTblStruct
+{
+ 	UCHAR CR[12];
+} SiS_Part2PortTblStruct;
+
+typedef struct _SiS_CRT1TableStruct
+{
 	UCHAR CR[17];
 } SiS_CRT1TableStruct;
 
-typedef struct _SiS_MCLKDataStruct {
-	UCHAR SR28, SR29, SR2A;
+typedef struct _SiS_MCLKDataStruct
+{
+	UCHAR SR28,SR29,SR2A;
 	USHORT CLOCK;
 } SiS_MCLKDataStruct;
 
-typedef struct _SiS_ECLKDataStruct {
-	UCHAR SR2E, SR2F, SR30;
+typedef struct _SiS_ECLKDataStruct
+{
+	UCHAR SR2E,SR2F,SR30;
 	USHORT CLOCK;
 } SiS_ECLKDataStruct;
 
-typedef struct _SiS_VCLKDataStruct {
-	UCHAR SR2B, SR2C;
+typedef struct _SiS_VCLKDataStruct
+{
+	UCHAR SR2B,SR2C;
 	USHORT CLOCK;
 } SiS_VCLKDataStruct;
 
-typedef struct _SiS_VBVCLKDataStruct {
-	UCHAR Part4_A, Part4_B;
+typedef struct _SiS_VBVCLKDataStruct
+{
+	UCHAR Part4_A,Part4_B;
 	USHORT CLOCK;
 } SiS_VBVCLKDataStruct;
 
-typedef struct _SiS_StResInfoStruct {
+typedef struct _SiS_StResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
 } SiS_StResInfoStruct;
 
-typedef struct _SiS_ModeResInfoStruct {
+typedef struct _SiS_ModeResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
-	UCHAR XChar;
-	UCHAR YChar;
+	UCHAR  XChar;
+	UCHAR  YChar;
 } SiS_ModeResInfoStruct;
 
 EXTERN SiS_StStruct *SiS_SModeIDTable;
 EXTERN SiS_StandTableStruct *SiS_StandTable;
-EXTERN SiS_ExtStruct *SiS_EModeIDTable;
-EXTERN SiS_Ext2Struct *SiS_RefIndex;
+EXTERN SiS_ExtStruct  *SiS_EModeIDTable;
+EXTERN SiS_Ext2Struct  *SiS_RefIndex;
 EXTERN SiS_VBModeStruct *SiS_VBModeIDTable;
-EXTERN SiS_CRT1TableStruct *SiS_CRT1Table;
-EXTERN SiS_MCLKDataStruct *SiS_MCLKData;
-EXTERN SiS_ECLKDataStruct *SiS_ECLKData;
-EXTERN SiS_VCLKDataStruct *SiS_VCLKData;
-EXTERN SiS_VBVCLKDataStruct *SiS_VBVCLKData;
-EXTERN SiS_StResInfoStruct *SiS_StResInfo;
-EXTERN SiS_ModeResInfoStruct *SiS_ModeResInfo;
+EXTERN SiS_CRT1TableStruct  *SiS_CRT1Table;
+EXTERN SiS_MCLKDataStruct  *SiS_MCLKData_0;
+EXTERN SiS_MCLKDataStruct  *SiS_MCLKData_1;
+EXTERN SiS_ECLKDataStruct  *SiS_ECLKData;
+EXTERN SiS_VCLKDataStruct  *SiS_VCLKData;
+EXTERN SiS_VBVCLKDataStruct  *SiS_VBVCLKData;
+EXTERN SiS_StResInfoStruct  *SiS_StResInfo;
+EXTERN SiS_ModeResInfoStruct  *SiS_ModeResInfo;
 EXTERN UCHAR *SiS_ScreenOffset;
 
 EXTERN UCHAR *pSiS_OutputSelect;
@@ -172,8 +198,8 @@
 EXTERN UCHAR *pSiS_SR07;
 
 typedef UCHAR DRAM4Type[4];
-EXTERN DRAM4Type *SiS_SR15;	/* pointer : point to array */
-EXTERN DRAM4Type *SiS_CR40;	/* pointer : point to array */
+EXTERN DRAM4Type *SiS_SR15; /* pointer : point to array */
+EXTERN DRAM4Type *SiS_CR40; /* pointer : point to array */
 EXTERN UCHAR *SiS_CR49;
 EXTERN UCHAR *SiS_SR25;
 
@@ -192,7 +218,7 @@
 EXTERN USHORT *pSiS_RGBSenseData;
 EXTERN USHORT *pSiS_VideoSenseData;
 EXTERN USHORT *pSiS_YCSenseData;
-EXTERN USHORT *pSiS_RGBSenseData2;	/*301b */
+EXTERN USHORT *pSiS_RGBSenseData2; /*301b*/
 EXTERN USHORT *pSiS_VideoSenseData2;
 EXTERN USHORT *pSiS_YCSenseData2;
 
@@ -202,21 +228,24 @@
 EXTERN UCHAR *SiS_PALPhase2;
 EXTERN UCHAR *SiS_PALMPhase;
 EXTERN UCHAR *SiS_PALNPhase;
-EXTERN SiS_LCDDataStruct *SiS_StLCD1024x768Data;
-EXTERN SiS_LCDDataStruct *SiS_ExtLCD1024x768Data;
-EXTERN SiS_LCDDataStruct *SiS_St2LCD1024x768Data;
-EXTERN SiS_LCDDataStruct *SiS_StLCD1280x1024Data;
-EXTERN SiS_LCDDataStruct *SiS_ExtLCD1280x1024Data;
-EXTERN SiS_LCDDataStruct *SiS_St2LCD1280x1024Data;
-EXTERN SiS_LCDDataStruct *SiS_NoScaleData;
-EXTERN SiS_LCDDataStruct *SiS_LCD1280x960Data;
-EXTERN SiS_TVDataStruct *SiS_StPALData;
-EXTERN SiS_TVDataStruct *SiS_ExtPALData;
-EXTERN SiS_TVDataStruct *SiS_StNTSCData;
-EXTERN SiS_TVDataStruct *SiS_ExtNTSCData;
-EXTERN SiS_TVDataStruct *SiS_St1HiTVData;
-EXTERN SiS_TVDataStruct *SiS_St2HiTVData;
-EXTERN SiS_TVDataStruct *SiS_ExtHiTVData;
+EXTERN UCHAR *SiS_PALMPhase2;
+EXTERN UCHAR *SiS_PALNPhase2;
+EXTERN SiS_LCDDataStruct  *SiS_StLCD1024x768Data;
+EXTERN SiS_LCDDataStruct  *SiS_ExtLCD1024x768Data;
+EXTERN SiS_LCDDataStruct  *SiS_St2LCD1024x768Data;
+EXTERN SiS_LCDDataStruct  *SiS_StLCD1280x1024Data;
+EXTERN SiS_LCDDataStruct  *SiS_ExtLCD1280x1024Data;
+EXTERN SiS_LCDDataStruct  *SiS_St2LCD1280x1024Data;
+EXTERN SiS_LCDDataStruct  *SiS_NoScaleData1024x768;
+EXTERN SiS_LCDDataStruct  *SiS_NoScaleData1280x1024;
+EXTERN SiS_LCDDataStruct  *SiS_LCD1280x960Data;
+EXTERN SiS_TVDataStruct   *SiS_StPALData;
+EXTERN SiS_TVDataStruct   *SiS_ExtPALData;
+EXTERN SiS_TVDataStruct   *SiS_StNTSCData;
+EXTERN SiS_TVDataStruct   *SiS_ExtNTSCData;
+EXTERN SiS_TVDataStruct   *SiS_St1HiTVData;
+EXTERN SiS_TVDataStruct   *SiS_St2HiTVData;
+EXTERN SiS_TVDataStruct   *SiS_ExtHiTVData;
 EXTERN UCHAR *SiS_NTSCTiming;
 EXTERN UCHAR *SiS_PALTiming;
 EXTERN UCHAR *SiS_HiTVExtTiming;
@@ -228,91 +257,125 @@
 EXTERN UCHAR *SiS_HiTVGroup3Text;
 
 EXTERN SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS800x600Data_1;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS800x600Data_2;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS1024x768Data_1;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS1024x768Data_2;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_1;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_2;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS640x480Data_1;
-EXTERN SiS_LVDSDataStruct *SiS_CHTVUNTSCData;
-EXTERN SiS_LVDSDataStruct *SiS_CHTVONTSCData;
-EXTERN SiS_LVDSDataStruct *SiS_CHTVUPALData;
-EXTERN SiS_LVDSDataStruct *SiS_CHTVOPALData;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType00_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType01_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType02_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType03_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType04_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType05_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType06_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType07_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType08_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType09_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0a_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0b_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0c_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0d_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0e_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0f_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType00_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType01_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType02_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType03_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType04_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType05_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType06_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType07_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType08_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType09_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0a_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0b_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0c_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0d_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0e_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0f_2;
-/*301b*/
-EXTERN SiS_LVDSDesStruct *LVDS1024x768Des_1;
-EXTERN SiS_LVDSDesStruct *LVDS1280x1024Des_1;
-EXTERN SiS_LVDSDesStruct *LVDS1280x960Des_1;
-EXTERN SiS_LVDSDesStruct *LVDS1024x768Des_2;
-EXTERN SiS_LVDSDesStruct *LVDS1280x1024Des_2;
-EXTERN SiS_LVDSDesStruct *LVDS1280x960Des_2;
-/*end 301b*/
-EXTERN SiS_LVDSDesStruct *SiS_CHTVUNTSCDesData;
-EXTERN SiS_LVDSDesStruct *SiS_CHTVONTSCDesData;
-EXTERN SiS_LVDSDesStruct *SiS_CHTVUPALDesData;
-EXTERN SiS_LVDSDesStruct *SiS_CHTVOPALDesData;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UNTSC;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1ONTSC;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UPAL;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1OPAL;
-/*add for  LCDA*/
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_1;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_1;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_1;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_1_H;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_1_H;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_1_H;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_2;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_2;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_2;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_2_H;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_2_H;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_2_H;
-/*end 301b*/
+EXTERN SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS800x600Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS800x600Data_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1280x1024Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1280x1024Data_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1280x960Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1280x960Data_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1400x1050Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1400x1050Data_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1024x600Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1024x600Data_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS640x480Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS320x480Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDSXXXxXXXData_1;
+EXTERN SiS_LVDSDataStruct  *SiS_CHTVUNTSCData;
+EXTERN SiS_LVDSDataStruct  *SiS_CHTVONTSCData;
+EXTERN SiS_LVDSDataStruct  *SiS_CHTVUPALData;
+EXTERN SiS_LVDSDataStruct  *SiS_CHTVOPALData;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType00_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType01_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType02_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType03_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType04_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType05_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType06_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType07_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType08_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType09_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0a_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0b_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0c_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0d_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0e_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0f_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType00_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType01_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType02_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType03_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType04_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType05_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType06_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType07_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType08_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType09_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0a_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0b_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0c_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0d_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0e_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0f_2;
+
+EXTERN SiS_LVDSDesStruct  *LVDS1024x768Des_1;
+EXTERN SiS_LVDSDesStruct  *LVDS1280x1024Des_1;
+EXTERN SiS_LVDSDesStruct  *LVDS1280x960Des_1;
+EXTERN SiS_LVDSDesStruct  *LVDS1024x768Des_2;
+EXTERN SiS_LVDSDesStruct  *LVDS1280x1024Des_2;
+EXTERN SiS_LVDSDesStruct  *LVDS1280x960Des_2;
+
+EXTERN SiS_LVDSDesStruct  *SiS_CHTVUNTSCDesData;
+EXTERN SiS_LVDSDesStruct  *SiS_CHTVONTSCDesData;
+EXTERN SiS_LVDSDesStruct  *SiS_CHTVUPALDesData;
+EXTERN SiS_LVDSDesStruct  *SiS_CHTVOPALDesData;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_1;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_1;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_1;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_1_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_1_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_1_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_2;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_2;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_2;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_2;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_2;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_2;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_2_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_2_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_2_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_2_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_2_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_2_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UNTSC;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1ONTSC;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UPAL;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1OPAL;
+
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1320x480_1;
+
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_1;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_1_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_2;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_2_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2_H;
+
+/* TW: New from 650/301LV BIOS */
+EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
+EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
+EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
+EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
+EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
+EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
 
 EXTERN SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC;
 EXTERN SiS_CHTVRegDataStruct *SiS_CHTVReg_ONTSC;
@@ -322,3 +385,6 @@
 EXTERN UCHAR *SiS_CHTVVCLKONTSC;
 EXTERN UCHAR *SiS_CHTVVCLKUPAL;
 EXTERN UCHAR *SiS_CHTVVCLKOPAL;
+
+
+
diff -Nru a/drivers/video/sstfb.c b/drivers/video/sstfb.c
--- a/drivers/video/sstfb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/sstfb.c	Wed Jul 24 14:03:38 2002
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/video/sstfb.c -- voodoo graphics frame buffer
  *
- *     Copyright (c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>
+ *     Copyright (c) 2000-2002 Ghozlane Toumi <gtoumi@laposte.net>
  *
  *     Created 15 Jan 2000 by Ghozlane Toumi
  *
@@ -9,11 +9,11 @@
  *
  * 03/2001 James Simmons   <jsimmons@linux-fbdev.org>
  * 04/2001 Paul Mundt      <lethal@chaoticdreams.org>
- * 05/2001 Urs Ganse       <urs.ganse@t-online.de>
- *     (initial work on voodoo2 port)
+ * 05/2001 Urs Ganse       <ursg@uni.de>
+ *     (initial work on voodoo2 port, interlace)
  *
  *
- * $Id: sstfb.c,v 1.26.4.1 2001/08/29 01:30:37 ghoz Exp $
+ * $Id: sstfb.c,v 1.37 2002/05/10 19:35:11 ghoz Exp $
  */
 
 /*
@@ -27,38 +27,22 @@
  * misc notes, TODOs, toASKs, and deep thoughts
 
 -TODO: at one time or another test that the mode is acceptable by the monitor
--ASK: I can choose different ordering for the color bitfields (rgba argb ...) 
-      wich one should i use ? is there any preferred one ? It seems ARGB is 
+-ASK: I can choose different ordering for the color bitfields (rgba argb ...)
+      wich one should i use ? is there any preferred one ? It seems ARGB is
       the one ...
 -ASK: later: how to cope with endianness ? the fbi chip has builtin functions
       to do byte swizling /swapping, maybe use that ...
--TODO: check the error paths . if something get wrong, the error doesn't seem 
-      to be very well handled...if handled at all.. not good. 
--ASK: ioremap ou ioremap_nocache ? : nocache is safe
+-TODO: check the error paths . if something get wrong, the error doesn't seem
+      to be very well handled...if handled at all.. not good.
 -TODO: in  set_var check the validity of timings (hsync vsync)...
--FIXME: I'm not sure i like all the functions with no parameters.. change them 
-        to use a sstfb_par or sstfb_info or something like that.
--TODO: check and recheck the use of sst_wait_idle : we dont flush the fifo via 
-       a nop command . so it's ok as long as the commands we pass don't go 
-       through the fifo. warning: issuing a nop command seems to need pci_fifo 
-       enabled
--ASK: the 24 bits mode is NOT packed . how do i differenciate from a packed mode ?
-      set a pseudo alpha value not used ?
--ASK: how does the 32 bpp work ? should i enable the pipeline so alpha values 
-      are used ?
--TODO: check how the voodoo graphics can cope with 24/32 bpp (engine is 16bpp 
-       only)
--ASK: Do i ioremap the complete area devoted to the lfb (4Mb), or check the 
-      real size, then unmap and remap to the real size of the lfb ? 
-      ... map all the area.
--FIXME: in case of failure in the init sequence, be sure we return to a safe 
+-TODO: check and recheck the use of sst_wait_idle : we dont flush the fifo via
+       a nop command . so it's ok as long as the commands we pass don't go
+       through the fifo. warning: issuing a nop command seems to need pci_fifo
+-FIXME: in case of failure in the init sequence, be sure we return to a safe
         state.
 -FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20)
 -ASK: I stole "inverse" but seems it doesn't work... check what it realy does...
-Notes
 -TODO: change struct sst_info fb_info from static to array/dynamic
-  TTT comments is for code i've put there for debuging the "weird peinguin 
-  	syndrome", it should disapear soon
 
  *
  */
@@ -87,8 +71,8 @@
  *   		test disp  (0x46de) : draws a test motif
  */
 
-/* #define SST_DEBUG */
-#undef SST_DEBUG
+#define SST_DEBUG
+//#undef SST_DEBUG
 
 #define SST_DEBUG_REG   0
 #define SST_DEBUG_FUNC  0
@@ -119,6 +103,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/version.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/ioctl.h>
@@ -132,52 +117,11 @@
 
 #include "sstfb.h"
 
-/* void Dump_regs(void); */
-
-/* sst default init registers */
-#define FBIINIT0_DEFAULT EN_VGA_PASSTHROUGH
-
-#define FBIINIT1_DEFAULT 	\
-	(			\
-	  FAST_PCI_WRITES	\
-/*	  SLOW_PCI_WRITES*/	\
-	| VIDEO_RESET		\
-	| 10 << TILES_IN_X_SHIFT\
-	| SEL_SOURCE_VCLK_2X_SEL\
-	| EN_LFB_READ		\
-	)
-
-#define FBIINIT2_DEFAULT	\
-	(			\
-	 SWAP_DACVSYNC		\
-	| EN_DRAM_OE		\
-	| DRAM_REFRESH_16	\
-	| EN_DRAM_REFRESH	\
-	| EN_FAST_RAS_READ	\
-	| EN_RD_AHEAD_FIFO	\
-	| EN_FAST_RD_AHEAD_WR	\
-	)
-
-#define FBIINIT3_DEFAULT 	\
-	( DISABLE_TEXTURE )
-
-#define FBIINIT4_DEFAULT	\
-	(			\
-	  FAST_PCI_READS	\
-/*	  SLOW_PCI_READS*/	\
-	| LFB_READ_AHEAD	\
-	)
-/* Careful with this one : writing back the data just read will trash the DAC
-   reading some fields give logic value on pins, but setting this field will
-   set the source signal driving the pin. conclusion : just use the default
-   as a base before writing back .
-*/
-#define FBIINIT6_DEFAULT	(0x0)
+void __Dump_regs(struct sstfb_info *);
+#define Dump_regs __Dump_regs(sst_info)  //XXX
 
 /********/
 
-int num_sst; /* =0*/		/* number of initialized boards */
-
 /* initialized by setup */
 static int inverse; /* =0 */	/* invert colormap */
 static int vgapass; /* =0 */	/* enable Vga passthrough cable */
@@ -185,31 +129,17 @@
 static int clipping = 1;	/* use clipping (slower, safer) */
 static int gfxclk;  /* =0 */	/* force FBI freq in Mhz . Dangerous */
 static int slowpci; /* =0 */	/* slow PCI settings */
-static int dev = -1;		/* specify device (0..n) */
-static char * mode_option ;
+static int dev = -2;		/* specify device (0..n) -2=all -1=none*/
 
+static char * mode_option ;
 
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
-union {
-#  ifdef FBCON_HAS_CFB16
-	u16 cfb16[16];
-#  endif
-#ifdef EN_24_32_BPP
-#  if defined (FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
-	u32 cfb32[16];
-#  endif
-#endif
-	} fbcon_cmap;
-#endif
-static struct { u_int red, green, blue, transp; } palette[16];
-static struct sstfb_info fb_info;
-static struct display disp;
 
 /********/
 
-/* Interface to ze oueurld  */
 int sstfb_init(void);
 int sstfb_setup(char *options);
+static int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id);
+static void __devexit sstfb_remove(struct pci_dev *pdev);
 
 
 /* Framebuffer API */
@@ -223,8 +153,8 @@
                          int con, struct fb_info *info);
 static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc,
                           int con, struct fb_info *info);
-static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                           u_int transp, struct fb_info *info);
+static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc,
+                          int con, struct fb_info *info);
 static int sstfb_pan_display(struct fb_var_screeninfo *var,
                              int con, struct fb_info *info);
 static int sstfb_ioctl(struct inode *inode, struct file *file,
@@ -234,10 +164,14 @@
 /* Interface to the low level console driver */
 static int sstfbcon_switch(int con, struct fb_info *info);
 static int sstfbcon_updatevar(int con, struct fb_info *info);
+static void sstfbcon_blank(int blank, struct fb_info *info);
 
 /* Internal routines */
+static void sstfb_install_cmap(int con, struct fb_info *info);
 static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
                            u_int *transp, struct fb_info *info);
+static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                           u_int transp, struct fb_info *info);
 
 static int sstfb_set_par(const struct sstfb_par *par,
                           struct sstfb_info *sst_info);
@@ -255,21 +189,20 @@
 #endif
 
 /* Low level routines */
-static int sst_get_memsize(u_long *memsize);
-static int sst_wait_idle(void);
-static int sst_detect_dactype(void);
-static int sst_detect_att(void);
-static int sst_detect_ti(void);
-static int sst_detect_ics(void);
+static int sst_get_memsize(struct sstfb_info *sst_info, u_long *memsize);
+static int __sst_wait_idle(u_long vbase);
+#define sst_wait_idle()	 __sst_wait_idle(sst_info->mmio.vbase)
+static int sst_detect_dactype(struct sstfb_info *sst_info);
+static int sst_detect_att(struct sstfb_info *sst_info);
+static int sst_detect_ti(struct sstfb_info *sst_info);
+static int sst_detect_ics(struct sstfb_info *sst_info);
 static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t);
-static int sst_set_pll_att_ti(const struct pll_timing *t, const int clock);
-static int sst_set_pll_ics(const struct pll_timing *t, const int clock);
-static void sst_set_vidmod_att_ti(const int bpp);
-static void sst_set_vidmod_ics(const int bpp);
-static int sst_init(void);
-#ifdef MODULE
-static void sst_shutdown(void);
-#endif
+static int sst_set_pll_att_ti(struct sstfb_info *sst_info, const struct pll_timing *t, const int clock);
+static int sst_set_pll_ics(struct sstfb_info *sst_info, const struct pll_timing *t, const int clock);
+static void sst_set_vidmod_att_ti(struct sstfb_info *sst_info, const int bpp);
+static void sst_set_vidmod_ics(struct sstfb_info *sst_info, const int bpp);
+static int sst_init(struct sstfb_info *sst_info);
+static void sst_shutdown(struct sstfb_info *sst_info);
 
 static struct fb_ops sstfb_ops = {
 	owner : THIS_MODULE,
@@ -279,15 +212,42 @@
 	fb_get_var:	sstfb_get_var,
 	fb_set_var:	sstfb_set_var,
 	fb_get_cmap:	sstfb_get_cmap,
-	fb_set_cmap:	gen_set_cmap,
-	fb_setcolreg:	sstfb_setcolreg,
+	fb_set_cmap:	sstfb_set_cmap,
 	fb_pan_display:	sstfb_pan_display,
 	fb_ioctl:	sstfb_ioctl,
 };
 
-#ifndef DEFAULT_MODE
-#  define DEFAULT_MODE 0
-#endif
+enum {
+	ID_VOODOO1 = 0,
+	ID_VOODOO2 = 1,
+};
+
+#define IS_VOODOO2(info) ((info)->type == ID_VOODOO2 )
+
+static struct sst_spec voodoo_spec[] __devinitdata = {
+	{ name : "Voodoo Graphics",
+	default_gfx_clock : 50000,
+	max_gfxclk : 60, },
+	{ name : "Voodoo2",
+	default_gfx_clock : 75000,
+	max_gfxclk : 85, },
+};
+
+static struct pci_device_id sstfb_id_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO1 },
+	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO2 },
+	{ 0 },
+};
+
+static struct pci_driver sstfb_driver = {
+	name:		"sstfb",
+	id_table:	sstfb_id_tbl,
+	probe:          sstfb_probe,
+	remove:		__devexit_p(sstfb_remove),
+};
+
 static struct fb_var_screeninfo	sstfb_default =
 #if ( DEFAULT_MODE == 0 )
     { /* 800x600@60, 16 bpp .borowed from glide/sst1/include/sst1init.h */
@@ -322,7 +282,7 @@
     0, FB_VMODE_NONINTERLACED };
 #endif
 
-static struct dac_switch dacs[] = {
+static struct dac_switch dacs[] __devinitdata = {
 	{	name:		"TI TVP3409",
 		detect:		sst_detect_ti,
 		set_pll:	sst_set_pll_att_ti,
@@ -338,17 +298,6 @@
 		set_vidmod:	sst_set_vidmod_ics },
 };
 
-static struct sst_spec voodoo1_spec = {
-	name : "Voodoo Graphics",
-	default_gfx_clock : 50000,
-	max_gfxclk : 60,
-};
-
-static struct sst_spec voodoo2_spec = {
-	name : "Voodoo2",
-	default_gfx_clock : 75000,
-	max_gfxclk : 85,
-};
 
 /*
  *
@@ -380,8 +329,8 @@
 }
 #endif /* (SST_DEBUG_VAR > 0) */
 
+#if (SST_DEBUG_REG > 0)
 static void sst_dbg_print_read_reg (u32 reg, u32 val) {
-#if (SST_DEBUG_REG > 0) /* i need the init registers :) */
 	char * regname =NULL;
 	switch (reg) {
 	case FBIINIT0: regname="FbiInit0"; break;
@@ -389,17 +338,16 @@
 	case FBIINIT2: regname="FbiInit2"; break;
 	case FBIINIT3: regname="FbiInit3"; break;
 	case FBIINIT4: regname="FbiInit4"; break;
+	case FBIINIT5: regname="FbiInit5"; break;
 	case FBIINIT6: regname="FbiInit6"; break;
 	}
 	if (regname == NULL)
 		r_ddprintk("sst_read(%#x): %#x\n", reg, val);
 	else
 		r_dprintk(" sst_read(%s): %#x\n", regname, val);
-#endif /*  (SST_DEBUG_REG > 0) */
 }
 
 static void sst_dbg_print_write_reg (u32 reg, u32 val) {
-#if (SST_DEBUG_REG > 0) /* i need the init registers :) */
 	char * regname = NULL;
 
 	switch (reg) {
@@ -408,157 +356,199 @@
 	case FBIINIT2: regname="FbiInit2"; break;
 	case FBIINIT3: regname="FbiInit3"; break;
 	case FBIINIT4: regname="FbiInit4"; break;
+	case FBIINIT5: regname="FbiInit5"; break;
 	case FBIINIT6: regname="FbiInit6"; break;
 	}
 	if (regname == NULL)
 		r_ddprintk("sst_write(%#x, %#x)\n", reg, val);
 	else
 		r_dprintk(" sst_write(%s, %#x)\n", regname, val);
-#endif /*  (SST_DEBUG_REG > 0) */
 }
+#else /*  (SST_DEBUG_REG > 0) */
+#  define sst_dbg_print_read_reg(reg, val)	do {}while(0)
+#  define sst_dbg_print_write_reg(reg, val)	do {}while(0)
+#endif /*  (SST_DEBUG_REG > 0) */
 
 /* register access */
-static inline u32 sst_read(u32 reg)
+#define sst_read(reg)		__sst_read(sst_info->mmio.vbase, reg)
+#define sst_write(reg,val)	__sst_write(sst_info->mmio.vbase, reg, val)
+#define sst_set_bits(reg,val)	__sst_set_bits(sst_info->mmio.vbase, reg, val)
+#define sst_unset_bits(reg,val)	__sst_unset_bits(sst_info->mmio.vbase, reg, val)
+#define sst_dac_read(reg)	__sst_dac_read(sst_info->mmio.vbase, reg)
+#define sst_dac_write(reg,val)	__sst_dac_write(sst_info->mmio.vbase, reg, val)
+#define dac_i_read(reg)		__dac_i_read(sst_info->mmio.vbase, reg)
+#define dac_i_write(reg,val)	__dac_i_write(sst_info->mmio.vbase, reg, val)
+
+static inline u32 __sst_read(u_long vbase, u32 reg)
 {
 	u32 ret;
 
-	ret = readl(fb_info.mmio.vbase + reg);
+	ret = readl(vbase + reg);
 	sst_dbg_print_read_reg(reg, ret);
 	return ret;
 }
 
-static inline void sst_write(u32 reg, u32 val)
+static inline void __sst_write(u_long vbase, u32 reg, u32 val)
 {
 	sst_dbg_print_write_reg(reg, val);
-	writel(val, fb_info.mmio.vbase + reg);
+	writel(val, vbase + reg);
 }
 
-static inline void sst_set_bits(u32 reg, u32 val)
+static inline void __sst_set_bits(u_long vbase, u32 reg, u32 val)
 {
 	r_dprintk("sst_set_bits(%#x, %#x)\n", reg, val);
-	sst_write(reg, sst_read(reg) | val);
+	__sst_write(vbase, reg, __sst_read(vbase, reg) | val);
 }
 
-static inline void sst_unset_bits(u32 reg, u32 val)
+static inline void __sst_unset_bits(u_long vbase, u32 reg, u32 val)
 {
 	r_dprintk("sst_unset_bits(%#x, %#x)\n", reg, val);
-	sst_write(reg, sst_read(reg) & ~val);
+	__sst_write(vbase, reg, __sst_read(vbase, reg) & ~val);
 }
 
 /* dac access */
 /* dac_read should be remaped to FbiInit2 (via the pci reg init_enable) */
-static u8 sst_dac_read(u8 reg)
+static u8 __sst_dac_read(u_long vbase, u8 reg)
 {
 	u8 ret;
 
 #ifdef SST_DEBUG
 	if ((reg & 0x07) != reg) {
-		dprintk("bug line %d: register adress '%d' is to high\n",
+		dprintk("bug line %d: register adress '%d' is too high\n",
 		         __LINE__,reg);
 	}
 #endif
 	reg &= 0x07;
-	sst_write(DAC_DATA, ((u32)reg << 8) | DAC_READ_CMD );
-	sst_wait_idle();
+	__sst_write(vbase, DAC_DATA, ((u32)reg << 8) | DAC_READ_CMD );
+	__sst_wait_idle(vbase);
 	/*udelay(10);*/
-	ret=(sst_read(DAC_READ) & 0xff);
+	ret=(__sst_read(vbase, DAC_READ) & 0xff);
 	r_dprintk("sst_dac_read(%#x): %#x\n", reg, ret);
 	return (u8)ret;
 }
 
-static void sst_dac_write(u8 reg, u8 val)
+static void __sst_dac_write(u_long vbase, u8 reg, u8 val)
 {
 	r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val);
 #ifdef SST_DEBUG
 	if ((reg & 0x07) != reg)
-		dprintk("bug line %d: register adress '%d' is to high\n",
+		dprintk("bug line %d: register adress '%d' is too high\n",
 		         __LINE__,reg);
 #endif
 	reg &= 0x07;
-	sst_write(DAC_DATA,(((u32)reg << 8)) | (u32)val);
+	__sst_write(vbase, DAC_DATA,(((u32)reg << 8)) | (u32)val);
 }
 
 /* indexed access to ti/att dacs */
-static inline u32 dac_i_read(u8 reg)
+static u32 __dac_i_read(u_long vbase, u8 reg)
 {
 	u32 ret;
 
-	sst_dac_write(DACREG_ADDR_I, reg);
-	ret = sst_dac_read(DACREG_DATA_I);
+	__sst_dac_write(vbase, DACREG_ADDR_I, reg);
+	ret = __sst_dac_read(vbase, DACREG_DATA_I);
 	r_dprintk("sst_dac_read_i(%#x): %#x\n", reg, ret);
 	return ret;
 }
-
-static inline void dac_i_write(u8 reg,u8 val)
+static void __dac_i_write(u_long vbase, u8 reg,u8 val)
 {
 	r_dprintk("sst_dac_write_i(%#x, %#x)\n", reg, val);
-	sst_dac_write(DACREG_ADDR_I, reg);
-	sst_dac_write(DACREG_DATA_I, val);
+	__sst_dac_write(vbase, DACREG_ADDR_I, reg);
+	__sst_dac_write(vbase, DACREG_DATA_I, val);
+}
+
+/*
+ *
+ *  Internal routines
+ *
+ */
+
+static void sstfb_install_cmap(int con, struct fb_info *info)
+{
+#define sst_info	((struct sstfb_info *) info)
+	f_dprintk("sstfb_install_cmap(con: %d)\n",con);
+	f_ddprintk("currcon: %d\n", sst_info->currcon);
+	if (con != sst_info->currcon)
+		return;
+	if (fb_display[con].cmap.len)
+		fb_set_cmap(&fb_display[con].cmap, 1, sstfb_setcolreg, info);
+	else
+		fb_set_cmap(
+			fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+			1, sstfb_setcolreg, info);
+#undef sst_info
 }
 
 static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
                            u_int *transp, struct fb_info *info)
 {
-	f_ddprintk("sstfb_getcolreg\n");
+#define sst_info	((struct sstfb_info *) info)
+	f_dddprintk("sstfb_getcolreg\n");
 	if (regno >= 16) return 1;
 
-	*red    = palette[regno].red;
-	*green  = palette[regno].green;
-	*blue   = palette[regno].blue;
-	*transp = palette[regno].transp;
+	*red    = sst_info->palette[regno].red;
+	*green  = sst_info->palette[regno].green;
+	*blue   = sst_info->palette[regno].blue;
+	*transp = sst_info->palette[regno].transp;
 	f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",
 	            regno,*red, *green, *blue, *transp);
 	return 0;
+#undef sst_info
 }
 
 static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                            u_int transp, struct fb_info *info)
 {
+#define sst_info	((struct sstfb_info *) info)
 	u32 col;
+	struct display * disp;
 
-	f_ddprintk("sstfb_setcolreg\n");
+	f_dddprintk("sstfb_setcolreg\n");
 	f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",
 	            regno, red, green, blue, transp);
 	if (regno >= 16) return 1;
-	palette[regno].red   = red;
-	palette[regno].green = green;
-	palette[regno].blue  = blue;
-
-	red    >>= (16 - disp.var.red.length);
-	green  >>= (16 - disp.var.green.length);
-	blue   >>= (16 - disp.var.blue.length);
-	transp >>= (16 - disp.var.transp.length);
-	col = (red << disp.var.red.offset)
-		| (green << disp.var.green.offset)
-		| (blue  << disp.var.blue.offset)
-		| (transp << disp.var.transp.offset);
 
-	switch(disp.var.bits_per_pixel) {
+	sst_info->palette[regno].red   = red;
+	sst_info->palette[regno].green = green;
+	sst_info->palette[regno].blue  = blue;
+	sst_info->palette[regno].transp= transp;
+
+	disp=&sst_info->disp;
+	red    >>= (16 - disp->var.red.length);
+	green  >>= (16 - disp->var.green.length);
+	blue   >>= (16 - disp->var.blue.length);
+	transp >>= (16 - disp->var.transp.length);
+	col = (red << disp->var.red.offset)
+	    | (green << disp->var.green.offset)
+	    | (blue  << disp->var.blue.offset)
+	    | (transp << disp->var.transp.offset);
+
+	switch(disp->var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB16
 	case 16:
-		fbcon_cmap.cfb16[regno]=(u16)col;
+		sst_info->fbcon_cmap.cfb16[regno]=(u16)col;
 		break;
 #endif
 #ifdef EN_24_32_BPP
 #ifdef FBCON_HAS_CFB24
 	case 24:
-		fbcon_cmap.cfb32[regno]=col;
+		sst_info->fbcon_cmap.cfb32[regno]=col;
 		break;
 #endif
 #ifdef FBCON_HAS_CFB32
 	case 32:
-		fbcon_cmap.cfb32[regno]=col;
+		sst_info->fbcon_cmap.cfb32[regno]=col;
 		break;
 #endif
 #endif
 	default:
 		eprintk("bug line %d: bad depth '%u'\n",__LINE__,
-			disp.var.bits_per_pixel);
+			disp->var.bits_per_pixel);
 		break;
 	}
 	f_dddprintk("bpp: %d . encoded color: %#x\n",
-	            disp.var.bits_per_pixel, col);
+	            disp->var.bits_per_pixel, col);
 	return 0;
+#undef sst_info
 }
 
 /* set par according to var ( checks var ) */
@@ -570,17 +560,7 @@
 
 	f_dprintk("sstfb_decode_var\n");
 	/* Check var validity */
-	if ((var->xres > 1024) || (!var->xres) || (!var->xres)) {
-		eprintk ("Unsupported resolution %dx%d\n",
-		         var->xres, var->yres);
-		return -EINVAL;
-	}
-	if ((var->vmode & FB_VMODE_MASK) !=  FB_VMODE_NONINTERLACED) {
-		eprintk("Interlace non supported %#x\n",
-			(var->vmode & FB_VMODE_MASK));
-		return -EINVAL;
-	}
-
+	par->valid=0;
 
 	memset(par, 0, sizeof(par));
 	par->xDim       = var->xres;
@@ -592,6 +572,24 @@
 	par->vSyncOff   = var->yres + var->lower_margin + var->upper_margin;
 	par->vBackPorch = var->upper_margin;
 
+	if(sst_calc_pll (PS2KHZ(var->pixclock), &par->freq, &par->pll)) {
+		eprintk("Pixclock %d out of range\n", var->pixclock);
+		return -EINVAL; //XXX
+	}
+
+	par->sync=var->sync & (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT);
+
+	par->vmode=var->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE); 
+	/* in laced mode, vBackPorch should be even. odd -> funky display */
+	if (par->vmode & FB_VMODE_INTERLACED)
+		par->vBackPorch += (par->vBackPorch % 2);
+	if (par->vmode & FB_VMODE_DOUBLE) {
+		par->vBackPorch <<= 1;
+		par->yDim <<=1;
+		par->vSyncOn <<=1;
+		par->vSyncOff <<=1;
+	}
+
 	switch (var->bits_per_pixel) {
 	case 0 ... 16 :
 		par->bpp = 16;
@@ -610,7 +608,7 @@
 		break;
 	}
 
-	if (sst_info->is_voodoo2) {
+	if (IS_VOODOO2(sst_info)) {
 		/* voodoo2 has 32 pixel wide tiles , BUT stange things
 		 happen with odd number of tiles */
 		par->tiles_in_X= (par->xDim + 63 ) / 64 * 2;
@@ -619,23 +617,68 @@
 		par->tiles_in_X= (par->xDim + 63 ) / 64;
 	}
 
-	/*
-	 *  mem check
-	 */
+	/* validity tests */
+	if((par->xDim <= 1) || (par->yDim <= 0 )
+	   || (par->hSyncOn <= 1)
+	   || (par->hSyncOff <= 1)
+	   || (par->hBackPorch <= 2)
+	   || (par->vSyncOn <= 0)
+	   || (par->vSyncOff <= 0)
+	   || (par->vBackPorch <= 0)
+	   || (par->tiles_in_X <= 0)) {
+		return -EINVAL;
+	}
+	if (IS_VOODOO2(sst_info)) {
+		/* Voodoo 2 limits */
+		if(((par->xDim-1) >= POW2(11)) || (par->yDim >= POW2(11))) {
+			eprintk ("Unsupported resolution %dx%d\n",
+			         var->xres, var->yres);
+			return -EINVAL;
+		}
+		if (((par->hSyncOn-1) >= POW2(9))
+		   || ((par->hSyncOff-1) >= POW2(11))
+		   || ((par->hBackPorch-2) >= POW2(9))
+		   || (par->vSyncOn >= POW2(13))
+		   || (par->vSyncOff >= POW2(13))
+		   || (par->vBackPorch >= POW2(9))
+		   || (par->tiles_in_X >= POW2(6))) {
+			eprintk ("Unsupported Timing\n");
+			return -EINVAL;
+		}
+	} else {
+		/* Voodoo limits */
+		if (par->vmode) {
+			eprintk("Interlace/Doublescan not supported %#x\n",
+				par->vmode);
+			return -EINVAL;
+		}
+		if(((par->xDim-1) >= POW2(10)) || (par->yDim >= POW2(10))) {
+			eprintk ("Unsupported resolution %dx%d\n",
+			         var->xres, var->yres);
+			return -EINVAL;
+		}
+		if (((par->hSyncOn-1) >= POW2(8))
+		   || ((par->hSyncOff-1) >= POW2(10))
+		   || ((par->hBackPorch-2) >= POW2(8))
+		   || (par->vSyncOn >= POW2(12))
+		   || (par->vSyncOff >= POW2(12))
+		   || (par->vBackPorch >= POW2(8))
+		   || (par->tiles_in_X >= POW2(4))) {
+			eprintk ("Unsupported Timings\n");
+			return -EINVAL;
+		}
+	}
+
 	/* it seems that the fbi uses tiles of 64x16 pixels to "map" the mem*/
 	/* FIXME: i don't like this... looks wrong*/
-	real_length = par->tiles_in_X  * (sst_info->is_voodoo2 ? 32 : 64 )
+	real_length = par->tiles_in_X  * (IS_VOODOO2(sst_info) ? 32 : 64 )
 	              * ((par->bpp == 16) ? 2 : 4);
-/*shoud this function change var ? for instance with yvirt > yres  ?*/
 
-	if ((real_length * var->yres) > fb_info.video.len) {
+	if ((real_length * var->yres) > sst_info->video.len) {
 		eprintk ("Not enough video memory\n");
 		return -ENOMEM;
 	}
-
-	par->freq = PS2KHZ(var->pixclock);
-	
-	/* TODO add checks for timings */
+	par->valid=1;
 	return 0;
 }
 
@@ -651,7 +694,7 @@
 	var->xres_virtual   = par->xDim;
 	var->yres_virtual   = par->yDim;
 	var->bits_per_pixel = par->bpp;
-	/* {x|y}offset = 0 ; sync=0 */
+	/* {x|y}offset = 0 */
 	var->height         = -1;
 	var->width          = -1;
 	var->pixclock       = KHZ2PS(par->freq);
@@ -661,7 +704,15 @@
 	var->lower_margin   = par->vSyncOff - par->yDim - par->vBackPorch;
 	var->hsync_len      = par->hSyncOn;
 	var->vsync_len      = par->vSyncOn;
-	var->vmode          = FB_VMODE_NONINTERLACED;
+	var->sync           = par->sync;
+	var->vmode          = par->vmode;
+	if (var->vmode & FB_VMODE_DOUBLE) {
+		var->yres           >>=1;
+		var->yres_virtual   >>=1;
+		var->vsync_len      >>=1;
+		var->upper_margin   >>=1;
+		var->lower_margin   >>=1;
+	}
 
 	/*
 	 * correct the color bit fields
@@ -708,14 +759,12 @@
 static int sstfb_open(struct fb_info *info, int user)
 {
 	f_dprintk("sstfb_open(user: %d)\n",user);
-	MOD_INC_USE_COUNT;
 	return 0;
 }
 
 static int sstfb_release(struct fb_info *info, int user)
 {
 	f_dprintk("sstfb_release(user: %d)\n",user);
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -728,7 +777,7 @@
 
 	f_dprintk("sstfb_get_fix(con: %d)\n",con);
 	if (con == -1)
-		var = &sstfb_default;
+		sstfb_encode_var(var, &sst_info->current_par, sst_info);
 	else
 		var = &fb_display[con].var;
 
@@ -751,21 +800,23 @@
 static int sstfb_get_var(struct fb_var_screeninfo *var,
                          int con, struct fb_info *info)
 {
+#define sst_info	((struct sstfb_info *) info)
 	f_dprintk("sstfb_get_var(con: %d)\n",con);
 	if (con == -1)
-		*var = sstfb_default;
+		sstfb_encode_var(var, &sst_info->current_par, sst_info);
 	else
 		*var = fb_display[con].var;
 	print_var(var, "var");
 	return 0;
+#undef sst_info
  }
 
 static int sstfb_set_var(struct fb_var_screeninfo *var,
                          int con, struct fb_info *info)
 {
-#define sst_info	((struct sstfb_info *) info)	
+#define sst_info	((struct sstfb_info *) info)
 
-	struct sstfb_par par;	
+	struct sstfb_par par;
 	struct display *display;
 	int err;
 	int old_bpp,old_xres,old_yres;
@@ -776,15 +827,14 @@
 		 var->xres,var->yres,var->xres_virtual,var->yres_virtual,
 		 var->bits_per_pixel,var->activate);
 	if (con < 0)
-		display = &disp;
+		display = &sst_info->disp;
 	else
 		display = &fb_display[con];
 
-	err = sstfb_decode_var(var, &par, sst_info);
-	if (err)
+	if ((err = sstfb_decode_var(var, &par, sst_info)))
 		return err;
 	sstfb_encode_var (var, &par, sst_info);
-	
+
 	switch (var->activate & FB_ACTIVATE_MASK) {
 		case FB_ACTIVATE_TEST:
 			return 0;
@@ -802,7 +852,7 @@
 	if ((old_xres != var->xres) || (old_yres != var->yres)
 	    || (old_bpp != var->bits_per_pixel)) {
 		/* 2-3  lignes redondantes avec get_fix */
-		info->screen_base = (char *) sst_info->video.vbase;
+		display->screen_base = (char *) sst_info->video.vbase;
 		display->visual = FB_VISUAL_TRUECOLOR;
 		display->type = FB_TYPE_PACKED_PIXELS;
 		display->type_aux = 0;
@@ -814,7 +864,7 @@
 #ifdef FBCON_HAS_CFB16
 		case 16:
 			display->dispsw = &fbcon_cfb16;
-			display->dispsw_data = fbcon_cmap.cfb16;
+			display->dispsw_data = sst_info->fbcon_cmap.cfb16;
 			break;
 #endif
 #ifdef EN_24_32_BPP
@@ -822,7 +872,7 @@
 		case 24: /*24bpp non packed <=> 32 bpp */
 		case 32:
 			display->dispsw = &fbcon_cfb32;
-			display->dispsw_data = fbcon_cmap.cfb32;
+			display->dispsw_data = sst_info->fbcon_cmap.cfb32;
 			break;
 #endif
 #endif
@@ -840,7 +890,7 @@
 		}
 	}
 
-	if ((con <0) || (con==info->currcon)) {
+	if ((con == -1) || (con==sst_info->currcon)) {
 		sstfb_set_par (&par, sst_info);
 	}
 	print_var(var, "var");
@@ -849,22 +899,48 @@
 	if (old_bpp != var->bits_per_pixel) {
 	    if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
 		return err;
-	    do_install_cmap(con, info);
+	    sstfb_install_cmap(con, info);
 	}
 
 	return 0;
 #undef sst_info
 }
 
+
+static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc,
+                          int con, struct fb_info *info)
+{
+#define sst_info	((struct sstfb_info *) info)
+	struct display *d = (con<0) ? info->disp : fb_display + con;
+
+	f_dprintk("sstfb_set_cmap\n");
+	f_ddprintk("con: %d, currcon: %d, d->cmap.len %d\n",
+		 con, sst_info->currcon, d->cmap.len);
+
+	if (d->cmap.len != 16 ) {	/* or test if cmap.len == 0 ? */
+		int err;
+		err = fb_alloc_cmap(&d->cmap, 16, 0); /* cmap size=16 */
+		if (err) return err;
+	}
+	if (con == sst_info->currcon) {
+		return fb_set_cmap(cmap, kspc, sstfb_setcolreg, info);
+	} else {
+		fb_copy_cmap(cmap, &d->cmap, kspc ? 0 : 1);
+	}
+	return 0;
+#undef sst_info
+}
+
 static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc,
                           int con, struct fb_info *info)
 {
+#define sst_info	((struct sstfb_info *) info)
 	f_dprintk("sstfb_get_cmap\n");
 	f_ddprintk("con %d, curcon %d, cmap.len %d\n",
-		 con, info->currcon, fb_display[con].cmap.len);
+		 con, sst_info->currcon, fb_display[con].cmap.len);
 
 	/* FIXME: check if con = -1 ? cf sstfb_set_cmap...  */
-	if (con == info->currcon)
+	if (con == sst_info->currcon)
 		return fb_get_cmap(cmap, kspc, sstfb_getcolreg, info);
 	else if (fb_display[con].cmap.len)
 		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
@@ -873,6 +949,7 @@
 			fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 			cmap, kspc ? 0 : 2);
 	return 0;
+#undef sst_info
 }
 
 /* TODO */
@@ -887,7 +964,7 @@
                        u_int cmd, u_long arg, int con,
                        struct fb_info *info)
 {
-#define sst_info	((struct sstfb_info *) info)	
+#define sst_info	((struct sstfb_info *) info)
 #if (SST_DEBUG_IOCTL >0)
 	int i;
 	u_long p;
@@ -934,10 +1011,10 @@
 		return 0;
 	case _IO('F', 0xde):		/* 0x46de */
 		f_dprintk("test color display\n");
-		f_ddprintk("currcon: %d, bpp %d\n",
-			  info->currcon, fb_display[currcon].var.bits_per_pixel);
+		f_ddprintk("currcon: %d, bpp %d\n", sst_info->currcon,
+			  sst_info->current_par.bpp);
 		memset_io(sst_info->video.vbase, 0, sst_info->video.len);
-	switch (fb_display[info->currcon].var.bits_per_pixel) {
+	switch (sst_info->current_par.bpp) {
 /* FIXME broken : if we call this ioctl from a tty not bound to the fb, we use its depth and not the current one ... */
 	       	case 16:
 			sstfb_test16(sst_info);
@@ -950,9 +1027,12 @@
 #  endif
 		default:
 			dprintk("bug line %d: bad depth '%u'\n", __LINE__,
-			        fb_display[info->currcon].var.bits_per_pixel);
+			        sst_info->current_par.bpp);
 			}
 		return 0;
+	case _IO('F', 0xdf):		/* 0x46db */
+		Dump_regs;
+		return 0;
 	}
 #endif /* (SST_DEBUG_IOCTL >0) */
 	return -EINVAL;
@@ -966,9 +1046,9 @@
 
 /* get lfb size */
 
-static int sst_get_memsize(u_long *memsize)
+static int __devinit sst_get_memsize(struct sstfb_info *sst_info, u_long *memsize)
 {
-	u32 fbbase_virt = fb_info.video.vbase;
+	u_long fbbase_virt = sst_info->video.vbase;
 	f_dprintk("sst_get_memsize\n");
 
 	/* force memsize */
@@ -1011,13 +1091,13 @@
  * in a row a "idle" answer to our requests
  */
 
-static int sst_wait_idle(void)
+static int __sst_wait_idle(u_long vbase)
 {
 	int count = 0;
 
 	f_ddprintk("sst_wait_idle\n");
 	while(1) {
-		if (sst_read(STATUS) & STATUS_FBI_BUSY) {
+		if (__sst_read(vbase, STATUS) & STATUS_FBI_BUSY) {
 			f_dddprintk("status: busy\n");
 /* FIXME basicaly, this is a busy wait. maybe not that good. oh well; this is a small loop after all ...*/
 			count = 0;
@@ -1026,6 +1106,7 @@
 			f_dddprintk("status: idle(%d)\n", count);
 		}
 		if (count >= 5) return 1;
+//XXX  do something to avoid hanging the machine if the voodoo is out
 	}
 }
 
@@ -1035,25 +1116,25 @@
  * dram refresh disabled, FbiInit remaped.
  * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ...
  */
-static int __init sst_detect_dactype(void)
+static int __devinit sst_detect_dactype(struct sstfb_info * sst_info)
 {
 	int ret=0,i;
 	f_dprintk("sst_detect_dactype\n");
 	for (i=0; i< sizeof(dacs)/sizeof(dacs[0]) ; i++) {
-		ret = dacs[i].detect();
+		ret = dacs[i].detect(sst_info);
 		if (ret) break;
 	}
 	if (!ret)
 		return 0;
 	f_dprintk("found %s\n", dacs[i].name);
-	fb_info.dac_sw=&dacs[i];
+	sst_info->dac_sw=dacs[i];
 	return 1;
 }
 
 /* fbi should be idle, and fifo emty and mem disabled */
 /* supposed to detect AT&T ATT20C409 and Ti TVP3409 ramdacs */
 
-static int __init (sst_detect_att(void))
+static int __devinit sst_detect_att(struct sstfb_info * sst_info)
 {
 	int i, mir, dir;
 
@@ -1078,7 +1159,7 @@
 	return 0;
 }
 
-static int __init (sst_detect_ti(void))
+static int __devinit sst_detect_ti(struct sstfb_info * sst_info)
 {
 	int i, mir, dir;
 
@@ -1114,7 +1195,7 @@
  * touched...
  * is it realy safe ? how can i reset this ramdac ? geee...
  */
-static int __init sst_detect_ics(void)
+static int __devinit sst_detect_ics(struct sstfb_info * sst_info)
 {
 	int i;
 	int m_clk0_1, m_clk0_7, m_clk1_b;
@@ -1200,7 +1281,7 @@
  * see detect_dac
  */
 
-static int sst_set_pll_att_ti(const struct pll_timing *t, const int clock)
+static int sst_set_pll_att_ti(struct sstfb_info * sst_info, const struct pll_timing *t, const int clock)
 {
 	u8 cr0, cc;
 	f_dprintk("sst_set_pll_att_ti\n");
@@ -1254,7 +1335,7 @@
 	return 1;
 }
 
-static int sst_set_pll_ics(const struct pll_timing *t, const int clock)
+static int sst_set_pll_ics(struct sstfb_info * sst_info, const struct pll_timing *t, const int clock)
 {
 	u8 pll_ctrl;
 
@@ -1294,11 +1375,9 @@
 
 static int sstfb_set_par(const struct sstfb_par * par, struct sstfb_info * sst_info)
 {
-	u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit6=0;
+	u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0;
 	int ntiles;
-	struct pll_timing pll;
-	int fout;
-	struct pci_dev  * sst_dev = sst_info->dev;
+	struct pci_dev * sst_dev = sst_info->dev;
 
 	f_dprintk("sst_set_par(%dx%d)\n", par->xDim, par->yDim);
 	f_ddprintk("hSyncOn hSyncOff vSyncOn vSyncOff\n");
@@ -1310,9 +1389,10 @@
 	           par->hBackPorch, par->vBackPorch,
 	           par->xDim, par->yDim, par->freq);
 
-
-	sst_calc_pll (par->freq, &fout, &pll);
-
+	if (!par->valid) {
+		BUG();
+		return -1;
+	}
 	sst_write(NOPCMD, 0);
 	sst_wait_idle();
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
@@ -1323,10 +1403,10 @@
 
 	/*sst_unset_bits (FBIINIT0, FBI_RESET); / reenable FBI ? */
 
-	sst_write(BACKPORCH,       par->vBackPorch << 16 | (par->hBackPorch-2));
-	sst_write(VIDEODIMENSIONS, (par->yDim - 1) << 16 | (par->xDim - 1));
-	sst_write(HSYNC,         (par->hSyncOff-1) << 16 | (par->hSyncOn-1));
-	sst_write(VSYNC,             par->vSyncOff << 16 | par->vSyncOn);
+	sst_write(BACKPORCH, par->vBackPorch << 16 | (par->hBackPorch - 2));
+	sst_write(VIDEODIMENSIONS, par->yDim << 16 | (par->xDim - 1));
+	sst_write(HSYNC, (par->hSyncOff - 1) << 16 | (par->hSyncOn - 1));
+	sst_write(VSYNC,       par->vSyncOff << 16 | par->vSyncOn);
 
 	fbiinit2=sst_read(FBIINIT2);
 	fbiinit3=sst_read(FBIINIT3);
@@ -1335,12 +1415,15 @@
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 	                       PCI_EN_INIT_WR | PCI_REMAP_DAC );
 
-	sst_info->dac_sw->set_vidmod(par->bpp);
+	sst_info->dac_sw.set_vidmod(sst_info, par->bpp);
+
 	/* set video clock */
-	sst_info->dac_sw->set_pll(&pll, VID_CLOCK);
+	sst_info->dac_sw.set_pll(sst_info, &par->pll, VID_CLOCK);
+
 	/* disable fbiinit2/3 remap */
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 	                       PCI_EN_INIT_WR);
+
 	/* restore fbiinit2/3 */
 	sst_write(FBIINIT2,fbiinit2);
 	sst_write(FBIINIT3,fbiinit3);
@@ -1363,7 +1446,7 @@
 */
 
 	ntiles = par->tiles_in_X;
-	if (sst_info->is_voodoo2) {
+	if (IS_VOODOO2(sst_info)) {
 		fbiinit1 |= ((ntiles & 0x20) >> 5) << TILES_IN_X_MSB_SHIFT
 		            | ((ntiles & 0x1e) >> 1) << TILES_IN_X_SHIFT ;
 /* as the only value of importance for us in fbiinit6 is tiles in X (lsb),
@@ -1393,8 +1476,19 @@
 		break;
 	}
 	sst_write(FBIINIT1, fbiinit1);
-	if (sst_info->is_voodoo2)
+	if (IS_VOODOO2(sst_info)) {
 		sst_write(FBIINIT6, fbiinit6);
+		fbiinit5=sst_read(FBIINIT5) & FBIINIT5_MASK ;
+		if (par->vmode & FB_VMODE_INTERLACED)
+			fbiinit5 |= INTERLACE;
+		if (par->vmode & FB_VMODE_DOUBLE )
+			fbiinit5 |= VDOUBLESCAN;
+		if (par->sync & FB_SYNC_HOR_HIGH_ACT)
+			fbiinit5 |= HSYNC_HIGH;
+		if (par->sync & FB_SYNC_VERT_HIGH_ACT)
+			fbiinit5 |= VSYNC_HIGH;
+		sst_write(FBIINIT5, fbiinit5);
+	}
 	sst_wait_idle();
 	sst_unset_bits(FBIINIT1, VIDEO_RESET);
 	sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
@@ -1437,9 +1531,6 @@
 		f_ddprintk("setting clipping dimensions 0..%d, 0..%d\n",
 		            par->xDim-1, par->yDim-1);
 
-/* warning the fields are 9bits wide on voodoo1 , 11 (or 10) on voodoo2,
-   make sure we check the values before playing with the registers.. */
-
 		sst_write(CLIP_LEFT_RIGHT, par->xDim );
 		sst_write(CLIP_LOWY_HIGHY, par->yDim );
 		sst_set_bits(FBZMODE, EN_CLIPPING | EN_RGB_WRITE);
@@ -1452,7 +1543,7 @@
 	return 1;
 }
 
-static void sst_set_vidmod_att_ti(const int bpp)
+static void sst_set_vidmod_att_ti(struct sstfb_info * sst_info, const int bpp)
 {
 	u8 cr0;
 
@@ -1488,7 +1579,7 @@
 	}
 }
 
-static void sst_set_vidmod_ics(const int bpp)
+static void sst_set_vidmod_ics(struct sstfb_info * sst_info, const int bpp)
 {
 	f_dprintk("sst_set_vidmod_ics(bpp: %d)\n", bpp);
 	switch(bpp) {
@@ -1507,14 +1598,18 @@
 	}
 }
 
-static int __init sst_init(void)
+static int __devinit sst_init(struct sstfb_info *sst_info)
 {
 	struct pll_timing gfx_timings;
+	struct sst_spec * spec;
+	struct pci_dev * sst_dev = sst_info->dev;
 	int Fout;
-	int dac_ok;
 	u32 fbiinit0, fbiinit1, fbiinit4;
-	struct pci_dev * sst_dev = fb_info.dev; /* or define a macro ?*/
 
+	dprintk("sst_init\n"); //XXX
+	Dump_regs; //XXX
+
+	spec = &voodoo_spec[sst_info->type];
 	f_dprintk("sst_init\n");
 	f_ddprintk(" fbiinit0   fbiinit1   fbiinit2   fbiinit3   fbiinit4  "
 	           " fbiinit6\n");
@@ -1547,25 +1642,24 @@
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 	                               PCI_EN_INIT_WR | PCI_REMAP_DAC );
 	/* detect dac type */
-	dac_ok = sst_detect_dactype();
-	if (!dac_ok) {
+	if (!sst_detect_dactype(sst_info)) {
 		eprintk("Unknown dac type\n");
+		//FIXME watch it : we are not in a safe state , bad bad bad .
 		return 0;
 	}
 
 	/* set graphic clock */
-	if (dac_ok) {
-		fb_info.gfx_clock = fb_info.spec->default_gfx_clock;
-		if ((gfxclk >10 ) && (gfxclk < fb_info.spec->max_gfxclk)) {
-			iprintk ("Using supplied graphic freq : %dMHz\n", gfxclk);
-			 fb_info.gfx_clock = gfxclk *1000;
-		} else if (gfxclk) {
-			wprintk ("You fool, %dMhz is way out of spec! Using default\n", gfxclk);
-		}
-
-		sst_calc_pll(fb_info.gfx_clock, &Fout, &gfx_timings);
-		fb_info.dac_sw->set_pll(&gfx_timings, GFX_CLOCK);
+	sst_info->gfx_clock = spec->default_gfx_clock;
+	if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) {
+		iprintk ("Using supplied graphic freq : %dMHz\n", gfxclk);
+		 sst_info->gfx_clock = gfxclk *1000;
+	} else if (gfxclk) {
+		wprintk ("You fool, %dMhz is way out of spec! Using default\n", gfxclk);
 	}
+
+	sst_calc_pll(sst_info->gfx_clock, &Fout, &gfx_timings);
+	sst_info->dac_sw.set_pll(sst_info, &gfx_timings, GFX_CLOCK);
+
 	/* disable fbiinit remap */
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 	                       PCI_EN_INIT_WR| PCI_EN_FIFO_WR );
@@ -1595,7 +1689,7 @@
 	sst_wait_idle();
 	sst_write(FBIINIT4, fbiinit4);
 	sst_wait_idle();
-	if (fb_info.is_voodoo2) {
+	if (IS_VOODOO2(sst_info)) {
 		sst_write(FBIINIT6, FBIINIT6_DEFAULT);
 		sst_wait_idle();
 	}
@@ -1603,16 +1697,14 @@
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR );
 	pci_write_config_dword(sst_dev, PCI_VCLK_ENABLE, 0);
 
-	return dac_ok;
+	return 1;
 }
 
-#ifdef MODULE
-
-static void  __exit sst_shutdown(void)
+static void  __devexit sst_shutdown(struct sstfb_info *sst_info)
 {
+	struct pci_dev * sst_dev = sst_info->dev;
 	struct pll_timing gfx_timings;
 	int Fout;
-	struct pci_dev * sst_dev = fb_info.dev;
 
 	f_dprintk("sst_shutdown\n");
 	/* reset video, gfx, fifo, disable dram + remap fbiinit2/3 */
@@ -1625,7 +1717,7 @@
 	                       PCI_EN_INIT_WR | PCI_REMAP_DAC );
 	/*set 20Mhz gfx clock */
 	sst_calc_pll(20000, &Fout, &gfx_timings);
-	fb_info.dac_sw->set_pll(&gfx_timings, GFX_CLOCK);
+	sst_info->dac_sw.set_pll(sst_info, &gfx_timings, GFX_CLOCK);
 	/* TODO maybe shutdown the dac, vrefresh and so on... */
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 	                       PCI_EN_INIT_WR);
@@ -1635,7 +1727,6 @@
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 0);
 
 }
-#endif /* MODULE */
 
 /*
  * Interface to the world
@@ -1683,116 +1774,172 @@
 	return 0;
 }
 
-int __init sstfb_init(void)
+int __devinit sstfb_init(void)
 {
-	struct pci_dev * pdev;
-	struct fb_var_screeninfo var;
-#define sst_dev	(fb_info.dev)
 	f_dprintk("sstfb_init\n");
 	dprintk("Compile date: "__DATE__" "__TIME__"\n");
+	return pci_module_init(&sstfb_driver);
+}
 
-	memset (&fb_info, 0, sizeof(fb_info));
-	pci_for_each_dev(pdev) {
-		if (pdev->vendor != PCI_VENDOR_ID_3DFX) continue;
-		if (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO) {
-			fb_info.is_voodoo2=0;
-			fb_info.spec=&voodoo1_spec;
-		}
-		else if (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO2) {
-			fb_info.is_voodoo2=1;
-			fb_info.spec=&voodoo2_spec;
-		}
-		else
-			continue;
-		if (dev > 0) {
-			dev--;
-			continue;
-		}
-		f_ddprintk("found device : %s\n", fb_info.spec->name);
-		fb_info.dev = pdev;
-		fb_info.mmio.base = sst_dev->resource[0].start;
-		pci_read_config_byte(sst_dev,
-		                     PCI_REVISION_ID, &fb_info.revision);
-
-		fb_info.mmio.vbase = (u32) ioremap_nocache(fb_info.mmio.base, 0x400000);
-		if (!fb_info.mmio.vbase) {
-			eprintk("cannot remap register area %#lx\n",
-			        fb_info.mmio.base);
-			return -ENXIO;
-		}
-		fb_info.video.base = fb_info.mmio.base+0x400000;
-		fb_info.video.vbase = (u32) ioremap_nocache(fb_info.video.base,
-					            0x400000);
-		if (!fb_info.video.vbase) {
-			eprintk("cannot remap framebuffer %#lx\n",
-			        fb_info.video.base);
-			iounmap((void*) fb_info.mmio.vbase);
-			return -ENXIO;
-		}
-		if(!sst_init()) {
-			eprintk("Init failed\n");
-			iounmap((void*)fb_info.mmio.vbase);
-			iounmap((void*)fb_info.video.vbase);
-			return -ENXIO;
-		}
-		sst_get_memsize(&fb_info.video.len);
-		fb_info.configured = 1;
-		strncpy(fb_info.info.modename, fb_info.spec->name, 16);
-
-		iprintk("%s with %s dac\n", fb_info.info.modename, fb_info.dac_sw->name);
-		iprintk("framebuffer at %#lx, mapped to %#lx,"
-		        " size %ldMb\n",
-		        fb_info.video.base, fb_info.video.vbase,
-		        fb_info.video.len >> 20);
-
-		f_ddprintk("revision: %d\n", fb_info.revision);
-		f_ddprintk("regbase_virt: %#lx\n", fb_info.mmio.vbase);
-		f_ddprintk("membase_phys: %#lx\n", fb_info.video.base);
-		f_ddprintk("fbbase_virt: %#lx\n", fb_info.video.vbase);
-
-		fb_info.info.node       = NODEV;
-		fb_info.info.flags      = FBINFO_FLAG_DEFAULT;
-		fb_info.info.fbops      = &sstfb_ops;
-		fb_info.info.disp       = &disp;
-		fb_info.info.currcon	= -1;
-		fb_info.info.changevar  = NULL;
-		fb_info.info.switch_con = &sstfbcon_switch;
-		fb_info.info.updatevar  = &sstfbcon_updatevar;
-		if ( !mode_option &&
-	             !fb_find_mode(&var, &fb_info.info, mode_option,
-		                   NULL, 0, NULL, 16)) {
-			var = sstfb_default;
-		}
-		if (sstfb_set_var(&var, -1, &fb_info.info)) {
+void __devexit sstfb_exit(void)
+{
+	f_dprintk("sstfb_exit\n");
+	pci_unregister_driver(&sstfb_driver);
+}
+
+#ifdef MODULE
+module_init(sstfb_init);
+module_exit(sstfb_exit);
+#endif
+
+static int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct fb_var_screeninfo var;
+	struct sstfb_info * sst_info;
+	struct sst_spec * spec;
+	int tmp,err;
+	f_dprintk("sstfb_probe\n");
+
+	/* dev >  0  the device is not the one asked for.   skip */
+	/* dev == 0  this is the device the user asked.     init */
+	/* dev == -1 we already inited the asked device.    skip */
+	/* dev < -1  init all devices. including this one.  init */
+	if ((dev == -1 ) || (dev-- > 0))
+		return -1;
+
+	if ((err=pci_enable_device(pdev))) {
+		eprintk("cannot enable device\n");
+		return err;
+	}
+
+	sst_info = (struct sstfb_info*)kmalloc(sizeof(*sst_info), GFP_KERNEL);
+	if (!sst_info)
+		goto fail_kmalloc;
+	pci_set_drvdata(pdev, sst_info);
+	sst_info->type = id->driver_data;
+	spec = &voodoo_spec[sst_info->type];
+	f_ddprintk("found device : %s\n", spec->name);
+
+	sst_info->dev = pdev;
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &sst_info->revision);
+
+	sst_info->mmio.base = pci_resource_start(pdev,0);
+	sst_info->video.base = sst_info->mmio.base+0x400000;
+
+	if (!request_mem_region(sst_info->mmio.base,0x400000,"sstfb MMIO")) {
+		eprintk ("cannot reserve mmio memory\n");
+		goto fail_mmio_mem;
+	}
+
+	if (!request_mem_region(sst_info->video.base,0x400000,"sstfb FB")) {
+		eprintk ("cannot reserve fb memory\n");
+		goto fail_fb_mem;
+	}
+
+	sst_info->mmio.vbase = (u_long) ioremap_nocache(sst_info->mmio.base, 0x400000);
+	if (!sst_info->mmio.vbase) {
+		eprintk("cannot remap register area %#lx\n",
+		        sst_info->mmio.base);
+		goto fail_mmio_remap;
+	}
+	sst_info->video.vbase = (u_long) ioremap_nocache(sst_info->video.base, 0x400000);
+	if (!sst_info->video.vbase) {
+		eprintk("cannot remap framebuffer %#lx\n",
+		        sst_info->video.base);
+		goto fail_fb_remap;
+	}
+
+	if(!sst_init(sst_info)) {
+		eprintk("Init failed\n");
+		goto fail;
+	}
+	sst_get_memsize(sst_info, &sst_info->video.len);
+	strncpy(sst_info->info.modename, spec->name, 16);
+
+	iprintk("%s with %s dac\n", sst_info->info.modename, sst_info->dac_sw.name);
+	iprintk("framebuffer at %#lx, mapped to %#lx,"
+	        " size %ldMb\n",
+	        sst_info->video.base, sst_info->video.vbase,
+	        sst_info->video.len >> 20);
+
+	f_ddprintk("revision: %d\n", sst_info->revision);
+	f_ddprintk("regbase_virt: %#lx\n", sst_info->mmio.vbase);
+	f_ddprintk("membase_phys: %#lx\n", sst_info->video.base);
+	f_ddprintk("fbbase_virt: %#lx\n", sst_info->video.vbase);
+
+	sst_info->info.node       = -1 ;
+	sst_info->info.flags      = FBINFO_FLAG_DEFAULT;
+	sst_info->info.fbops      = &sstfb_ops;
+	sst_info->info.disp       = &sst_info->disp;
+	sst_info->info.changevar  = NULL;
+	sst_info->info.switch_con = &sstfbcon_switch;
+	sst_info->info.updatevar  = &sstfbcon_updatevar;
+	sst_info->info.blank      = &sstfbcon_blank;
+
+	tmp=0;
+	var = sstfb_default;
+	if ( mode_option  &&
+	     fb_find_mode(&var, &sst_info->info, mode_option,
+	                   NULL, 0, NULL, 16)) {
+		if (sstfb_set_var(&var, -1, &sst_info->info)) {
 			eprintk("can't set supplied video mode. Using default\n");
 			var = sstfb_default;
-			if (sstfb_set_var(&var, -1, &fb_info.info)) {
-				eprintk("can't set default video mode.\n");
-				return -ENXIO;
-			}
-		}
-		/*clear fb */
-		memset_io(fb_info.video.vbase, 0, fb_info.video.len);
-		/* print some squares ... */
-		sstfb_test16(&fb_info); /* FIXME this is only for 16bpp */
-
-		/* register fb */
-		if (register_framebuffer(&fb_info.info) < 0) {
-			eprintk("can't register framebuffer.\n");
-			return -ENXIO;
+		} else {
+			/* set the new default */
+			sstfb_default = var;
+			tmp=1;  /* no need to set the mode. */
 		}
-		printk(KERN_INFO "fb%d: %s frame buffer device\n",
-		       GET_FB_IDX(fb_info.info.node),fb_info.info.modename);
+	}
 
-		num_sst++;
+	if (!tmp && sstfb_set_var(&var, -1, &sst_info->info)) {
+		eprintk("can't set default video mode.\n");
+		goto fail;
+	}
+	/*clear fb */
+	memset_io(sst_info->video.vbase, 0, sst_info->video.len);
+	/* print some squares ... */
+	sstfb_test16(sst_info); /* FIXME this is only for 16bpp */
 
-		if (dev <= 0)	/* we use the first card only for now (==0) */
-			return 0;
+	/* register fb */
+	if (register_framebuffer(&sst_info->info) < 0) {
+		eprintk("can't register framebuffer.\n");
+		goto fail;
 	}
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+	       GET_FB_IDX(sst_info->info.node),sst_info->info.modename);
+	return 0;
+
+fail:
+	iounmap((void *)sst_info->video.base);
+fail_fb_remap:
+	iounmap((void *)sst_info->mmio.base);
+fail_mmio_remap:
+	release_mem_region(sst_info->video.base,0x400000);
+fail_fb_mem:
+	release_mem_region(sst_info->mmio.base,0x400000);
+fail_mmio_mem:
+	kfree(sst_info);
+fail_kmalloc:
 	return -ENXIO; 	/* no voodoo detected */
-#undef sst_dev
 }
 
+static void __devexit sstfb_remove(struct pci_dev *pdev)
+{
+	struct sstfb_info * sst_info;
+
+	f_dprintk("sstfb_remove\n");
+	sst_info=pci_get_drvdata(pdev);
+	sst_shutdown(sst_info);
+
+	unregister_framebuffer(&sst_info->info);
+	iounmap((void*)sst_info->video.vbase);
+	iounmap((void*)sst_info->mmio.vbase);
+	release_mem_region(sst_info->video.base,0x400000);
+	release_mem_region(sst_info->mmio.base,0x400000);
+	kfree(sst_info);
+}
+
+
 /*
  * console driver
  */
@@ -1802,15 +1949,15 @@
 	struct sstfb_par par;
 
 	f_dprintk("sstfbcon_switch(con: %d)\n",con);
-	f_ddprintk("currcon: %d\n", info->currcon);
-	v_dprintk("currcon: %d\n", info->currcon);
+	f_ddprintk("currcon: %d\n", sst_info->currcon);
+	v_dprintk("currcon: %d\n", sst_info->currcon);
 
-	if (info->currcon >=  0) {
-		if (fb_display[info->currcon].cmap.len)
-			fb_get_cmap(&fb_display[info->currcon].cmap, 1,
+	if (sst_info->currcon >=  0) {
+		if (fb_display[sst_info->currcon].cmap.len)
+			fb_get_cmap(&fb_display[sst_info->currcon].cmap, 1,
 			            sstfb_getcolreg, info);
 	}
-	info->currcon = con;
+	sst_info->currcon = con;
 	fb_display[con].var.activate = FB_ACTIVATE_NOW;
 
 	print_var(&fb_display[con].var, "&fb_display[con: %d].var",con);
@@ -1818,7 +1965,7 @@
 	if (memcmp(&par,&(sst_info->current_par),sizeof(par))) {
 		sstfb_set_par(&par, sst_info);
 	}
-	do_install_cmap(con, info);
+	sstfb_install_cmap(con, info);
 	return 0;
 #undef sst_info
 }
@@ -1829,6 +1976,12 @@
 	return -EINVAL;
 }
 
+static void sstfbcon_blank(int blank, struct fb_info *info)
+{
+	f_dprintk("sstfbcon_blank(level %d)\n", blank);
+}
+
+
 /* print some squares on the fb (presuming 16bpp)  */
 static void sstfb_test16(struct sstfb_info *sst_info)
 {
@@ -1877,7 +2030,7 @@
 {
 	int i,j;
 	u_long p;
-	u32 fbbase_virt = sst_info->video.vbase;
+	u_long fbbase_virt = sst_info->video.vbase;
 
 	f_dprintk("sstfb_test32\n");
 	/* rect blanc 20x100+200+0 */
@@ -1915,31 +2068,7 @@
 }
 #endif /* EN_24_32_BPP */
 
-#ifdef MODULE
-
-int init_module(void)
-{
-	f_dprintk("init_module\n");
-	sstfb_init();
-	if (num_sst == 0 )
-		return -ENXIO;
-	return 0;
-}
-
-void cleanup_module(void)
-{
-	f_dprintk("cleanup_module\n");
-	f_ddprintk("conf %d\n",fb_info.configured);
-
-	if (fb_info.configured) {
-		sst_shutdown();
-		iounmap((void*)fb_info.mmio.vbase);
-		iounmap((void*)fb_info.video.vbase);
-		unregister_framebuffer(&fb_info.info);
-	}
-}
-
-MODULE_AUTHOR("(c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>");
+MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>");
 MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
 MODULE_LICENSE("GPL");
 
@@ -1957,7 +2086,6 @@
 MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
 MODULE_PARM(dev,"i");
 MODULE_PARM_DESC(dev , "Attach to device ID (0..n) (default=1st device)");
-#endif	/* MODULE */
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
@@ -1967,13 +2095,13 @@
  * End:
  */
 
-#if 0
-void Dump_regs ( void)
+#if 1
+void __Dump_regs (struct sstfb_info * sst_info)
 {
 	struct { u32 reg ; char * reg_name;}  pci_regs [] =  {
 		{ PCI_INIT_ENABLE, "initenable"},
-		{ PCI_VCLK_ENABLE, "enable vclk"}, 
-		{ PCI_VCLK_DISABLE, "disable vclk"}, 
+		{ PCI_VCLK_ENABLE, "enable vclk"},
+		{ PCI_VCLK_DISABLE, "disable vclk"},
 	};
 
 	struct { u32 reg ; char * reg_name;}  sst_regs [] =  {
@@ -1988,25 +2116,27 @@
 		{LFBMODE,"lfbmode"},
 		{FBZMODE,"fbzmode"},
 	};
-	u32 pci_res[sizeof(pci_regs)/sizeof(pci_regs[0])];
-	u32 sst_res[sizeof(sst_regs)/sizeof(sst_regs[0])];
+	int pci_s = sizeof(pci_regs)/sizeof(*pci_regs);
+	int sst_s = sizeof(sst_regs)/sizeof(*sst_regs);
+	u32 pci_res[pci_s];
+	u32 sst_res[sst_s];
 
-	struct pci_dev * dev = fb_info.dev;
+	struct pci_dev * dev = sst_info->dev;
 
 	int i;
 
-	for (i=0; i<(sizeof(pci_regs)/sizeof(pci_regs[0])) ; i++ ) {
+	for (i=0; i < pci_s ; i++ ) {
 		pci_read_config_dword ( dev, pci_regs[i].reg , &pci_res[i]) ;
 	}
-	for (i=0; i<(sizeof(sst_regs)/sizeof(sst_regs[0])) ; i++ ) {
+	for (i=0; i < sst_s ; i++ ) {
 		sst_res[i]=sst_read(sst_regs[i].reg);
 	}
 
 	dprintk ("Dump regs\n");
-	for (i=0; i<(sizeof(pci_regs)/sizeof(pci_regs[0])) ; i++ ) {
+	for (i=0; i < pci_s ; i++ ) {
 		dprintk("%s = %0#10x\n", pci_regs[i].reg_name , pci_res[i]) ;
 	}
-	for (i=0; i<(sizeof(sst_regs)/sizeof(sst_regs[0])) ; i++ ) {
+	for (i=0; i < sst_s ; i++ ) {
 		dprintk("%s = %0#10x\n", sst_regs[i].reg_name , sst_res[i]) ;
 	}
 }
diff -Nru a/drivers/video/sstfb.h b/drivers/video/sstfb.h
--- a/drivers/video/sstfb.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/sstfb.h	Wed Jul 24 14:03:36 2002
@@ -5,13 +5,13 @@
  *
  *     Created 28 Aug 2001 by Ghozlane Toumi
  *
- * $Id: sstfb.h,v 1.1.4.1 2001/08/29 01:30:38 ghoz Exp $
+ * $Id: sstfb.h,v 1.8 2002/05/10 19:35:11 ghoz Exp $
  */
 
 
 #ifndef _SSTFB_H_
 #define _SSTFB_H_
- 
+
 /*
  *
  *  Debug Stuff
@@ -72,9 +72,10 @@
 #define iprintk(X...)	printk(KERN_INFO "sstfb: " X)
 #define wprintk(X...)	printk(KERN_WARNING "sstfb: " X)
 
-#define BIT(x)		(1ul << (x))
+#define BIT(x)		(1ul<<(x))
 #define PS2KHZ(a)	(1000000000UL/(a))	/* picoseconds to KHz */
 #define KHZ2PS(a)	(1000000000UL/(a))
+#define POW2(x)		(1ul<<(x))
 
 #ifndef ABS
 # define ABS(x)		(((x)<0)?-(x):(x))
@@ -170,9 +171,15 @@
 #define DAC_DATA		0x022c
 #  define DAC_READ_CMD		  BIT(11)	/* set read dacreg mode */
 #define FBIINIT5		0x0244		/* v2 specific */
+#  define FBIINIT5_MASK		  0xfa40ffff    /* mask video bits*/
+#  define HDOUBLESCAN		  BIT(20)
+#  define VDOUBLESCAN		  BIT(21)
+#  define HSYNC_HIGH 		  BIT(23)
+#  define VSYNC_HIGH 		  BIT(24)
+#  define INTERLACE		  BIT(26)
 #define FBIINIT6		0x0248		/* v2 specific */
-#define FBIINIT7		0x024c		/* v2 specific */
 #  define TILES_IN_X_LSB_SHIFT	  30		/* v2 */
+#define FBIINIT7		0x024c		/* v2 specific */
 
 /* Dac Registers */
 #define DACREG_WMA		0x0	/* pixel write mode address */
@@ -275,30 +282,32 @@
  */
 
 /* used to know witch clock to set */
-#define VID_CLOCK	0
-#define GFX_CLOCK	1
+enum {
+	VID_CLOCK=0,
+	GFX_CLOCK=1,
+};
 
 /* freq max */
 #define DAC_FREF	14318	/* DAC reference freq (Khz) */
 #define VCO_MAX		260000
 
 /*
- *
- *  Declarations
- *
+ *  driver structs
  */
 
 struct pll_timing {
-	u8 m;
-	u8 n;
-	u8 p;
+	unsigned int m;
+	unsigned int n;
+	unsigned int p;
 };
 
+struct sstfb_info;
+
 struct dac_switch {
 	char * name;
-	int (*detect) (void);
-	int (*set_pll) (const struct pll_timing *t, const int clock);
-	void (*set_vidmod) (const int bpp);
+	int (*detect) (struct sstfb_info *sst_info);
+	int (*set_pll) (struct sstfb_info *sst_info, const struct pll_timing *t, const int clock);
+	void (*set_vidmod) (struct sstfb_info *sst_info, const int bpp);
 };
 
 struct sst_spec {
@@ -317,8 +326,12 @@
 	unsigned int vSyncOn;
 	unsigned int vSyncOff;
 	unsigned int vBackPorch;
-	unsigned int freq;	/* freq in picoseconds */
-	unsigned int tiles_in_X; /* num of tiles in X res */
+	unsigned int freq;	/* freq in kHz */
+	struct pll_timing pll;
+	unsigned int tiles_in_X;/* num of tiles in X res */
+	unsigned int vmode;     /* doublescan/interlaced */
+	unsigned int sync;      /* H/V sync polarity */
+	unsigned int valid;	/* par is correct (fool proof) */
 };
 
 struct sstfb_info {
@@ -336,18 +349,34 @@
 		unsigned long	vbase;
 	} mmio;				/* registers memory info */
 
-	struct dac_switch *	dac_sw;	/* dac specific functions */
-	struct sst_spec *	spec;
+	struct dac_switch 	dac_sw;	/* dac specific functions */
 
-	int	is_voodoo2;
+	int	type;
 	u8	revision;
 
 	/* status */
-	int	configured;
-/*	int	indexed_mode;
+/*XXX	int	configured;
+	int	indexed_mode;
 	int	vgapass;
 	int	clipping; */
 	int	gfx_clock;
+
+	int	currcon;
+	struct display  	disp; /* current display */
+	struct { u_int red, green, blue, transp; } palette[16];
+
+	union {
+#ifdef FBCON_HAS_CFB16
+		u16 cfb16[16];
+#endif
+#ifdef EN_24_32_BPP
+#if defined (FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
+		u32 cfb32[16];
+#endif
+#endif
+	} fbcon_cmap;
+
 };
+
 
 #endif /* _SSTFB_H_ */
diff -Nru a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c
--- a/drivers/video/sun3fb.c	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/sun3fb.c	Wed Jul 24 14:03:36 2002
@@ -48,6 +48,13 @@
 
 #ifdef CONFIG_SUN3
 #include <asm/oplib.h>
+#include <asm/machines.h>
+#include <asm/idprom.h>
+
+#define CGFOUR_OBMEM_ADDR 0x1f300000
+#define BWTWO_OBMEM_ADDR 0x1f000000
+#define BWTWO_OBMEM50_ADDR 0x00100000
+
 #endif
 #ifdef CONFIG_SUN3X
 #include <asm/sun3x.h>
@@ -59,12 +66,14 @@
 #define CURSOR_SHAPE			1
 #define CURSOR_BLINK			2
 
+#define mymemset(x,y) memset(x,0,y)
+
     /*
      *  Interface used by the world
      */
 
 int sun3fb_init(void);
-int sun3fb_setup(char *options);
+void sun3fb_setup(char *options);
 
 static char fontname[40] __initdata = { 0 };
 static int curblink __initdata = 1;
@@ -113,6 +122,8 @@
 static void sun3fb_clear_margin(struct display *p, int s)
 {
 	struct fb_info_sbusfb *fb = sbusfbinfod(p);
+	
+	return;
 
 	if (fb->switch_from_graph)
 		(*fb->switch_from_graph)(fb);
@@ -352,7 +363,7 @@
 		p++;
 	}
 
-	return 0;
+	return;
 }
 
 static int sun3fbcon_switch(int con, struct fb_info *info)
@@ -408,6 +419,7 @@
     	return fb->blank(fb);
     else if (!blank && fb->unblank)
     	return fb->unblank(fb);
+    return 0;
 }
 
     /*
@@ -505,7 +517,7 @@
      */
 static int __init sun3fb_init_fb(int fbtype, unsigned long addr)
 {
-	static struct linux_sbus_device sdb;
+	static struct sbus_dev sdb;
 	struct fb_fix_screeninfo *fix;
 	struct fb_var_screeninfo *var;
 	struct display *disp;
@@ -513,7 +525,7 @@
 	struct fbtype *type;
 	int linebytes, w, h, depth;
 	char *p = NULL;
-
+	
 	fb = kmalloc(sizeof(struct fb_info_sbusfb), GFP_ATOMIC);
 	if (!fb)
 		return -ENOMEM;
@@ -535,9 +547,11 @@
 	type->fb_depth  = depth = (fbtype == FBTYPE_SUN2BW) ? 1 : 8;
 	linebytes = w * depth / 8;
 	type->fb_size   = PAGE_ALIGN((linebytes) * h);
-	
+/*	
 	fb->x_margin = (w & 7) / 2;
 	fb->y_margin = (h & 15) / 2;
+*/
+	fb->x_margin = fb->y_margin = 0;
 
 	var->xres_virtual = w;
 	var->yres_virtual = h;
@@ -582,8 +596,14 @@
 	case FBTYPE_SUN2BW:
 		p = bwtwofb_init(fb); break;
 #endif
+#ifdef CONFIG_FB_CGTHREE
+	case FBTYPE_SUN4COLOR:
+	case FBTYPE_SUN3COLOR:
+		type->fb_size = 0x100000;
+		p = cgthreefb_init(fb); break;
+#endif
 	}
-	fix->smem_start = fb->info.screen_base;
+	fix->smem_start = (unsigned long)fb->info.screen_base;	// FIXME
 	
 	if (!p) {
 		kfree(fb);
@@ -638,17 +658,25 @@
 	unsigned long addr;
 	char p4id;
 	
-	if (!con_is_present()) return;
-	printk("sun3fb_init()\n");
+	if (!con_is_present()) return -ENODEV;
 #ifdef CONFIG_SUN3
-	addr = 0xfe20000;
         switch(*(romvec->pv_fbtype))
         {
-		case FBTYPE_SUN2BW:
-			return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
-		case FBTYPE_SUN3COLOR:
-			printk("cg3 detected but not supported\n");
-			return -EINVAL;
+	case FBTYPE_SUN2BW:
+		addr = 0xfe20000;
+		return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
+	case FBTYPE_SUN3COLOR:
+	case FBTYPE_SUN4COLOR:
+		if(idprom->id_machtype != (SM_SUN3|SM_3_60)) {
+			printk("sun3fb: cgthree/four only supported on 3/60\n");
+			return -ENODEV;
+		}
+		
+		addr = CGFOUR_OBMEM_ADDR;
+		return sun3fb_init_fb(*(romvec->pv_fbtype), addr);
+	default:
+		printk("sun3fb: unsupported framebuffer\n");
+		return -ENODEV;
 	}
 #else
 	addr = SUN3X_VIDEO_BASE;
@@ -660,16 +688,18 @@
 			return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
 #if 0 /* not yet */
 		case 0x40:
-			sun3fb_init_fb(FBTYPE_SUN4COLOR, addr);
+			return sun3fb_init_fb(FBTYPE_SUN4COLOR, addr);
 			break;
 		case 0x45:
-			sun3fb_init_fb(FBTYPE_SUN8COLOR, addr);
+			return sun3fb_init_fb(FBTYPE_SUN8COLOR, addr);
 			break;
 #endif
 		case 0x60:
 			return sun3fb_init_fb(FBTYPE_SUNFAST_COLOR, addr);
 	}
 #endif			
+	
+	return -ENODEV;
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
--- a/drivers/video/tdfxfb.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/tdfxfb.c	Wed Jul 24 14:03:37 2002
@@ -79,10 +79,6 @@
 #include <video/tdfx.h>
 #include <video/fbcon.h>
 
-#ifndef PCI_DEVICE_ID_3DFX_VOODOO5
-#define PCI_DEVICE_ID_3DFX_VOODOO5      0x0009
-#endif
-
 #undef TDFXFB_DEBUG 
 #ifdef TDFXFB_DEBUG
 #define DPRINTK(a,b...) printk(KERN_DEBUG "fb: %s: " a, __FUNCTION__ , ## b)
@@ -995,7 +991,7 @@
 	info = kmalloc(sizeof(struct fb_info) + sizeof(struct display) +
 			sizeof(u32) * 16, GFP_KERNEL);
 
-	if (!info)	return -ENXIO;
+	if (!info)	return -ENOMEM;
 		
 	memset(info, 0, sizeof(info) + sizeof(struct display) + sizeof(u32) * 16);
      
@@ -1016,25 +1012,25 @@
 	}
 
 	tdfx_fix.mmio_start = pci_resource_start(pdev, 0);
-	tdfx_fix.mmio_len = 1 << 24;
-	default_par.regbase_virt = ioremap_nocache(tdfx_fix.mmio_start, 1<<24);
+	tdfx_fix.mmio_len = pci_resource_len(pdev, 0);
+	default_par.regbase_virt = ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
 	if (!default_par.regbase_virt) {
 		printk("fb: Can't remap %s register area.\n", tdfx_fix.id);
-		return -ENXIO;
+		goto out_err;
 	}
     
 	if (!request_mem_region(pci_resource_start(pdev, 0),
 	    pci_resource_len(pdev, 0), "tdfx regbase")) {
 		printk(KERN_WARNING "tdfxfb: Can't reserve regbase\n");
-		iounmap(default_par.regbase_virt);
-		return -ENXIO;
+		goto out_err;
 	} 
 
 	tdfx_fix.smem_start = pci_resource_start(pdev, 1);
 	if (!(tdfx_fix.smem_len = do_lfb_size(pdev->device))) {
-		iounmap(default_par.regbase_virt);
 		printk("fb: Can't count %s memory.\n", tdfx_fix.id);
-		return -ENXIO;
+		release_mem_region(pci_resource_start(pdev, 0),
+				   pci_resource_len(pdev, 0));
+		goto out_err;	
 	}
 
 	if (!request_mem_region(pci_resource_start(pdev, 1),
@@ -1042,16 +1038,18 @@
 		printk(KERN_WARNING "tdfxfb: Can't reserve smem\n");
 		release_mem_region(pci_resource_start(pdev, 0),
 				   pci_resource_len(pdev, 0));
-		iounmap(default_par.regbase_virt);
-		return -ENXIO;
+		goto out_err;
 	}
 
 	info->screen_base = ioremap_nocache(tdfx_fix.smem_start, 
-	tdfx_fix.smem_len);
+					    tdfx_fix.smem_len);
 	if (!info->screen_base) {
 		printk("fb: Can't remap %s framebuffer.\n", tdfx_fix.id);
-		iounmap(default_par.regbase_virt);
-		return -ENXIO;
+		release_mem_region(pci_resource_start(pdev, 1),
+				   pci_resource_len(pdev, 1));
+		release_mem_region(pci_resource_start(pdev, 0),
+				   pci_resource_len(pdev, 0));
+		goto out_err;
 	}
 
 	default_par.iobase = pci_resource_start(pdev, 2);
@@ -1063,9 +1061,7 @@
 				   pci_resource_len(pdev, 1));
 		release_mem_region(pci_resource_start(pdev, 0),
 				   pci_resource_len(pdev, 0));
-		iounmap(default_par.regbase_virt);
-		iounmap(info->screen_base);
-		return -ENXIO;
+		goto out_err;
 	}
 
 	printk("fb: %s memory = %dK\n", tdfx_fix.id, tdfx_fix.smem_len >> 10);
@@ -1104,13 +1100,24 @@
 
 	if (register_framebuffer(info) < 0) {
 		printk("tdfxfb: can't register framebuffer\n");
-		return -ENXIO;
+		goto out_err;
 	}
 	/*
 	 * Our driver data
 	 */
-	pdev->driver_data = info;
+	pci_set_drvdata(pdev, info);
 	return 0; 
+
+out_err:
+	/*
+	 * Cleanup after anything that was remapped/allocated.
+	 */
+	if (default_par.regbase_virt)
+		iounmap(default_par.regbase_virt);
+	if (info->screen_base)
+		iounmap(info->screen_base);
+	kfree(info);
+	return -ENXIO;
 }
 
 /**
@@ -1124,7 +1131,7 @@
  */
 static void __devexit tdfxfb_remove(struct pci_dev *pdev)
 {
-	struct fb_info *info = (struct fb_info *)pdev->driver_data;
+	struct fb_info *info = pci_get_drvdata(pdev);
 	struct tdfx_par *par = (struct tdfx_par *) info->par;
 
 	unregister_framebuffer(info);
@@ -1138,6 +1145,8 @@
 			   pci_resource_len(pdev, 1));
 	release_mem_region(pci_resource_start(pdev, 0),
 			   pci_resource_len(pdev, 0));
+	pci_set_drvdata(pdev, NULL);
+	kfree(info);
 }
 
 int __init tdfxfb_init(void)
diff -Nru a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c
--- a/drivers/video/tx3912fb.c	Wed Jul 24 14:03:38 2002
+++ b/drivers/video/tx3912fb.c	Wed Jul 24 14:03:38 2002
@@ -325,7 +325,7 @@
 	return 0;
 }
 
-int __init tx3912fb_setup(char *options)
+void __init tx3912fb_setup(char *options)
 {
 	char *this_opt;
 
diff -Nru a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
--- a/drivers/video/valkyriefb.c	Wed Jul 24 14:03:39 2002
+++ b/drivers/video/valkyriefb.c	Wed Jul 24 14:03:39 2002
@@ -7,6 +7,8 @@
  *  Vmode-switching changes and vmode 15/17 modifications created 29 August
  *  1998 by Barry K. Nathan <barryn@pobox.com>.
  *
+ *  Ported to m68k Macintosh by David Huggins-Daines <dhd@debian.org>
+ *
  *  Derived directly from:
  *
  *   controlfb.c -- frame buffer device for the PowerMac 'control' display
@@ -53,13 +55,15 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/nvram.h>
-#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <asm/vc_ioctl.h>
-#endif
 #include <linux/adb.h>
 #include <linux/cuda.h>
 #include <asm/io.h>
+#ifdef CONFIG_MAC
+#include <asm/bootinfo.h>
+#include <asm/macintosh.h>
+#else
 #include <asm/prom.h>
+#endif
 #include <asm/pgtable.h>
 
 #include <video/fbcon.h>
@@ -71,8 +75,15 @@
 
 static int can_soft_blank = 1;
 
+#ifdef CONFIG_MAC
+/* We don't yet have functions to read the PRAM... perhaps we can
+   adapt them from the PPC code? */
+static int default_vmode = VMODE_640_480_67;
+static int default_cmode = CMODE_8;
+#else
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
+#endif
 static char fontname[40] __initdata = { 0 };
 
 static int switching = 0;
@@ -116,7 +127,6 @@
 int valkyriefb_init(void);
 int valkyriefb_setup(char*);
 
-static void valkyrie_of_init(struct device_node *dp);
 static int valkyrie_get_fix(struct fb_fix_screeninfo *fix, int con,
 			 struct fb_info *info);
 static int valkyrie_get_var(struct fb_var_screeninfo *var, int con,
@@ -370,11 +380,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-extern struct vc_mode display_info;
-extern struct fb_info *console_fb_info;
-#endif /* CONFIG_FB_COMPAT_XPMAC */
-
 static int valkyrie_vram_reqd(int video_mode, int color_mode)
 {
 	int pitch;
@@ -409,6 +414,7 @@
 	printk(KERN_INFO "Monitor sense value = 0x%x, ", p->sense);
 
 	/* Try to pick a video mode out of NVRAM if we have one. */
+#ifndef CONFIG_MAC
 	if (default_vmode == VMODE_NVRAM) {
 		default_vmode = nvram_read_byte(NV_VMODE);
 		if (default_vmode <= 0
@@ -416,12 +422,15 @@
 		 || !valkyrie_reg_init[default_vmode - 1])
 			default_vmode = VMODE_CHOOSE;
 	}
+#endif
 	if (default_vmode == VMODE_CHOOSE)
 		default_vmode = mac_map_monitor_sense(p->sense);
 	if (!valkyrie_reg_init[default_vmode - 1])
 		default_vmode = VMODE_640_480_67;
+#ifndef CONFIG_MAC
 	if (default_cmode == CMODE_NVRAM)
 		default_cmode = nvram_read_byte(NV_CMODE);
+#endif
 
 	/*
 	 * Reduce the pixel size if we don't have enough VRAM or bandwitdh.
@@ -492,70 +501,61 @@
 
 	/* Turn on display */
 	out_8(&valkyrie_regs->mode.r, init->mode);
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-	/* And let the world know the truth. */
-	if (!console_fb_info || console_fb_info == &p->info) {
-		display_info.height = p->var.yres;
-		display_info.width = p->var.xres;
-		display_info.depth = (cmode == CMODE_16) ? 16 : 8;
-		display_info.pitch = p->fix.line_length;
-		display_info.mode = vmode;
-		strncpy(display_info.name, "valkyrie",
-			sizeof(display_info.name));
-		display_info.fb_address = p->frame_buffer_phys + 0x1000;
-		display_info.cmap_adr_address = p->cmap_regs_phys;
-		display_info.cmap_data_address = p->cmap_regs_phys + 8;
-		display_info.disp_reg_address = p->valkyrie_regs_phys;
-		console_fb_info = &p->info;
-	}
-#endif /* CONFIG_FB_COMPAT_XPMAC */
 }
 
 int __init valkyriefb_init(void)
 {
+	struct fb_info_valkyrie	*p;
+	unsigned long frame_buffer_phys, cmap_regs_phys, flags;
+
+#ifdef CONFIG_MAC
+	if (!MACH_IS_MAC)
+		return 0;
+	if (!(mac_bi_data.id == MAC_MODEL_Q630
+	      /* I'm not sure about this one */
+	    || mac_bi_data.id == MAC_MODEL_P588))
+		return 0;
+
+	/* Hardcoded addresses... welcome to 68k Macintosh country :-) */
+	frame_buffer_phys = 0xf9000000;
+	cmap_regs_phys = 0x50f24000;
+	flags = IOMAP_NOCACHE_SER; /* IOMAP_WRITETHROUGH?? */
+#else /* ppc (!CONFIG_MAC) */
 	struct device_node *dp;
 
 	dp = find_devices("valkyrie");
-	if (dp != 0)
-		valkyrie_of_init(dp);
-	return 0;
-}
+	if (dp == 0)
+		return 0;
 
-static void __init valkyrie_of_init(struct device_node *dp)
-{
-	struct fb_info_valkyrie	*p;
-	unsigned long addr;
-	
 	if(dp->n_addrs != 1) {
 		printk(KERN_ERR "expecting 1 address for valkyrie (got %d)", dp->n_addrs);
-		return;
+		return 0;
 	}	
 
+	frame_buffer_phys = dp->addrs[0].address;
+	cmap_regs_phys = dp->addrs[0].address+0x304000;
+	flags = _PAGE_WRITETHRU;
+#endif /* ppc (!CONFIG_MAC) */
+
 	p = kmalloc(sizeof(*p), GFP_ATOMIC);
 	if (p == 0)
-		return;
+		return 0;
 	memset(p, 0, sizeof(*p));
 
 	/* Map in frame buffer and registers */
-	addr = dp->addrs[0].address;
-	if (!request_mem_region(addr, dp->addrs[0].size, "valkyriefb")) {
+	if (!request_mem_region(frame_buffer_phys, 0x100000, "valkyriefb")) {
 		kfree(p);
-		return;
+		return 0;
 	}
-	p->frame_buffer_phys  = addr;
-	p->frame_buffer  = __ioremap(addr, 0x100000, _PAGE_WRITETHRU);
-	p->cmap_regs_phys     = addr + 0x304000;
-	p->cmap_regs     = ioremap(p->cmap_regs_phys,4096);
-	p->valkyrie_regs_phys = addr + 0x30a000;
-	p->valkyrie_regs = ioremap(p->valkyrie_regs_phys, 4096);
-
-	/*
-	 * kps: As far as I know, all Valkyries have fixed usable VRAM.
-	 */
 	p->total_vram = 0x100000;
-
+	p->frame_buffer_phys  = frame_buffer_phys;
+	p->frame_buffer = __ioremap(frame_buffer_phys, p->total_vram, flags);
+	p->cmap_regs_phys = cmap_regs_phys;
+	p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000);
+	p->valkyrie_regs_phys = cmap_regs_phys+0x6000;
+	p->valkyrie_regs = ioremap(p->valkyrie_regs_phys, 0x1000);
 	init_valkyrie(p);
+	return 0;
 }
 
 /*
diff -Nru a/drivers/video/valkyriefb.h b/drivers/video/valkyriefb.h
--- a/drivers/video/valkyriefb.h	Wed Jul 24 14:03:39 2002
+++ b/drivers/video/valkyriefb.h	Wed Jul 24 14:03:39 2002
@@ -9,6 +9,8 @@
  * 
  * vmode 10 changed by Steven Borley <sjb@salix.demon.co.uk>, 14 mai 2000
  *
+ * Ported to 68k Macintosh by David Huggins-Daines <dhd@debian.org>
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
@@ -37,12 +39,19 @@
  *  Copyright (C) 1998 Jon Howell
  */
 
+#ifdef CONFIG_MAC
+/* Valkyrie registers are word-aligned on m68k */
+#define VALKYRIE_REG_PADSIZE	3
+#else
+#define VALKYRIE_REG_PADSIZE	7
+#endif
+
 /*
  * Structure of the registers for the Valkyrie colormap registers.
  */
 struct cmap_regs {
 	unsigned char addr;
-	char pad1[7];
+	char pad1[VALKYRIE_REG_PADSIZE];
 	unsigned char lut;
 };
 
@@ -52,7 +61,7 @@
 
 struct vpreg {			/* padded register */
 	unsigned char r;
-	char pad[7];
+	char pad[VALKYRIE_REG_PADSIZE];
 };
 
 
@@ -81,6 +90,7 @@
 	int	vres;
 };
 
+#ifndef CONFIG_MAC
 /* Register values for 1024x768, 75Hz mode (17) */
 /* I'm not sure which mode this is (16 or 17), so I'm defining it as 17,
  * since the equivalent mode in controlfb (which I adapted this from) is
@@ -125,14 +135,6 @@
 	1024, 768
 };
 
-/* Register values for 832x624, 75Hz mode (13) */
-static struct valkyrie_regvals valkyrie_reg_init_13 = {
-    9,
-    { 23, 42, 3 },  /* pixel clock = 57.07MHz for V=74.27Hz */
-    { 832, 0 },
-	832, 624
-};
-
 /* Register values for 800x600, 72Hz mode (11) */
 static struct valkyrie_regvals valkyrie_reg_init_11 = {
     13,
@@ -140,6 +142,15 @@
     { 800, 0 },
 	800, 600
 };
+#endif /* CONFIG_MAC */
+
+/* Register values for 832x624, 75Hz mode (13) */
+static struct valkyrie_regvals valkyrie_reg_init_13 = {
+    9,
+    { 23, 42, 3 },  /* pixel clock = 57.07MHz for V=74.27Hz */
+    { 832, 0 },
+	832, 624
+};
 
 /* Register values for 800x600, 60Hz mode (10) */
 static struct valkyrie_regvals valkyrie_reg_init_10 = {
@@ -177,6 +188,15 @@
 	NULL,
 	NULL,
 	&valkyrie_reg_init_10,
+#ifdef CONFIG_MAC
+	NULL,
+	NULL,
+	&valkyrie_reg_init_13,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+#else
 	&valkyrie_reg_init_11,
 	NULL,
 	&valkyrie_reg_init_13,
@@ -184,6 +204,7 @@
 	&valkyrie_reg_init_15,
 	NULL,
 	&valkyrie_reg_init_17,
+#endif
 	NULL,
 	NULL,
 	NULL
diff -Nru a/drivers/video/vesafb.c b/drivers/video/vesafb.c
--- a/drivers/video/vesafb.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/video/vesafb.c	Wed Jul 24 14:03:35 2002
@@ -32,14 +32,18 @@
 
 /* --------------------------------------------------------------------- */
 
-static struct fb_var_screeninfo vesafb_defined = {
+static struct fb_var_screeninfo vesafb_defined __initdata = {
 	activate:	FB_ACTIVATE_NOW,
 	height:		-1,
 	width:		-1,
+	right_margin:	32,
+	upper_margin:	16,
+	lower_margin:	4,
+	vsync_len:	4,
 	vmode:		FB_VMODE_NONINTERLACED,
 };
 
-static struct fb_fix_screeninfo vesafb_fix = {
+static struct fb_fix_screeninfo vesafb_fix __initdata = {
 	id:	"VESA VGA",
 	type:	FB_TYPE_PACKED_PIXELS,
 	accel:	FB_ACCEL_NONE,
@@ -301,11 +305,7 @@
 	/* some dummy values for timing to make fbset happy */
 	vesafb_defined.pixclock     = 10000000 / vesafb_defined.xres * 1000 / vesafb_defined.yres;
 	vesafb_defined.left_margin  = (vesafb_defined.xres / 8) & 0xf8;
-	vesafb_defined.right_margin = 32;
-	vesafb_defined.upper_margin = 16;
-	vesafb_defined.lower_margin = 4;
 	vesafb_defined.hsync_len    = (vesafb_defined.xres / 8) & 0xf8;
-	vesafb_defined.vsync_len    = 4;
 
 	if (vesafb_defined.bits_per_pixel > 8) {
 		vesafb_defined.red.offset    = screen_info.red_pos;
diff -Nru a/drivers/video/vfb.c b/drivers/video/vfb.c
--- a/drivers/video/vfb.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/video/vfb.c	Wed Jul 24 14:03:35 2002
@@ -24,7 +24,7 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 
-#include <linux/fbcon.h>
+#include <video/fbcon.h>
 
     /*
      *  RAM we reserve for the frame buffer. This defines the maximum screen
@@ -446,7 +446,7 @@
 	fb_info.pseudo_palette = &vfb_pseudo_palette;
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 
-	strcpy(fb_info.modename, vesafb_fix.id);
+	strcpy(fb_info.modename, vfb_fix.id);
 	fb_info.changevar = NULL;
 	fb_info.currcon = -1;
 	fb_info.disp = &disp;
diff -Nru a/drivers/video/vga.h b/drivers/video/vga.h
--- a/drivers/video/vga.h	Wed Jul 24 14:03:36 2002
+++ b/drivers/video/vga.h	Wed Jul 24 14:03:36 2002
@@ -22,6 +22,19 @@
 #include <asm/io.h>
 #ifndef CONFIG_AMIGA
 #include <asm/vga.h>
+#else
+/*
+ * FIXME
+ * Ugh, we don't have PCI space, so map readb() and friends to use Zorro space
+ * for MMIO accesses. This should make clgenfb work again on Amiga
+ */
+#define inb(port)	0
+#define inw(port)	0
+#define outb(port, val)	do { } while (0)
+#define outw(port, val)	do { } while (0)
+#define readb		z_readb
+#define writeb		z_writeb
+#define writew		z_writew
 #endif
 #include <asm/byteorder.h>
 
diff -Nru a/drivers/video/virgefb.c b/drivers/video/virgefb.c
--- a/drivers/video/virgefb.c	Wed Jul 24 14:03:37 2002
+++ b/drivers/video/virgefb.c	Wed Jul 24 14:03:37 2002
@@ -9,12 +9,30 @@
  *    Copyright (C) 1996 Martin Apel
  *                       Geert Uytterhoeven
  *
+ * Zorro II additions :
+ *
+ *    Copyright (C) 1998-2000 Christian T. Steigies
+ *
+ * Initialization additions :
+ *
+ *    Copyright (C) 1998-2000 Ken Tyler
+ *
+ * Parts of the Initialization code are based on Cyberfb.c by Allan Bair,
+ * and on the NetBSD CyberVision64 frame buffer driver by Michael Teske who gave
+ * permission for its use.
+ *
+ * Many thanks to Frank Mariak for his assistance with ZORRO 2 access and other
+ * mysteries.
+ *
+ *
+ *
  * 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.
  */
 
 #undef VIRGEFBDEBUG
+#undef VIRGEFBDUMP
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -29,16 +47,15 @@
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
 #include <asm/amigahw.h>
 #include <asm/io.h>
-
-#include <video/s3blit.h>
+#include <asm/irq.h>
 #include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb32.h>
 
+#include "virgefb.h"
 
 #ifdef VIRGEFBDEBUG
 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
@@ -46,63 +63,163 @@
 #define DPRINTK(fmt, args...)
 #endif
 
-#if 1
-#define vgawb_3d(reg,dat) \
-	if (cv3d_on_zorro2) { \
-	*((unsigned char volatile *)((Cyber_vcode_switch_base) + 0x04)) = \
-	(0x01 & 0xffff); asm volatile ("nop"); \
-	} \
-	(*((unsigned char *)(CyberVGARegs + (reg ^ 3))) = dat); \
-	if (cv3d_on_zorro2) { \
-	*((unsigned char volatile *)((Cyber_vcode_switch_base) + 0x04)) = \
-	(0x02 & 0xffff); asm volatile ("nop"); \
-	}
-#define vgaww_3d(reg,dat) \
-                (*((unsigned word *)(CyberVGARegs + (reg ^ 2))) = swab16(dat))
-#define vgawl_3d(reg,dat) \
-                (*((unsigned long *)(CyberVGARegs + reg)) = swab32(dat))
+#ifdef VIRGEFBDUMP
+static void cv64_dump(void);
+#define DUMP cv64_dump()
 #else
-     /*
-      * Dunno why this doesn't work at the moment - we'll have to look at
-      * it later.
-      */
-#define vgawb_3d(reg,dat) \
-                (*((unsigned char *)(CyberRegs + 0x8000 + reg)) = dat)
-#define vgaww_3d(reg,dat) \
-                (*((unsigned word *)(CyberRegs + 0x8000 + reg)) = dat)
-#define vgawl_3d(reg,dat) \
-                (*((unsigned long *)(CyberRegs + 0x8000 + reg)) = dat)
-#endif
-
-     /*
-      * We asume P5 mapped the big-endian version of these registers.
-      */
-#define wb_3d(reg,dat) \
-                (*((unsigned char volatile *)(CyberRegs + reg)) = dat)
-#define ww_3d(reg,dat) \
-                (*((unsigned word volatile *)(CyberRegs + reg)) = dat)
-#define wl_3d(reg,dat) \
-                (*((unsigned long volatile *)(CyberRegs + reg)) = dat)
-#define rl_3d(reg) \
-                (*((unsigned long volatile *)(CyberRegs + reg)))
+#define DUMP
+#endif
 
-#define Select_Zorro2_FrameBuffer(flag) \
-	do { \
-		*((unsigned char volatile *)((Cyber_vcode_switch_base) + 0x08)) = \
-		((flag * 0x40) & 0xffff); asm volatile ("nop"); \
-	} while (0)
 /*
- *	may be needed when we initialize the board?
- *	8bit: flag = 2, 16 bit: flag = 1, 24/32bit: flag = 0 
- *	_when_ the board is initialized, depth doesnt matter, we allways write
- *	to the same address, aperture seems not to matter on Z2.
+ *	Macros for register access and zorro control
  */
 
+static inline void mb_inline(void) { mb(); }	/* for use in comma expressions */
+
+/* Set zorro 2 map */
+
+#define SelectIO \
+	mb(); \
+	if (on_zorro2) { \
+		(*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x01); \
+		mb(); \
+	}
+
+#define	SelectMMIO \
+	mb(); \
+	if (on_zorro2) { \
+		(*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x02); \
+		mb(); \
+	}
+
+#define	SelectCFG \
+	mb(); \
+	if (on_zorro2) { \
+		(*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x03); \
+		mb(); \
+	}
+
+/* Set pass through, 0 = amiga, !=0 = cv64/3d */
+
+#define SetVSwitch(x) \
+	mb(); \
+	(*(volatile u16 *)((u8 *)(vcode_switch_base)) = \
+	(u16)(x ? 0 : 1)); \
+	mb();
+
+/* Zorro2 endian 'aperture' */
+
+#define ENDIAN_BYTE	2
+#define ENDIAN_WORD	1
+#define ENDIAN_LONG	0
+
+#define Select_Zorro2_FrameBuffer(x) \
+	do { \
+		if (on_zorro2) { \
+			mb(); \
+			(*(volatile u16 *)((u8 *)(vcode_switch_base + 0x08)) = \
+			(x * 0x40)); \
+			mb(); \
+		} \
+	} while (0)
+
+/* SetPortVal - only used for interrupt enable (not yet implemented) */
+
+#if 0
+#define SetPortVal(x) \
+	mb(); \
+	(*(volatile u16 *)((u8 *)(vcode_switch_base + 0x0c)) = \
+	(u16)x); \
+	mb();
+#endif
+
+/* IO access */
+
+#define byte_access_io(x)	(((x) & 0x3ffc) | (((x) & 3)^3) | (((x) & 3) <<14))
+#define byte_access_mmio(x)	(((x) & 0xfffc) | (((x) & 3)^3))
+
+/* Write 8 bit VGA register - used once for chip wakeup */
+
+#define wb_vgaio(reg, dat) \
+	SelectIO; \
+	(*(volatile u8 *)(vgaio_regs + ((u32)byte_access_io(reg) & 0xffff)) = \
+	(dat & 0xff)); \
+	SelectMMIO;
+
+/* Read 8 bit VGA register - only used in dump (SelectIO not needed on read ?) */
+
+#ifdef VIRGEFBDUMP
+#define rb_vgaio(reg) \
+	({ \
+	u8 __zzyzx; \
+	SelectIO; \
+	__zzyzx = (*(volatile u8 *)((vgaio_regs)+(u32)byte_access_io(reg))); \
+	SelectMMIO; \
+	__zzyzx; \
+	})
+#endif
+
+/* MMIO access */
+
+/* Read 8 bit MMIO register */
+
+#define rb_mmio(reg) \
+	(mb_inline(), \
+	(*(volatile u8 *)(mmio_regs + 0x8000 + (u32)byte_access_mmio(reg))))
+
+/* Write 8 bit MMIO register */
+
+#define wb_mmio(reg,dat) \
+	mb(); \
+	(*(volatile u8 *)(mmio_regs + 0x8000 + (byte_access_mmio((reg) & 0xffff))) = \
+	(dat & 0xff)); \
+	mb();
+
+/* Read 32 bit MMIO register */
+
+#define rl_mmio(reg) \
+	(mb_inline(), \
+	(*((volatile u32 *)((u8 *)((mmio_regs + (on_zorro2 ? 0x20000 : 0)) + (reg))))))
+
+/* Write 32 bit MMIO register */
+
+#define wl_mmio(reg,dat) \
+	mb(); \
+	((*(volatile u32 *)((u8 *)((mmio_regs + (on_zorro2 ? 0x20000 : 0)) + (reg)))) = \
+	(u32)(dat)); \
+	mb();
+
+/* Write to virge graphics register */
+
+#define wgfx(reg, dat)	do { wb_mmio(GCT_ADDRESS, (reg)); wb_mmio(GCT_ADDRESS_W, (dat)); } while (0)
+
+/* Write to virge sequencer register */
+
+#define wseq(reg, dat)	do { wb_mmio(SEQ_ADDRESS, (reg)); wb_mmio(SEQ_ADDRESS_W, (dat)); } while (0)
+
+/* Write to virge CRT controller register */
+
+#define wcrt(reg, dat)	do { wb_mmio(CRT_ADDRESS, (reg)); wb_mmio(CRT_ADDRESS_W, (dat)); } while (0)
+
+/* Write to virge attribute register */
+
+#define watr(reg, dat) \
+	do { \
+		volatile unsigned char watr_tmp; \
+		watr_tmp = rb_mmio(ACT_ADDRESS_RESET); \
+		wb_mmio(ACT_ADDRESS_W, (reg)); \
+		wb_mmio(ACT_ADDRESS_W, (dat)); \
+		udelay(10); \
+	} while (0)
+
+/* end of macros */
+
 struct virgefb_par {
-   int xres;
-   int yres;
-   int bpp;
-   int accel;
+   struct fb_var_screeninfo var;
+   __u32 type;
+   __u32 type_aux;
+   __u32 visual;
+   __u32 line_length;
 };
 
 static struct virgefb_par current_par;
@@ -116,6 +233,9 @@
 #ifdef FBCON_HAS_CFB16
     u16 cfb16[16];
 #endif
+#ifdef FBCON_HAS_CFB32
+    u32 cfb32[16];
+#endif
 } fbcon_cmap;
 
 /*
@@ -138,43 +258,48 @@
    void (*blank)(int blank);
 } *fbhw;
 
-static int blit_maybe_busy = 0;
+static unsigned char blit_maybe_busy = 0;
 
 /*
  *    Frame Buffer Name
  */
 
-static char virgefb_name[16] = "Cybervision/3D";
-
+static char virgefb_name[16] = "CyberVision/3D";
 
 /*
- *    Cybervision Graphics Board
+ *    CyberVision64/3d Graphics Board
  */
 
-#define VIRGE8_WIDTH 1152
-#define VIRGE8_HEIGHT 886
-#define VIRGE8_PIXCLOCK 12500    /* ++Geert: Just a guess */
+static unsigned char virgefb_colour_table [256][3];
+static unsigned long v_ram;
+static unsigned long v_ram_size;
+static volatile unsigned char *mmio_regs;
+static volatile unsigned char *vgaio_regs;
+
+static unsigned long v_ram_phys;
+static unsigned long mmio_regs_phys;
+static unsigned long vcode_switch_base;
+static unsigned char on_zorro2;
 
-#if 1
-#define VIRGE16_WIDTH 800
-#define VIRGE16_HEIGHT 600
+/*
+ * Offsets from start of video ram to appropriate ZIII aperture
+ */
+
+#ifdef FBCON_HAS_CFB8
+#define CYBMEM_OFFSET_8  0x800000	/* BGRX */
+#endif
+#ifdef FBCON_HAS_CFB16
+#define CYBMEM_OFFSET_16 0x400000	/* GBXR */
+#endif
+#ifdef FBCON_HAS_CFB32
+#define CYBMEM_OFFSET_32 0x000000	/* XRGB */
 #endif
-#define VIRGE16_PIXCLOCK 25000   /* ++Geert: Just a guess */
 
+/*
+ *    MEMCLOCK was 32MHz, 64MHz works, 72MHz doesn't (on my board)
+ */
 
-static unsigned char Cyber_colour_table [256][3];
-static unsigned long CyberMem;
-static unsigned long CyberSize;
-static volatile char *CyberRegs;
-static volatile unsigned long CyberVGARegs; /* ++Andre: for CV64/3D, see macros at the beginning */
-static unsigned long CyberMem_phys;
-static unsigned long CyberRegs_phys;
-static unsigned long Cyber_register_base;
-static unsigned long Cyber_vcode_switch_base;
-static unsigned char cv3d_on_zorro2;
- 
-#define CYBMEM_OFFSET_8  0x800000	/* offsets from start of video - */ 
-#define CYBMEM_OFFSET_16 0x400000	/* ram to appropriate aperture */
+#define MEMCLOCK 50000000
 
 /*
  *    Predefined Video Modes
@@ -184,125 +309,350 @@
     const char *name;
     struct fb_var_screeninfo var;
 } virgefb_predefined[] __initdata = {
+#ifdef FBCON_HAS_CFB8
     {
 	"640x480-8", {		/* Cybervision 8 bpp */
 	    640, 480, 640, 480, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 160, 136, 82, 61, 88, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    }, {
+	"768x576-8", {		/* Cybervision 8 bpp */
+	    768, 576, 768, 576, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
 	"800x600-8", {		/* Cybervision 8 bpp */
 	    800, 600, 800, 600, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
+  #if 0 
 	"1024x768-8", {		/* Cybervision 8 bpp */
 	    1024, 768, 1024, 768, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+  #else
+	"1024x768-8", {
+	    1024, 768, 1024, 768, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+   #if 0
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 12500, 184, 40, 40, 2, 96, 1,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    }
+    #else
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 12699, 176, 16, 28, 1, 96, 3,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	    }
+    #endif
+  #endif
     }, {
 	"1152x886-8", {		/* Cybervision 8 bpp */
 	    1152, 886, 1152, 886, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
-	"1280x1024-8", {	/* Cybervision 8 bpp */
+	"1280x1024-8", { 	/* Cybervision 8 bpp */
 	    1280, 1024, 1280, 1024, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+  #if 0
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    }
+  #else
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 7414, 232, 64, 38, 1, 112, 3,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    }
+  #endif
     }, {
-	"1600x1200-8", {	/* Cybervision 8 bpp */
+	"1600x1200-8", { 	/* Cybervision 8 bpp */
 	    1600, 1200, 1600, 1200, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+  #if 0
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+  #else
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 6411, 256, 32, 52, 10, 160, 8,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
-    }, {
+	    }
+  #endif
+    },
+#endif
+
+#ifdef FBCON_HAS_CFB16
+    {
 	"640x480-16", {		/* Cybervision 16 bpp */
 	    640, 480, 640, 480, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 152, 144, 82, 61, 88, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    }, {
+	"768x576-16", {		/* Cybervision 16 bpp */
+	    768, 576, 768, 576, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
 	"800x600-16", {		/* Cybervision 16 bpp */
 	    800, 600, 800, 600, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
-	"1024x768-16", {         /* Cybervision 16 bpp */
+#if 0
+	"1024x768-16", { 	/* Cybervision 16 bpp */
 	    1024, 768, 1024, 768, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-       }
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+#else
+         "1024x768-16", {
+             1024, 768, 1024, 768, 0, 0, 16, 0,
+             {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+             0, 0, -1, -1, FB_ACCELF_TEXT, 12500, 184, 40, 40, 2, 96, 1,
+             FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+         }
+#endif
     }, {
-	"1152x886-16", {         /* Cybervision 16 bpp */
+	"1152x886-16", { 	/* Cybervision 16 bpp */
 	    1152, 886, 1152, 886, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-       }
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
-	"1280x1024-16", {         /* Cybervision 16 bpp */
+	"1280x1024-16", { 	/* Cybervision 16 bpp */
 	    1280, 1024, 1280, 1024, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-       }
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
-	"1600x1200-16", {         /* Cybervision 16 bpp */
+	"1600x1200-16", { 	/* Cybervision 16 bpp */
 	    1600, 1200, 1600, 1200, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-       }
-    }
-};
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    },
+#endif
+
+#ifdef FBCON_HAS_CFB32
+    {
+	"640x480-32", {		/* Cybervision 32 bpp */
+	    640, 480, 640, 480, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 160, 136, 82, 61, 88, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+     }, {
+	"768x576-32", {		/* Cybervision 32 bpp */
+	    768, 576, 768, 576, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+     }, {
+	"800x600-32", {		/* Cybervision 32 bpp */
+	    800, 600, 800, 600, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+  	    0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+     }, {
+	"1024x768-32", {	/* Cybervision 32 bpp */
+	    1024, 768, 1024, 768, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    }, {
+	"1152x886-32", {	/* Cybervision 32 bpp */
+	    1152, 886, 1152, 886, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    }, {
+	"1280x1024-32", {	/* Cybervision 32 bpp */
+	    1280, 1024, 1280, 1024, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    }, {
+	"1600x1200-32", {	/* Cybervision 32 bpp */
+	    1600, 1200, 1600, 1200, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    },
+#endif
+
+/* interlaced modes */
+
+#ifdef FBCON_HAS_CFB8
+    {
+	"1024x768-8i", {	/* Cybervision 8 bpp */
+	    1024, 768, 1024, 768, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1280x1024-8i", {	/* Cybervision 8 bpp */
+	    1280, 1024, 1280, 1024, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1600x1200-8i", {	/* Cybervision 8 bpp */
+	    1600, 1200, 1600, 1200, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    },
+#endif
 
+#ifdef FBCON_HAS_CFB16
+    {
+	"1024x768-16i", {	/* Cybervision 16 bpp */
+	    1024, 768, 1024, 768, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1280x1024-16i", {	/* Cybervision 16 bpp */
+	    1280, 1024, 1280, 1024, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1600x1200-16i", {	/* Cybervision 16 bpp */
+	    1600, 1200, 1600, 1200, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    },
+#endif
 
-#define NUM_TOTAL_MODES    ARRAY_SIZE(virgefb_predefined)
+#ifdef FBCON_HAS_CFB32
+    {
+	"1024x768-32i", {	/* Cybervision 32 bpp */
+	    1024, 768, 1024, 768, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 22222, 216, 144, 39, 2, 72, 1,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1280x1024-32i", {	/* Cybervision 32 bpp */
+	    1280, 1024, 1280, 1024, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {23, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1600x1200-32i", {	/* Cybervision 32 bpp */
+	    1600, 1200, 1600, 1200, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    },
+#endif
+
+/* doublescan modes */
+
+#ifdef FBCON_HAS_CFB8
+    {
+	"320x240-8d", {		/* Cybervision 8 bpp */
+	    320, 240, 320, 240, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1,
+	    0, FB_VMODE_DOUBLE
+	    }
+    },
+#endif
+
+#ifdef FBCON_HAS_CFB16
+    {
+	"320x240-16d", {	/* Cybervision 16 bpp */
+	    320, 240, 320, 240, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1,
+	    0, FB_VMODE_DOUBLE
+	    }
+    },
+#endif
 
+#ifdef FBCON_HAS_CFB32
+    {
+	"320x240-32d", {	/* Cybervision 32 bpp */
+	    320, 240, 320, 240, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1,
+	    0, FB_VMODE_DOUBLE
+	    }
+    },
+#endif
+};
 
-static int Cyberfb_inverse = 0;
+#define arraysize(x)	(sizeof(x)/sizeof(*(x)))
+#define NUM_TOTAL_MODES	arraysize(virgefb_predefined)
 
 /*
- *    Some default modes
+ *    Default to 800x600 for video=virge8:, virge16: or virge32:
  */
 
-#define VIRGE8_DEFMODE     (1)
-#define VIRGE16_DEFMODE    (7)
+#ifdef FBCON_HAS_CFB8
+#define VIRGE8_DEFMODE	(2)
+#endif
 
-static struct fb_var_screeninfo virgefb_default;
+#ifdef FBCON_HAS_CFB16
+#define VIRGE16_DEFMODE	(9)
+#endif
 
+#ifdef FBCON_HAS_CFB32
+#define VIRGE32_DEFMODE	(16)
+#endif
+
+static struct fb_var_screeninfo virgefb_default;
+static int virgefb_inverse = 0;
 
 /*
  *    Interface used by the world
  */
 
 int virgefb_setup(char*);
-
-static int virgefb_get_fix(struct fb_fix_screeninfo *fix, int con, struct
-fb_info *info);
-static int virgefb_get_var(struct fb_var_screeninfo *var, int con, struct
-fb_info *info);
-static int virgefb_set_var(struct fb_var_screeninfo *var, int con, struct
-fb_info *info);
+static int virgefb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			   struct fb_info *info);
+static int virgefb_get_var(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info);
+static int virgefb_set_var(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info);
 static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			    struct fb_info *info);
+			   struct fb_info *info);
 static int virgefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp, struct fb_info *info);
+			     u_int transp, struct fb_info *info);
 static int virgefb_blank(int blank, struct fb_info *info);
 
 /*
@@ -310,8 +660,8 @@
  */
 
 int virgefb_init(void);
-static int Cyberfb_switch(int con, struct fb_info *info);
-static int Cyberfb_updatevar(int con, struct fb_info *info);
+static int virgefb_switch(int con, struct fb_info *info);
+static int virgefb_updatevar(int con, struct fb_info *info);
 
 /*
  *    Text console acceleration
@@ -325,21 +675,29 @@
 static struct display_switch fbcon_virge16;
 #endif
 
+#ifdef FBCON_HAS_CFB32
+static struct display_switch fbcon_virge32;
+#endif
+
 /*
  *   Hardware Specific Routines
  */
 
-static int Cyber_init(void);
-static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
-                          struct virgefb_par *par);
-static int Cyber_decode_var(struct fb_var_screeninfo *var,
-                          struct virgefb_par *par);
-static int Cyber_encode_var(struct fb_var_screeninfo *var,
-                          struct virgefb_par *par);
-static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp, struct fb_info *info);
-static void Cyber_blank(int blank);
-
+static int virge_init(void);
+static int virgefb_encode_fix(struct fb_fix_screeninfo *fix,
+				struct virgefb_par *par);
+static int virgefb_decode_var(struct fb_var_screeninfo *var,
+				struct virgefb_par *par);
+static int virgefb_encode_var(struct fb_var_screeninfo *var,
+				struct virgefb_par *par);
+static int virgefb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+				u_int *transp, struct fb_info *info);
+static void virgefb_gfx_on_off(int blank);
+static inline void virgefb_wait_for_idle(void);
+static void virgefb_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
+		u_short width, u_short height, u_short stride, u_short depth);
+static void virgefb_RectFill(u_short x, u_short y, u_short width, u_short height,
+		u_short color, u_short stride, u_short depth);
 
 /*
  *    Internal routines
@@ -347,69 +705,249 @@
 
 static void virgefb_get_par(struct virgefb_par *par);
 static void virgefb_set_par(struct virgefb_par *par);
-static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
+static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
 static void virgefb_set_disp(int con, struct fb_info *info);
-static int get_video_mode(const char *name);
+static int virgefb_get_video_mode(const char *name);
+static void virgefb_set_video(struct fb_var_screeninfo *var);
 
+/*
+ *    Additions for Initialization
+ */
+
+static void virgefb_load_video_mode(struct fb_var_screeninfo *video_mode);
+static int cv3d_has_4mb(void);
+static unsigned short virgefb_compute_clock(unsigned long freq);
+static inline unsigned char rattr(short);
+static inline unsigned char rseq(short);
+static inline unsigned char rcrt(short);
+static inline unsigned char rgfx(short);
+static inline void gfx_on_off(int toggle);
+static void virgefb_pci_init(void);
 
 /* -------------------- Hardware specific routines ------------------------- */
 
+/*
+ *	Functions for register access
+ */
+
+/* Read attribute controller register */
+
+static inline unsigned char rattr(short idx)
+{
+	volatile unsigned char rattr_tmp;
+
+	rattr_tmp = rb_mmio(ACT_ADDRESS_RESET);
+	wb_mmio(ACT_ADDRESS_W, idx);
+	return (rb_mmio(ACT_ADDRESS_R));
+}
+
+/* Read sequencer register */
+
+static inline unsigned char rseq(short idx)
+{
+	wb_mmio(SEQ_ADDRESS, idx);
+	return (rb_mmio(SEQ_ADDRESS_R));
+}
+
+/* Read CRT controller register */
+
+static inline unsigned char rcrt(short idx)
+{
+	wb_mmio(CRT_ADDRESS, idx);
+	return (rb_mmio(CRT_ADDRESS_R));
+}
+
+/* Read graphics controller register */
+
+static inline unsigned char rgfx(short idx)
+{
+	wb_mmio(GCT_ADDRESS, idx);
+	return (rb_mmio(GCT_ADDRESS_R));
+}
+
 
 /*
- *    Initialization
- *
- *    Set the default video mode for this chipset. If a video mode was
- *    specified on the command line, it will override the default mode.
+ *	Initialization
  */
 
-static int Cyber_init(void)
+/* PCI init */
+
+void virgefb_pci_init(void) {
+
+	DPRINTK("ENTER\n");
+
+	SelectCFG;
+
+	if (on_zorro2) {
+		*((short *)(vgaio_regs + 0x00000010)) = 0;
+		*((long  *)(vgaio_regs + 0x00000004)) = 0x02000003;
+	} else {
+		*((short *)(vgaio_regs + 0x000e0010)) = 0;
+		*((long  *)(vgaio_regs + 0x000e0004)) = 0x02000003;
+	}
+
+	/* SelectIO is in wb_vgaio macro */
+	wb_vgaio(SREG_VIDEO_SUBS_ENABLE, 0x01);
+	/* SelectMMIO is in wb_vgaio macro */
+
+	DPRINTK("EXIT\n");
+
+	return;
+}
+
+/* 
+ * Initalize all mode independent regs, find mem size and clear mem
+*/
+
+static int virge_init(void)
 {
 	int i;
+	unsigned char tmp;
+
+	DPRINTK("ENTER\n");
+
+	virgefb_pci_init();
+
+	wb_mmio(GREG_MISC_OUTPUT_W, 0x07);	/* colour, ram enable, clk sel */
 
-	for (i = 0; i < 256; i++)
-	{
-		Cyber_colour_table [i][0] = i;
-		Cyber_colour_table [i][1] = i;
-		Cyber_colour_table [i][2] = i;
-	}
-
-	/*
-	 * Just clear the thing for the biggest mode.
-	 *
-	 * ++Andre, TODO: determine size first, then clear all memory
-	 *                (the 3D penguin might need texture memory :-) )
-	 */
+	wseq(SEQ_ID_UNLOCK_EXT, 0x06);		/* unlock extensions */
+	tmp = rb_mmio(GREG_MISC_OUTPUT_R);
+	wcrt(CRT_ID_REGISTER_LOCK_1, 0x48);	/* unlock CR2D to CR3F */
 
-	if (cv3d_on_zorro2) {
-		CyberSize = 0x00380000; /* 3.5 MB , we need some space for the registers? */
+	wcrt(CRT_ID_BACKWAD_COMP_1, 0x00);	/* irq disable */
+
+	wcrt(CRT_ID_REGISTER_LOCK_2, 0xa5);	/* unlock CR40 to CRFF and more */
+	wcrt(CRT_ID_REGISTER_LOCK,0x00);	/* unlock h and v timing */
+	wcrt(CRT_ID_SYSTEM_CONFIG, 0x01);	/* unlock enhanced programming registers */
+
+	wb_mmio(GREG_FEATURE_CONTROL_W, 0x00);
+
+	wcrt(CRT_ID_EXT_MISC_CNTL, 0x00);	/* b2 = 0 to allow VDAC mmio access */
+#if 0
+	/* write strap options ... ? */
+	wcrt(CRT_ID_CONFIG_1, 0x08);
+	wcrt(CRT_ID_CONFIG_2, 0xff);		/* 0x0x2 bit needs to be set ?? */
+	wcrt(CRT_ID_CONFIG_3, 0x0f);
+	wcrt(CRT_ID_CONFIG_4, 0x1a);
+#endif
+	wcrt(CRT_ID_EXT_MISC_CNTL_1, 0x82);	 /* PCI DE and software reset S3D engine */
+	/* EXT_MISC_CNTL_1, CR66 bit 0 should be the same as bit 0 MR_ADVANCED_FUNCTION_CONTROL - check */
+	wl_mmio(MR_ADVANCED_FUNCTION_CONTROL, 0x00000011); /* enhanced mode, linear addressing */
+
+/* crtc registers */
+
+	wcrt(CRT_ID_PRESET_ROW_SCAN, 0x00);
+
+	/* Disable h/w cursor */
+
+	wcrt(CRT_ID_CURSOR_START, 0x00);
+	wcrt(CRT_ID_CURSOR_END, 0x00);
+	wcrt(CRT_ID_START_ADDR_HIGH, 0x00);
+	wcrt(CRT_ID_START_ADDR_LOW, 0x00);
+	wcrt(CRT_ID_CURSOR_LOC_HIGH, 0x00);
+	wcrt(CRT_ID_CURSOR_LOC_LOW, 0x00);
+	wcrt(CRT_ID_EXT_MODE, 0x00);
+	wcrt(CRT_ID_HWGC_MODE, 0x00);
+	wcrt(CRT_ID_HWGC_ORIGIN_X_HI, 0x00);
+	wcrt(CRT_ID_HWGC_ORIGIN_X_LO, 0x00);
+	wcrt(CRT_ID_HWGC_ORIGIN_Y_HI, 0x00);
+	wcrt(CRT_ID_HWGC_ORIGIN_Y_LO, 0x00);
+	i = rcrt(CRT_ID_HWGC_MODE);
+	wcrt(CRT_ID_HWGC_FG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_FG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_FG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_BG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_BG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_BG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_START_AD_HI, 0x00);
+	wcrt(CRT_ID_HWGC_START_AD_LO, 0x00);
+	wcrt(CRT_ID_HWGC_DSTART_X, 0x00);
+	wcrt(CRT_ID_HWGC_DSTART_Y, 0x00);
+
+	wcrt(CRT_ID_UNDERLINE_LOC, 0x00);
+
+	wcrt(CRT_ID_MODE_CONTROL, 0xe3);
+	wcrt(CRT_ID_BACKWAD_COMP_2, 0x22);	/* blank bdr bit 5 blanking only on 8 bit */
+
+	wcrt(CRT_ID_EX_SYNC_1, 0x00);
+
+	/* memory */
+
+	wcrt(CRT_ID_EXT_SYS_CNTL_3, 0x00);
+	wcrt(CRT_ID_MEMORY_CONF, 0x08);		/* config enhanced map */
+	wcrt(CRT_ID_EXT_MEM_CNTL_1, 0x08);	/* MMIO Select (0x0c works as well)*/
+	wcrt(CRT_ID_EXT_MEM_CNTL_2, 0x02);	/* why 02 big endian 00 works ? */
+	wcrt(CRT_ID_EXT_MEM_CNTL_4, 0x9f);	/* config big endian - 0x00 ?  */
+	wcrt(CRT_ID_LAW_POS_HI, 0x00);
+	wcrt(CRT_ID_LAW_POS_LO, 0x00);
+	wcrt(CRT_ID_EXT_MISC_CNTL_1, 0x81);
+	wcrt(CRT_ID_MISC_1, 0x90);		/* must follow CRT_ID_EXT_MISC_CNTL_1 */
+	wcrt(CRT_ID_LAW_CNTL, 0x13);		/* force 4 Meg for test */
+	if (cv3d_has_4mb()) {
+		v_ram_size = 0x00400000;
+		wcrt(CRT_ID_LAW_CNTL, 0x13);	/* 4 MB */
 	} else {
-		CyberSize = 0x00400000; /* 4 MB */
+		v_ram_size = 0x00200000;
+		wcrt(CRT_ID_LAW_CNTL, 0x12); 	/* 2 MB */
+	}
+
+	if (on_zorro2)
+		v_ram_size -= 0x60000;		/* we need some space for the registers */
+
+	wcrt(CRT_ID_EXT_SYS_CNTL_4, 0x00);
+	wcrt(CRT_ID_EXT_DAC_CNTL, 0x00);	/* 0x10 for X11 cursor mode */
+
+/* sequencer registers */
+
+	wseq(SEQ_ID_CLOCKING_MODE, 0x01);	/* 8 dot clock */
+	wseq(SEQ_ID_MAP_MASK, 0xff);
+	wseq(SEQ_ID_CHAR_MAP_SELECT, 0x00);
+	wseq(SEQ_ID_MEMORY_MODE, 0x02);
+	wseq(SEQ_ID_RAMDAC_CNTL, 0x00);
+	wseq(SEQ_ID_SIGNAL_SELECT, 0x00);
+	wseq(SEQ_ID_EXT_SEQ_REG9, 0x00);	/* MMIO and PIO reg access enabled */
+	wseq(SEQ_ID_EXT_MISC_SEQ, 0x00);
+	wseq(SEQ_ID_CLKSYN_CNTL_1, 0x00);
+	wseq(SEQ_ID_EXT_SEQ, 0x00);
+
+/* graphic registers */
+
+	wgfx(GCT_ID_SET_RESET, 0x00);
+	wgfx(GCT_ID_ENABLE_SET_RESET, 0x00);
+	wgfx(GCT_ID_COLOR_COMPARE, 0x00);
+	wgfx(GCT_ID_DATA_ROTATE, 0x00);
+	wgfx(GCT_ID_READ_MAP_SELECT, 0x00);
+	wgfx(GCT_ID_GRAPHICS_MODE, 0x40);
+	wgfx(GCT_ID_MISC, 0x01);
+	wgfx(GCT_ID_COLOR_XCARE, 0x0f);
+	wgfx(GCT_ID_BITMASK, 0xff);
+
+/* attribute  registers */
+
+	for(i = 0; i <= 15; i++)
+		watr(ACT_ID_PALETTE0 + i, i);
+	watr(ACT_ID_ATTR_MODE_CNTL, 0x41);
+	watr(ACT_ID_OVERSCAN_COLOR, 0xff);
+	watr(ACT_ID_COLOR_PLANE_ENA, 0x0f);
+	watr(ACT_ID_HOR_PEL_PANNING, 0x00);
+	watr(ACT_ID_COLOR_SELECT, 0x00);
+
+	wb_mmio(VDAC_MASK, 0xff);
+
+/* init local cmap as greyscale levels */
+
+	for (i = 0; i < 256; i++) {
+		virgefb_colour_table [i][0] = i;
+		virgefb_colour_table [i][1] = i;
+		virgefb_colour_table [i][2] = i;
 	}
 
-	memset ((char*)CyberMem, 0, CyberSize);
+/* clear framebuffer memory */
 
-	/* Disable hardware cursor */
-	vgawb_3d(0x3c8, 255);
-	vgawb_3d(0x3c9, 56);
-	vgawb_3d(0x3c9, 100);
-	vgawb_3d(0x3c9, 160);
-
-	vgawb_3d(0x3c8, 254);
-	vgawb_3d(0x3c9, 0);
-	vgawb_3d(0x3c9, 0);
-	vgawb_3d(0x3c9, 0);
-
-	/* Disable hardware cursor */
-	vgawb_3d(S3_CRTC_ADR, S3_REG_LOCK2);
-	vgawb_3d(S3_CRTC_DATA, 0xa0);
-	vgawb_3d(S3_CRTC_ADR, S3_HGC_MODE);
-	vgawb_3d(S3_CRTC_DATA, 0x00);
-	vgawb_3d(S3_CRTC_ADR, S3_HWGC_DX);
-	vgawb_3d(S3_CRTC_DATA, 0x00);
-	vgawb_3d(S3_CRTC_ADR, S3_HWGC_DY);
-	vgawb_3d(S3_CRTC_DATA, 0x00);
+	memset((char*)v_ram, 0x00, v_ram_size);
 
-	return 0; /* TODO: hardware cursor for CV64/3D */
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -418,30 +956,49 @@
  *    values in the `par' structure.
  */
 
-static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
+static int virgefb_encode_fix(struct fb_fix_screeninfo *fix,
 			    struct virgefb_par *par)
 {
+	DPRINTK("ENTER set video phys addr\n");
+
 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 	strcpy(fix->id, virgefb_name);
-	if (cv3d_on_zorro2) {
-		fix->smem_start = CyberMem_phys;
-	} else {
-		switch (par->bpp) {
-			case 8:
-				fix->smem_start = (CyberMem_phys + CYBMEM_OFFSET_8);
-				break;
-			case 16:
-				fix->smem_start = (CyberMem_phys + CYBMEM_OFFSET_16);
-				break;
-		}
+	if (on_zorro2)
+		fix->smem_start = v_ram_phys;
+	switch (par->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+		case 8:
+			if (on_zorro2)
+				Select_Zorro2_FrameBuffer(ENDIAN_BYTE);
+			else
+				fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_8);
+			break;
+#endif
+#ifdef FBCON_HAS_CFB16
+		case 16:
+			if (on_zorro2)
+				Select_Zorro2_FrameBuffer(ENDIAN_WORD);
+			else
+				fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_16);
+			break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			if (on_zorro2)
+				Select_Zorro2_FrameBuffer(ENDIAN_LONG);
+			else
+				fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_32);
+			break;
+#endif
 	}
-	fix->smem_len = CyberSize;
-	fix->mmio_start = CyberRegs_phys;
+
+	fix->smem_len = v_ram_size;
+	fix->mmio_start = mmio_regs_phys;
 	fix->mmio_len = 0x10000; /* TODO: verify this for the CV64/3D */
 
 	fix->type = FB_TYPE_PACKED_PIXELS;
 	fix->type_aux = 0;
-	if (par->bpp == 8)
+	if (par->var.bits_per_pixel == 8)
 		fix->visual = FB_VISUAL_PSEUDOCOLOR;
 	else
 		fix->visual = FB_VISUAL_TRUECOLOR;
@@ -449,116 +1006,117 @@
 	fix->xpanstep = 0;
 	fix->ypanstep = 0;
 	fix->ywrapstep = 0;
-	fix->line_length = 0;
+	fix->line_length = par->var.xres_virtual*par->var.bits_per_pixel/8;
 	fix->accel = FB_ACCEL_S3_VIRGE;
-	return(0);
+	DPRINTK("EXIT v_ram_phys = 0x%8.8lx\n", (unsigned long)fix->smem_start);
+	return 0;
 }
 
 
 /*
- *    Get the video params out of `var'. If a value doesn't fit, round
- *    it up, if it's too big, return -EINVAL.
+ *	Fill the `par' structure based on the values in `var'.
+ *	TODO: Verify and adjust values, return -EINVAL if bad.
  */
 
-static int Cyber_decode_var(struct fb_var_screeninfo *var,
+static int virgefb_decode_var(struct fb_var_screeninfo *var,
 			    struct virgefb_par *par)
 {
-#if 1
-	par->xres = var->xres;
-	par->yres = var->yres;
-	par->bpp = var->bits_per_pixel;
-	if (var->accel_flags & FB_ACCELF_TEXT)
-	    par->accel = FB_ACCELF_TEXT;
+	DPRINTK("ENTER\n");
+	par->var.xres = var->xres;
+	par->var.yres = var->yres;
+	par->var.xres_virtual = var->xres_virtual;
+	par->var.yres_virtual = var->yres_virtual;
+	/* roundup and validate */
+	par->var.xres = (par->var.xres+7) & ~7;
+	par->var.xres_virtual = (par->var.xres_virtual+7) & ~7;
+	if (par->var.xres_virtual < par->var.xres)
+		par->var.xres_virtual = par->var.xres;
+	if (par->var.yres_virtual < par->var.yres)
+		par->var.yres_virtual = par->var.yres;
+	par->var.xoffset = var->xoffset;
+	par->var.yoffset = var->yoffset;
+	par->var.bits_per_pixel = var->bits_per_pixel;
+	if (par->var.bits_per_pixel <= 8)
+		par->var.bits_per_pixel = 8;
+	else if (par->var.bits_per_pixel <= 16)
+		par->var.bits_per_pixel = 16;
 	else
-	    par->accel = 0;
-#else
-	if (Cyberfb_Cyber8) {
-		par->xres = VIRGE8_WIDTH;
-		par->yres = VIRGE8_HEIGHT;
-		par->bpp = 8;
+		par->var.bits_per_pixel = 32;
+#ifndef FBCON_HAS_CFB32
+	if (par->var.bits_per_pixel == 32)
+		par->var.bits_per_pixel = 16;
+#endif
+#ifndef FBCON_HAS_CFB16
+	if (par->var.bits_per_pixel == 16)
+		par->var.bits_per_pixel = 8;
+#endif
+	par->var.grayscale = var->grayscale;
+	par->var.red = var->red;
+	par->var.green = var->green;
+	par->var.blue = var->blue;
+	par->var.transp = var->transp;
+	par->var.nonstd = var->nonstd;
+	par->var.activate = var->activate;
+	par->var.height = var->height;
+	par->var.width = var->width;
+	if (var->accel_flags & FB_ACCELF_TEXT) {
+		par->var.accel_flags = FB_ACCELF_TEXT;
 	} else {
-		par->xres = VIRGE16_WIDTH;
-		par->yres = VIRGE16_HEIGHT;
-		par->bpp = 16;
+		par->var.accel_flags = 0;
 	}
-#endif
-	return(0);
+	par->var.pixclock = var->pixclock;
+	par->var.left_margin = var->left_margin;
+	par->var.right_margin = var->right_margin;
+	par->var.upper_margin = var->upper_margin;
+	par->var.lower_margin = var->lower_margin;
+	par->var.hsync_len = var->hsync_len;
+	par->var.vsync_len = var->vsync_len;
+	par->var.sync = var->sync;
+	par->var.vmode = var->vmode;
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
-
 /*
- *    Fill the `var' structure based on the values in `par' and maybe
- *    other values read out of the hardware.
+ *	Fill the `var' structure based on the values in `par' and maybe
+ *	other values read out of the hardware.
  */
 
-static int Cyber_encode_var(struct fb_var_screeninfo *var,
-			    struct virgefb_par *par)
+static int virgefb_encode_var(struct fb_var_screeninfo *var,
+				struct virgefb_par *par)
 {
-	memset(var, 0, sizeof(struct fb_var_screeninfo));
-	var->xres = par->xres;
-	var->yres = par->yres;
-	var->xres_virtual = par->xres;
-	var->yres_virtual = par->yres;
-	var->xoffset = 0;
-	var->yoffset = 0;
-
-	var->bits_per_pixel = par->bpp;
-	var->grayscale = 0;
-
-	switch (var->bits_per_pixel) {
-		case 8:		/* CLUT */
-			var->red.offset = 0;
-			var->red.length = 6;
-			var->red.msb_right = 0;
-			var->blue = var->green = var->red;
-			break;
-		case 16:	/* RGB 565 */
-			var->red.offset = 11;
-			var->red.length = 5;
-			var->green.offset = 5;
-			var->green.length = 6;
-			var->blue.offset = 0;
-			var->blue.length = 5;
-			var->transp.offset = 0;
-			var->transp.length = 0;
-			break;
-	}
-	var->red.msb_right = 0;
-	var->green.msb_right = 0;
-	var->blue.msb_right = 0;
-	var->transp.msb_right = 0;
-
-	var->nonstd = 0;
-	var->activate = 0;
-
-	var->height = -1;
-	var->width = -1;
-
- 	var->accel_flags = (par->accel &&
-		((par->bpp == 8) || (par->bpp == 16))) ? FB_ACCELF_TEXT : 0;
-
-/*	printk("CV64/3D : %s\n",(var->accel_flags ? "accel" : "no accel")); */
-
-	var->vmode = FB_VMODE_NONINTERLACED;
-
-	/* Dummy values */
-
-	if (par->bpp == 8)
-		var->pixclock = VIRGE8_PIXCLOCK;
-	else
-		var->pixclock = VIRGE16_PIXCLOCK;
-	var->sync = 0;
-	var->left_margin = 64;
-	var->right_margin = 96;
-	var->upper_margin = 35;
-	var->lower_margin = 12;
-	var->hsync_len = 112;
-	var->vsync_len = 2;
-
-	return(0);
+	DPRINTK("ENTER\n");
+	memset(var, 0, sizeof(struct fb_var_screeninfo));	/* need this ? */
+	var->xres = par->var.xres;
+	var->yres = par->var.yres;
+	var->xres_virtual = par->var.xres_virtual;
+	var->yres_virtual = par->var.yres_virtual;
+	var->xoffset = par->var.xoffset;
+	var->yoffset = par->var.yoffset;
+	var->bits_per_pixel = par->var.bits_per_pixel;
+	var->grayscale = par->var.grayscale;
+	var->red = par->var.red;
+	var->green = par->var.green;
+	var->blue = par->var.blue;
+	var->transp = par->var.transp;
+	var->nonstd = par->var.nonstd;
+	var->activate = par->var.activate;
+	var->height = par->var.height;
+	var->width = par->var.width;
+	var->accel_flags = par->var.accel_flags;
+	var->pixclock = par->var.pixclock;
+	var->left_margin = par->var.left_margin;
+	var->right_margin = par->var.right_margin;
+	var->upper_margin = par->var.upper_margin;
+	var->lower_margin = par->var.lower_margin;
+	var->hsync_len = par->var.hsync_len;
+	var->vsync_len = par->var.vsync_len;
+	var->sync = par->var.sync;
+	var->vmode = par->var.vmode;
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
-
 /*
  *    Set a single color register. The values supplied are already
  *    rounded down to the hardware's capabilities (according to the
@@ -568,23 +1126,26 @@
 static int virgefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 			     u_int transp, struct fb_info *info)
 {
-	if (((current_par.bpp==8) && (regno>255)) ||
-		((current_par.bpp!=8) && (regno>15)))
-			return (1);
-
-	if (((current_par.bpp==8) && (regno<256)) || ((current_par.bpp==16) &&(regno<16))) {
-		Cyber_colour_table [regno][0] = red >> 10;
-		Cyber_colour_table [regno][1] = green >> 10;
-		Cyber_colour_table [regno][2] = blue >> 10;
+	DPRINTK("ENTER\n");
+	if (((current_par.var.bits_per_pixel==8) && (regno>255)) ||
+		((current_par.var.bits_per_pixel!=8) && (regno>15))) {
+			DPRINTK("EXIT\n");
+			return 1;
+	}
+	if (((current_par.var.bits_per_pixel==8) && (regno<256)) ||
+			((current_par.var.bits_per_pixel!=8) && (regno<16))) {
+		virgefb_colour_table [regno][0] = red >> 10;
+		virgefb_colour_table [regno][1] = green >> 10;
+		virgefb_colour_table [regno][2] = blue >> 10;
 	}
 
-	switch (current_par.bpp) {
+	switch (current_par.var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
 		case 8:
-			vgawb_3d(0x3c8, (unsigned char) regno);
-			vgawb_3d(0x3c9, ((unsigned char) (red >> 10)));
-			vgawb_3d(0x3c9, ((unsigned char) (green >> 10)));
-			vgawb_3d(0x3c9, ((unsigned char) (blue >> 10)));
+			wb_mmio(VDAC_ADDRESS_W, (unsigned char)regno);
+			wb_mmio(VDAC_DATA, ((unsigned char)(red >> 10)));
+			wb_mmio(VDAC_DATA, ((unsigned char)(green >> 10)));
+			wb_mmio(VDAC_DATA, ((unsigned char)(blue >> 10)));
 			break;
 #endif
 #ifdef FBCON_HAS_CFB16
@@ -595,8 +1156,18 @@
 				((blue  & 0xf800) >> 11));
 			break;
 #endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			fbcon_cmap.cfb32[regno] =
+				/* transp = 0's or 1's  ? */
+				(((red  & 0xff00) << 8) |
+				((green & 0xff00) >> 0) |
+				((blue  & 0xff00) >> 8));
+			break;
+#endif
 	}
-	return (0);
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -605,25 +1176,29 @@
  *    colors/transparent. Return != 0 for invalid regno.
  */
 
-static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+static int virgefb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
 			   u_int *transp, struct fb_info *info)
 {
 	int t;
 
-	if (regno > 255)
-		return (1);
-
-	if (((current_par.bpp==8) && (regno<256)) || ((current_par.bpp==16) && (regno<16))) {
-
-		t = Cyber_colour_table [regno][0];
-		*red    = (t<<10) | (t<<4) | (t>>2);
-		t = Cyber_colour_table [regno][1];
-		*green  = (t<<10) | (t<<4) | (t>>2);
-		t = Cyber_colour_table [regno][2];
-		*blue   = (t<<10) | (t<<4) | (t>>2);
+	DPRINTK("ENTER\n");
+	if (regno > 255) {
+		DPRINTK("EXIT\n");
+		return 1;
+	}
+	if (((current_par.var.bits_per_pixel==8) && (regno<256)) ||
+			((current_par.var.bits_per_pixel!=8) && (regno<16))) {
+
+		t = virgefb_colour_table [regno][0];
+		*red = (t<<10) | (t<<4) | (t>>2);
+		t = virgefb_colour_table [regno][1];
+		*green = (t<<10) | (t<<4) | (t>>2);
+		t = virgefb_colour_table [regno][2];
+		*blue = (t<<10) | (t<<4) | (t>>2);
 	}
 	*transp = 0;
-	return (0);
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -631,75 +1206,37 @@
  *    (Un)Blank the screen
  */
 
-void Cyber_blank(int blank)
+static void virgefb_gfx_on_off(int blank)
 {
-	int i;
-
-	if (blank)
-	{
-		for (i = 0; i < 256; i++)
-		{
-			vgawb_3d(0x3c8, (unsigned char) i);
-			vgawb_3d(0x3c9, 0);
-			vgawb_3d(0x3c9, 0);
-			vgawb_3d(0x3c9, 0);
-		}
-	}
-	else
-	{
-		for (i = 0; i < 256; i++)
-		{
-			vgawb_3d(0x3c8, (unsigned char) i);
-			vgawb_3d(0x3c9, Cyber_colour_table[i][0]);
-			vgawb_3d(0x3c9, Cyber_colour_table[i][1]);
-			vgawb_3d(0x3c9, Cyber_colour_table[i][2]);
-		}
-	}
+	DPRINTK("ENTER\n");
+	gfx_on_off(blank);
+	DPRINTK("EXIT\n");
 }
 
 /*
  * CV3D low-level support
  */
 
-#define Cyber3D_WaitQueue(v) \
-{ \
-	 do { \
-		while ((rl_3d(0x8504) & 0x1f00) < (((v)+2) << 8)); \
-	 } \
-	while (0); \
-}
 
-static inline void Cyber3D_WaitBusy(void)
+static inline void wait_3d_fifo_slots(int n)	/* WaitQueue */
 {
-unsigned long status;
-
 	do {
 		mb();
-		status = rl_3d(0x8504);
-	} while (!(status & (1 << 13)));
-	blit_maybe_busy = 0;
+	} while (((rl_mmio(MR_SUBSYSTEM_STATUS_R) >> 8) & 0x1f) < (n + 2));
 }
 
-#define S3V_BITBLT	(0x0 << 27)
-#define S3V_RECTFILL	(0x2 << 27)
-#define S3V_AUTOEXE	0x01
-#define S3V_HWCLIP	0x02
-#define S3V_DRAW	0x20
-#define S3V_DST_8BPP	0x00
-#define S3V_DST_16BPP	0x04
-#define S3V_DST_24BPP	0x08
-#define S3V_MONO_PAT	0x100
-
-#define S3V_BLT_COPY	(0xcc<<17)
-#define S3V_BLT_CLEAR	(0x00<<17)
-#define S3V_BLT_SET	(0xff<<17)
+static inline void virgefb_wait_for_idle(void)	/* WaitIdle */
+{
+	while(!(rl_mmio(MR_SUBSYSTEM_STATUS_R) & 0x2000)) ;
+	blit_maybe_busy = 0;
+}
 
  /*
   * BitBLT - Through the Plane
   */
 
-static void Cyber3D_BitBLT(u_short curx, u_short cury, u_short destx,
-			   u_short desty, u_short width, u_short height, u_short depth)
+static void virgefb_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
+			u_short width, u_short height, u_short stride, u_short depth)
 {
 	unsigned int blitcmd = S3V_BITBLT | S3V_DRAW | S3V_BLT_COPY;
 
@@ -714,61 +1251,56 @@
 			blitcmd |= S3V_DST_16BPP;
 			break;
 #endif
+#ifdef FBCON_HAS_CFB32
+		case 32 :
+			/* 32 bit uses 2 by 16 bit values, see fbcon_virge32_bmove */
+			blitcmd |= S3V_DST_16BPP;
+			break;
+#endif
 	}
 
 	/* Set drawing direction */
 	/* -Y, X maj, -X (default) */
-	if (curx > destx)
-	{
+	if (curx > destx) {
 		blitcmd |= (1 << 25);  /* Drawing direction +X */
-	}
-	else
-	{
+	} else {
 		curx  += (width - 1);
 		destx += (width - 1);
 	}
 
-	if (cury > desty)
-	{
+	if (cury > desty) {
 		blitcmd |= (1 << 26);  /* Drawing direction +Y */
-	}
-	else
-	{
+	} else {
 		cury  += (height - 1);
 		desty += (height - 1);
 	}
 
+	wait_3d_fifo_slots(8);		/* wait on fifo slots for 8 writes */
+
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	blit_maybe_busy = 1;
 
-	wl_3d(0xa4f4, 1); /* pattern fb color */
-
-	wl_3d(0xa4e8, ~0); /* mono pat 0 */
-	wl_3d(0xa4ec, ~0); /* mono pat 1 */
-
-	wl_3d(0xa504, ((width << 16) | height));	/* rwidth_height */
-	wl_3d(0xa508, ((curx << 16)  | cury));		/* rsrc_xy */
-	wl_3d(0xa50c, ((destx << 16) | desty));		/* rdest_xy */
-
-	wl_3d(0xa500, blitcmd);				/* GO! */
+	wl_mmio(BLT_PATTERN_COLOR, 1);	/* pattern fb color */
+	wl_mmio(BLT_MONO_PATTERN_0, ~0);
+	wl_mmio(BLT_MONO_PATTERN_1, ~0);
+	wl_mmio(BLT_SIZE_X_Y, ((width << 16) | height));
+	wl_mmio(BLT_SRC_X_Y, ((curx << 16)  | cury));
+	wl_mmio(BLT_DEST_X_Y, ((destx << 16) | desty));
+	wl_mmio(BLT_SRC_DEST_STRIDE, (((stride << 16) | stride) /* & 0x0ff80ff8 */)); /* why is this needed now ? */
+	wl_mmio(BLT_COMMAND_SET, blitcmd);
 }
 
 /*
  * Rectangle Fill Solid
  */
 
-static void Cyber3D_RectFill(u_short x, u_short y, u_short width,
-			     u_short height, u_short color, u_short depth)
+static void virgefb_RectFill(u_short x, u_short y, u_short width, u_short height,
+			u_short color,  u_short stride, u_short depth)
 {
-	unsigned int tmp;
 	unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW |
 		S3V_BLT_CLEAR | S3V_MONO_PAT | (1 << 26) | (1 << 25);
 
-	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
-	blit_maybe_busy = 1;
-
 	switch (depth) {
 #ifdef FBCON_HAS_CFB8
 		case 8 :
@@ -780,36 +1312,48 @@
 			blitcmd |= S3V_DST_16BPP;
 			break;
 #endif
+#ifdef FBCON_HAS_CFB32
+		case 32 :
+			/* 32 bit uses 2 times 16 bit values, see fbcon_virge32_clear */
+			blitcmd |= S3V_DST_16BPP;
+			break;
+#endif
 	}
 
-	tmp = color & 0xff;
-	wl_3d(0xa4f4, tmp);
+	wait_3d_fifo_slots(5);		/* wait on fifo slots for 5 writes */
 
-	wl_3d(0xa504, ((width << 16) | height));	/* rwidth_height */
-	wl_3d(0xa50c, ((x << 16) | y));			/* rdest_xy */
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	blit_maybe_busy = 1;
 
-	wl_3d(0xa500, blitcmd);				/* GO! */
+	wl_mmio(BLT_PATTERN_COLOR, (color & 0xff));
+	wl_mmio(BLT_SIZE_X_Y, ((width << 16) | height));
+	wl_mmio(BLT_DEST_X_Y, ((x << 16) | y));
+	wl_mmio(BLT_SRC_DEST_STRIDE, (((stride << 16) | stride) /* & 0x0ff80ff8 */));
+	wl_mmio(BLT_COMMAND_SET, blitcmd);
 }
 
-
-/**************************************************************
+/*
  * Move cursor to x, y
  */
 
 #if 0
-static void Cyber_MoveCursor (u_short x, u_short y)
+static void virgefb_move_cursor(u_short x, u_short y)
 {
-	printk(KERN_DEBUG "Yuck .... MoveCursor on a 3D\n");
-	return;
+	DPRINTK("Yuck .... MoveCursor on a 3D\n");
+	return 0;
 }
 #endif
 
 /* -------------------- Interfaces to hardware functions -------------------- */
 
-
-static struct fb_hwswitch Cyber_switch = {
-	Cyber_init, Cyber_encode_fix, Cyber_decode_var, Cyber_encode_var,
-	Cyber_getcolreg, Cyber_blank
+static struct fb_hwswitch virgefb_hw_switch = {
+	init:		virge_init,
+	encode_fix:	virgefb_encode_fix,
+	decode_var:	virgefb_decode_var,
+	encode_var:	virgefb_encode_var,
+	getcolreg:	virgefb_getcolreg,
+	blank:		virgefb_gfx_on_off
 };
 
 
@@ -822,54 +1366,75 @@
 
 static void virgefb_get_par(struct virgefb_par *par)
 {
-	if (current_par_valid)
-	{
+	DPRINTK("ENTER\n");
+	if (current_par_valid) {
 		*par = current_par;
-	}
-	else
-	{
+	} else {
 		fbhw->decode_var(&virgefb_default, par);
 	}
+	DPRINTK("EXIT\n");
 }
 
 
 static void virgefb_set_par(struct virgefb_par *par)
 {
+	DPRINTK("ENTER\n");
 	current_par = *par;
 	current_par_valid = 1;
+	DPRINTK("EXIT\n");
 }
 
 
-static void virge_set_video(struct fb_var_screeninfo *var)
+static void virgefb_set_video(struct fb_var_screeninfo *var)
 {
-	/* Set clipping rectangle to current screen size */
- 
+/* Set clipping rectangle to current screen size */
+
 	unsigned int clip;
 
+	DPRINTK("ENTER\n");
+	wait_3d_fifo_slots(4);
 	clip = ((0 << 16) | (var->xres - 1));
-	wl_3d(0xa4dc, clip);
+	wl_mmio(BLT_CLIP_LEFT_RIGHT, clip);
 	clip = ((0 << 16) | (var->yres - 1));
-	wl_3d(0xa4e0, clip);
+	wl_mmio(BLT_CLIP_TOP_BOTTOM, clip);
+	wl_mmio(BLT_SRC_BASE, 0);		/* seems we need to clear these two */
+	wl_mmio(BLT_DEST_BASE, 0);
+
+/* Load the video mode defined by the 'var' data */
+
+	virgefb_load_video_mode(var);
+	DPRINTK("EXIT\n");
 }
 
+/*
+Merge these two functions, Geert's suggestion.
+static int virgefb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info);
+static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
+*/
 
-static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
+static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
 {
 	int err, activate;
 	struct virgefb_par par;
 
-	if ((err = fbhw->decode_var(var, &par)))
-		return(err);
+	DPRINTK("ENTER\n");
+	if ((err = fbhw->decode_var(var, &par))) {
+		DPRINTK("EXIT\n");
+		return (err);
+	}
+
 	activate = var->activate;
 	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
 		virgefb_set_par(&par);
 	fbhw->encode_var(var, &par);
 	var->activate = activate;
-
-	virge_set_video(var);
+        if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
+		virgefb_set_video(var);
+	DPRINTK("EXIT\n");
 	return 0;
 }
 
+
 /*
  *    Get the Fixed Part of the Display
  */
@@ -880,11 +1445,16 @@
 	struct virgefb_par par;
 	int error = 0;
 
+	DPRINTK("ENTER\n");
 	if (con == -1)
 		virgefb_get_par(&par);
 	else
 		error = fbhw->decode_var(&fb_display[con].var, &par);
-	return(error ? error : fbhw->encode_fix(fix, &par));
+
+	if (!error)
+		error = fbhw->encode_fix(fix, &par);
+	DPRINTK("EXIT\n");
+	return(error);
 }
 
 
@@ -898,26 +1468,24 @@
 	struct virgefb_par par;
 	int error = 0;
 
-	if (con == -1)
-	{
+	DPRINTK("ENTER\n");
+	if (con == -1) {
 		virgefb_get_par(&par);
 		error = fbhw->encode_var(var, &par);
 		disp.var = *var;   /* ++Andre: don't know if this is the right place */
-	}
-	else
-	{
+	} else {
 		*var = fb_display[con].var;
 	}
-
+	DPRINTK("EXIT\n");
 	return(error);
 }
 
-
 static void virgefb_set_disp(int con, struct fb_info *info)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
 
+	DPRINTK("ENTER\n");
 	if (con >= 0)
 		display = &fb_display[con];
 	else
@@ -926,16 +1494,25 @@
 	virgefb_get_fix(&fix, con, info);
 	if (con == -1)
 		con = 0;
-	if (cv3d_on_zorro2) {
-		info->screen_base = (char*) CyberMem;
+	if(on_zorro2) {
+		info->screen_base = (char*)v_ram;
 	} else {
 	        switch (display->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
 			case 8:
-				info->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_8);
+				info->screen_base = (char*)(v_ram + CYBMEM_OFFSET_8);
 				break;
+#endif
+#ifdef FBCON_HAS_CFB16
 			case 16:
-				info->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_16);
+				info->screen_base = (char*)(v_ram + CYBMEM_OFFSET_16);
+				break;
+#endif
+#ifdef FBCON_HAS_CFB32
+			case 32:
+				info->screen_base = (char*)(v_ram + CYBMEM_OFFSET_32);
 				break;
+#endif
 		}
 	}
 	display->visual = fix.visual;
@@ -944,7 +1521,10 @@
 	display->ypanstep = fix.ypanstep;
 	display->ywrapstep = fix.ywrapstep;
 	display->can_soft_blank = 1;
-	display->inverse = Cyberfb_inverse;
+	display->inverse = virgefb_inverse;
+	display->line_length = display->var.xres_virtual*
+			       display->var.bits_per_pixel/8;
+
 	switch (display->var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
 		case 8:
@@ -964,10 +1544,20 @@
 			display->dispsw_data = &fbcon_cmap.cfb16;
 			break;
 #endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			if (display->var.accel_flags & FB_ACCELF_TEXT) {
+				display->dispsw = &fbcon_virge32;
+			} else
+				display->dispsw = &fbcon_cfb32;
+			display->dispsw_data = &fbcon_cmap.cfb32;
+			break;
+#endif
 		default:
 			display->dispsw = &fbcon_dummy;
 			break;
 	}
+	DPRINTK("EXIT v_ram virt = 0x%8.8lx\n",(unsigned long)display->screen_base);
 }
 
 
@@ -980,8 +1570,12 @@
 {
 	int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
 
-	if ((err = do_fb_set_var(var, con == info->currcon)))
+	DPRINTK("ENTER\n");
+
+	if ((err = virgefb_do_fb_set_var(var, con == info->currcon))) {
+		DPRINTK("EXIT\n");
 		return(err);
+	}
 	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
 		oldxres = fb_display[con].var.xres;
 		oldyres = fb_display[con].var.yres;
@@ -996,13 +1590,15 @@
 		    oldbpp != var->bits_per_pixel ||
 		    oldaccel != var->accel_flags) {
 			virgefb_set_disp(con, info);
-			(*fb_info.changevar)(con);
+			if (fb_info.changevar)
+				(*fb_info.changevar)(con);
 			fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
 			do_install_cmap(con, info);
 		}
 	}
 	var->activate = 0;
-	return(0);
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -1013,23 +1609,19 @@
 static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
 			    struct fb_info *info)
 {
-	if (con == info->currcon) /* current console? */
+	DPRINTK("ENTER\n");
+	if (con == info->currcon) { /* current console? */
+		DPRINTK("EXIT - console is current console, fb_get_cmap\n");
 		return(fb_get_cmap(cmap, kspc, fbhw->getcolreg, info));
-	else if (fb_display[con].cmap.len) /* non default colormap? */
+	} else if (fb_display[con].cmap.len) { /* non default colormap? */
+		DPRINTK("Use console cmap\n");
 		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-	else
-		fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+	} else {
+		DPRINTK("Use default cmap\n");
+		fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel==8 ? 256 : 16),
 			     cmap, kspc ? 0 : 2);
-	return(0);
-}
-
-/*
- *    Blank the display.
- */
-
-static int virgefb_blank(int blank, struct fb_info *info)
-{
-	fbhw->blank(blank);
+	}
+	DPRINTK("EXIT\n");
 	return 0;
 }
 
@@ -1047,141 +1639,196 @@
 int __init virgefb_setup(char *options)
 {
 	char *this_opt;
-
 	fb_info.fontname[0] = '\0';
 
-	if (!options || !*options)
+	DPRINTK("ENTER\n");
+	if (!options || !*options) {
+		DPRINTK("EXIT\n");
 		return 0;
+	}
 
 	while ((this_opt = strsep(&options, ",")) != NULL) {
 		if (!*this_opt)
 			continue;
 		if (!strcmp(this_opt, "inverse")) {
-			Cyberfb_inverse = 1;
+			virgefb_inverse = 1;
 			fb_invert_cmaps();
 		} else if (!strncmp(this_opt, "font:", 5))
 			strcpy(fb_info.fontname, this_opt+5);
+#ifdef FBCON_HAS_CFB8
 		else if (!strcmp (this_opt, "virge8")){
 			virgefb_default = virgefb_predefined[VIRGE8_DEFMODE].var;
 		}
+#endif
+#ifdef FBCON_HAS_CFB16
 		else if (!strcmp (this_opt, "virge16")){
 			virgefb_default = virgefb_predefined[VIRGE16_DEFMODE].var;
 		}
+#endif
+#ifdef FBCON_HAS_CFB32
+		else if (!strcmp (this_opt, "virge32")){
+			virgefb_default = virgefb_predefined[VIRGE32_DEFMODE].var;
+		}
+#endif
 		else
-			get_video_mode(this_opt);
+			virgefb_get_video_mode(this_opt);
 	}
 
-	DPRINTK("default mode: xres=%d, yres=%d, bpp=%d\n",virgefb_default.xres,
-                                                           virgefb_default.yres,
-		                                           virgefb_default.bits_per_pixel);
+	printk(KERN_INFO "mode : xres=%d, yres=%d, bpp=%d\n", virgefb_default.xres,
+			virgefb_default.yres, virgefb_default.bits_per_pixel);
+	DPRINTK("EXIT\n");
 	return 0;
 }
 
 
 /*
+ *    Get a Video Mode
+ */
+
+static int __init virgefb_get_video_mode(const char *name)
+{
+	int i;
+
+	DPRINTK("ENTER\n");
+	for (i = 0; i < NUM_TOTAL_MODES; i++) {
+		if (!strcmp(name, virgefb_predefined[i].name)) {
+			virgefb_default = virgefb_predefined[i].var;
+			DPRINTK("EXIT\n");
+			return(i);
+		}
+	}
+	/* ++Andre: set virgefb default mode */
+
+/* prefer 16 bit depth, 8 if no 16, if no 8 or 16 use 32 */
+
+#ifdef FBCON_HAS_CFB32
+	virgefb_default = virgefb_predefined[VIRGE32_DEFMODE].var;
+#endif
+#ifdef FBCON_HAS_CFB8
+	virgefb_default = virgefb_predefined[VIRGE8_DEFMODE].var;
+#endif
+#ifdef FBCON_HAS_CFB16
+	virgefb_default = virgefb_predefined[VIRGE16_DEFMODE].var;
+#endif
+	DPRINTK("EXIT\n");
+	return 0;
+}
+
+/*
  *    Initialization
  */
 
 int __init virgefb_init(void)
 {
 	struct virgefb_par par;
-	unsigned long board_addr, ramsize;
+	unsigned long board_addr, board_size;
 	struct zorro_dev *z = NULL;
 
-	while ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64_3D, z))) {
-	    board_addr = z->resource.start;
-	    if (board_addr < 0x01000000) {
-		/*
-		 * Ok we got the board running in Z2 space.
-		 */
-		 CyberRegs_phys = (unsigned long)(board_addr + 0x003e0000);
-		 CyberMem_phys = board_addr;
-		 ramsize = 0x00380000;
-	    } else {
-		CyberRegs_phys = board_addr + 0x05000000;
-		CyberMem_phys  = board_addr + 0x04000000;	/* was 0x04800000 */
-		ramsize = 0x00400000;
-	    }
-	    if (!request_mem_region(CyberRegs_phys, 0x10000, "S3 ViRGE"))
-		continue;
-	    if (!request_mem_region(CyberMem_phys, ramsize, "RAM")) {
-		release_mem_region(CyberRegs_phys, 0x10000);
-		continue;
-	    }
-
-	    if (board_addr < 0x01000000) {
-		/*
-		 * Ok we got the board running in Z2 space.
-		 */
-
-		CyberMem = ZTWO_VADDR(CyberMem_phys);
-		CyberVGARegs = (unsigned long) \
-			ZTWO_VADDR(board_addr + 0x003c0000);
-		CyberRegs = (unsigned char *)ZTWO_VADDR(CyberRegs_phys);
-		Cyber_register_base = (unsigned long) \
-			ZTWO_VADDR(board_addr + 0x003c8000);
-		Cyber_vcode_switch_base = (unsigned long) \
-			ZTWO_VADDR(board_addr + 0x003a0000);
-		cv3d_on_zorro2 = 1;
+	DPRINTK("ENTER\n");
+
+	z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64_3D, NULL);
+	if (!z)
+		return -ENODEV;
+
+	board_addr = z->resource.start;
+	if (board_addr < 0x01000000) {
+
+		/* board running in Z2 space. This includes the video memory
+		    as well as the S3 register set */
+
+		on_zorro2 = 1;
+		board_size = 0x00400000;
+
+		if (!request_mem_region(board_addr, board_size, "S3 ViRGE"))
+			return -ENOMEM;
+
+		v_ram_phys = board_addr;
+		v_ram = ZTWO_VADDR(v_ram_phys);
+		mmio_regs_phys = (unsigned long)(board_addr + 0x003c0000);
+		vgaio_regs = (unsigned char *) ZTWO_VADDR(board_addr + 0x003c0000);
+		mmio_regs = (unsigned char *)ZTWO_VADDR(mmio_regs_phys);
+		vcode_switch_base = (unsigned long) ZTWO_VADDR(board_addr + 0x003a0000);
 		printk(KERN_INFO "CV3D detected running in Z2 mode.\n");
-	    } else {
-		CyberVGARegs = (unsigned long)ioremap(board_addr+0x0c000000, 0x00010000);
-		CyberRegs = ioremap(CyberRegs_phys, 0x00010000);
-		CyberMem = (unsigned long)ioremap(CyberMem_phys, 0x01000000);	/* was 0x00400000 */
-		cv3d_on_zorro2 = 0;
-		printk(KERN_INFO "CV3D detected running in Z3 mode.\n");
-	    }
-
-	    fbhw = &Cyber_switch;
-
-	    strcpy(fb_info.modename, virgefb_name);
-	    fb_info.changevar = NULL;
-	    fb_info.node = NODEV;
-	    fb_info.fbops = &virgefb_ops;
-	    fb_info.disp = &disp;
-	    fb_info.currcon = -1;	
-	    fb_info.switch_con = &Cyberfb_switch;
-	    fb_info.updatevar = &Cyberfb_updatevar;
-	    fb_info.flags = FBINFO_FLAG_DEFAULT;
-
-	    fbhw->init();
-	    fbhw->decode_var(&virgefb_default, &par);
-	    fbhw->encode_var(&virgefb_default, &par);
-
-	    do_fb_set_var(&virgefb_default, 1);
-	    virgefb_get_var(&fb_display[0].var, -1, &fb_info);
-	    virgefb_set_disp(-1, &fb_info);
-	    do_install_cmap(0, &fb_info);
 
-	    if (register_framebuffer(&fb_info) < 0) {
+	} else {
+
+		/* board running in Z3 space. Seperate video memory (3 apertures)
+		   and S3 register set */
+
+		on_zorro2 = 0;
+		board_size = 0x01000000;
+
+		if (!request_mem_region(board_addr, board_size, "S3 ViRGE"))
+			return -ENOMEM;
+
+		v_ram_phys  = board_addr + 0x04000000;
+		v_ram = (unsigned long)ioremap(v_ram_phys, 0x01000000);
+		mmio_regs_phys = board_addr + 0x05000000;
+		vgaio_regs = (unsigned char *)ioremap(board_addr +0x0c000000, 0x00100000); /* includes PCI regs */
+		mmio_regs = ioremap(mmio_regs_phys, 0x00010000);
+		vcode_switch_base = (unsigned long)ioremap(board_addr + 0x08000000, 0x1000);
+		printk(KERN_INFO "CV3D detected running in Z3 mode\n");
+	}
+
+#if defined (VIRGEFBDEBUG)
+	DPRINTK("board_addr     : 0x%8.8lx\n",board_addr);
+	DPRINTK("board_size     : 0x%8.8lx\n",board_size);
+	DPRINTK("mmio_regs_phy  : 0x%8.8lx\n",mmio_regs_phys);
+	DPRINTK("v_ram_phys     : 0x%8.8lx\n",v_ram_phys);
+	DPRINTK("vgaio_regs     : 0x%8.8lx\n",(unsigned long)vgaio_regs);
+	DPRINTK("mmio_regs      : 0x%8.8lx\n",(unsigned long)mmio_regs);
+	DPRINTK("v_ram          : 0x%8.8lx\n",v_ram);
+	DPRINTK("vcode sw base  : 0x%8.8lx\n",vcode_switch_base);
+#endif
+	fbhw = &virgefb_hw_switch;
+	strcpy(fb_info.modename, virgefb_name);
+	fb_info.changevar = NULL;
+	fb_info.node = NODEV;
+	fb_info.fbops = &virgefb_ops;
+	fb_info.disp = &disp;
+	fb_info.currcon = -1;
+	fb_info.switch_con = &virgefb_switch;
+	fb_info.updatevar = &virgefb_updatevar;
+	fb_info.flags = FBINFO_FLAG_DEFAULT;
+	fbhw->init();
+	fbhw->decode_var(&virgefb_default, &par);
+	fbhw->encode_var(&virgefb_default, &par);
+	virgefb_do_fb_set_var(&virgefb_default, 1);
+	virgefb_get_var(&fb_display[0].var, -1, &fb_info);
+	virgefb_set_disp(-1, &fb_info);
+	do_install_cmap(0, &fb_info);
+
+	if (register_framebuffer(&fb_info) < 0) {
+		#warning release resources
 		printk(KERN_ERR "virgefb.c: register_framebuffer failed\n");
+		DPRINTK("EXIT\n");
 		return -EINVAL;
-	    }
+	}
 
-	    printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of "
-		   "video memory\n", GET_FB_IDX(fb_info.node),
-		   fb_info.modename, CyberSize>>10);
+	printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n",
+	       GET_FB_IDX(fb_info.node), fb_info.modename, v_ram_size>>10);
 
-	    /* TODO: This driver cannot be unloaded yet */
-	    MOD_INC_USE_COUNT;
-	    return 0;
-	}
-	return -ENODEV;
+	/* TODO: This driver cannot be unloaded yet */
+
+	MOD_INC_USE_COUNT;
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
-static int Cyberfb_switch(int con, struct fb_info *info)
+static int virgefb_switch(int con, struct fb_info *info)
 {
+	DPRINTK("ENTER\n");
 	/* Do we have to save the colormap? */
 	if (fb_display[info->currcon].cmap.len)
-		fb_get_cmap(&fb_display[info->currcon].cmap, 1, fbhw->getcolreg,
-			    info);
-
-	do_fb_set_var(&fb_display[con].var, 1);
+		fb_get_cmap(&fb_display[info->currcon].cmap, 1,
+			    fbhw->getcolreg, info);
+	virgefb_do_fb_set_var(&fb_display[con].var, 1);
 	info->currcon = con;
 	/* Install new colormap */
 	do_install_cmap(con, info);
-	return(0);
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -1192,38 +1839,23 @@
  *    Since it's called by a kernel driver, no range checking is done.
  */
 
-static int Cyberfb_updatevar(int con, struct fb_info *info)
+static int virgefb_updatevar(int con, struct fb_info *info)
 {
-	return(0);
+	DPRINTK("ENTER\n");
+	return 0;
+	DPRINTK("EXIT\n");
 }
 
-
 /*
  *    Blank the display.
  */
 
-static void virgefb_blank(int blank, struct fb_info *info)
+static int virgefb_blank(int blank, struct fb_info *info)
 {
+	DPRINTK("ENTER\n");
 	fbhw->blank(blank);
-}
-
-/*
- *    Get a Video Mode
- */
-
-static int __init get_video_mode(const char *name)
-{
-	int i;
-
-	for (i = 0; i < NUM_TOTAL_MODES; i++) {
-		if (!strcmp(name, virgefb_predefined[i].name)) {
-			virgefb_default = virgefb_predefined[i].var;
-			return(i);
-		}
-	}
-	/* ++Andre: set virgefb default mode */
-	virgefb_default = virgefb_predefined[VIRGE8_DEFMODE].var;
-	return(0);
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -1236,9 +1868,9 @@
 			       int dx, int height, int width)
 {
         sx *= 8; dx *= 8; width *= 8;
-        Cyber3D_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
+        virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
                        (u_short)(dy*fontheight(p)), (u_short)width,
-                       (u_short)(height*fontheight(p)), 8);
+                       (u_short)(height*fontheight(p)), (u_short)p->next_line, 8);
 }
 
 static void fbcon_virge8_clear(struct vc_data *conp, struct display *p, int sy,
@@ -1248,16 +1880,16 @@
 
         sx *= 8; width *= 8;
         bg = attr_bgcol_ec(p,conp);
-        Cyber3D_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
+        virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
                          (u_short)width, (u_short)(height*fontheight(p)),
-                         (u_short)bg, 8);
+                         (u_short)bg, (u_short)p->next_line, 8);
 }
 
 static void fbcon_virge8_putc(struct vc_data *conp, struct display *p, int c, int yy,
                               int xx)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb8_putc(conp, p, c, yy, xx);
 }
 
@@ -1265,14 +1897,14 @@
                       const unsigned short *s, int count, int yy, int xx)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
 }
 
 static void fbcon_virge8_revc(struct display *p, int xx, int yy)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb8_revc(p, xx, yy);
 }
 
@@ -1280,19 +1912,19 @@
                               int bottom_only)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb8_clear_margins(conp, p, bottom_only);
 }
 
 static struct display_switch fbcon_virge8 = {
-   setup:		fbcon_cfb8_setup,
-   bmove:		fbcon_virge8_bmove,
-   clear:		fbcon_virge8_clear,
-   putc:		fbcon_virge8_putc,
-   putcs:		fbcon_virge8_putcs,
-   revc:		fbcon_virge8_revc,
-   clear_margins:	fbcon_virge8_clear_margins,
-   fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+	setup:		fbcon_cfb8_setup,
+	bmove:		fbcon_virge8_bmove,
+	clear:		fbcon_virge8_clear,
+	putc:		fbcon_virge8_putc,
+	putcs:		fbcon_virge8_putcs,
+	revc:		fbcon_virge8_revc,
+	clear_margins:	fbcon_virge8_clear_margins,
+	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 
@@ -1301,28 +1933,28 @@
                                int dx, int height, int width)
 {
         sx *= 8; dx *= 8; width *= 8;
-        Cyber3D_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
+        virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
                        (u_short)(dy*fontheight(p)), (u_short)width,
-                       (u_short)(height*fontheight(p)), 16);
+                       (u_short)(height*fontheight(p)), (u_short)p->next_line, 16);
 }
-                
+
 static void fbcon_virge16_clear(struct vc_data *conp, struct display *p, int sy,
                                int sx, int height, int width)
 {
-        unsigned char bg;   
-                
+        unsigned char bg;
+
         sx *= 8; width *= 8;
         bg = attr_bgcol_ec(p,conp);
-        Cyber3D_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
+        virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
                          (u_short)width, (u_short)(height*fontheight(p)),
-                         (u_short)bg, 16);
+                         (u_short)bg, (u_short)p->next_line, 16);
 }
-   
+
 static void fbcon_virge16_putc(struct vc_data *conp, struct display *p, int c, int yy,
                               int xx)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb16_putc(conp, p, c, yy, xx);
 }
 
@@ -1330,14 +1962,14 @@
                       const unsigned short *s, int count, int yy, int xx)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
 }
 
 static void fbcon_virge16_revc(struct display *p, int xx, int yy)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb16_revc(p, xx, yy);
 }
 
@@ -1345,19 +1977,84 @@
                               int bottom_only)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb16_clear_margins(conp, p, bottom_only);
 }
 
 static struct display_switch fbcon_virge16 = {
-   setup:		fbcon_cfb16_setup,
-   bmove:		fbcon_virge16_bmove,
-   clear:		fbcon_virge16_clear,
-   putc:		fbcon_virge16_putc,
-   putcs:		fbcon_virge16_putcs,
-   revc:		fbcon_virge16_revc,
-   clear_margins:	fbcon_virge16_clear_margins,
-   fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+	setup:		fbcon_cfb16_setup,
+	bmove:		fbcon_virge16_bmove,
+	clear:		fbcon_virge16_clear,
+	putc:		fbcon_virge16_putc,
+	putcs:		fbcon_virge16_putcs,
+	revc:		fbcon_virge16_revc,
+	clear_margins:	fbcon_virge16_clear_margins,
+	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static void fbcon_virge32_bmove(struct display *p, int sy, int sx, int dy,
+			       int dx, int height, int width)
+{
+        sx *= 16; dx *= 16; width *= 16;	/* doubled these values to do 32 bit blit */
+        virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
+                       (u_short)(dy*fontheight(p)), (u_short)width,
+                       (u_short)(height*fontheight(p)), (u_short)p->next_line, 16);
+}
+
+static void fbcon_virge32_clear(struct vc_data *conp, struct display *p, int sy,
+			       int sx, int height, int width)
+{
+        unsigned char bg;
+
+        sx *= 16; width *= 16;			/* doubled these values to do 32 bit blit */
+        bg = attr_bgcol_ec(p,conp);
+        virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
+                         (u_short)width, (u_short)(height*fontheight(p)),
+                         (u_short)bg, (u_short)p->next_line, 16);
+}
+
+static void fbcon_virge32_putc(struct vc_data *conp, struct display *p, int c, int yy,
+                              int xx)
+{
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	fbcon_cfb32_putc(conp, p, c, yy, xx);
+}
+
+static void fbcon_virge32_putcs(struct vc_data *conp, struct display *p,
+                      const unsigned short *s, int count, int yy, int xx)
+{
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
+}
+
+static void fbcon_virge32_revc(struct display *p, int xx, int yy)
+{
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	fbcon_cfb32_revc(p, xx, yy);
+}
+
+static void fbcon_virge32_clear_margins(struct vc_data *conp, struct display *p,
+                              int bottom_only)
+{
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	fbcon_cfb32_clear_margins(conp, p, bottom_only);
+}
+
+static struct display_switch fbcon_virge32 = {
+	setup:		fbcon_cfb32_setup,
+	bmove:		fbcon_virge32_bmove,
+	clear:		fbcon_virge32_clear,
+	putc:		fbcon_virge32_putc,
+	putcs:		fbcon_virge32_putcs,
+	revc:		fbcon_virge32_revc,
+	clear_margins:	fbcon_virge32_clear_margins,
+	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 
@@ -1377,3 +2074,450 @@
 	/* TODO: clean up ... */
 }
 #endif /* MODULE */
+
+static int cv3d_has_4mb(void)
+{
+	/* cyberfb version didn't work, neither does this (not reliably)
+	forced to return 4MB */
+#if 0
+	volatile unsigned long *t0, *t2;
+#endif
+	DPRINTK("ENTER\n");
+#if 0
+	/* write patterns in memory and test if they can be read */
+	t0 = (volatile unsigned long *)v_ram;
+	t2 = (volatile unsigned long *)(v_ram + 0x00200000);
+	*t0 = 0x87654321;
+	*t2 = 0x12345678;
+
+	if (*t0 != 0x87654321) {
+		/* read of first location failed */
+		DPRINTK("EXIT - 0MB !\n");
+		return 0;
+	}
+
+	if (*t2 == 0x87654321) {
+		/* should read 0x12345678 if 4MB */
+		DPRINTK("EXIT - 2MB(a) \n");
+		return 0;
+	}
+
+	if (*t2 != 0x12345678) {
+		/* upper 2MB read back match failed */
+		DPRINTK("EXIT - 2MB(b)\n");
+		return 0;
+	}
+
+	/* may have 4MB */
+
+	*t2 = 0xAAAAAAAA;
+
+	if(*t2 != 0xAAAAAAAA) {
+		/* upper 2MB read back match failed */
+		DPRINTK("EXIT - 2MB(c)\n");
+		return 0;
+	}
+
+	*t2 = 0x55555555;
+
+	if(*t2 != 0x55555555) {
+		/* upper 2MB read back match failed */
+		DPRINTK("EXIT - 2MB(d)\n");
+		return 0;
+	}
+
+#endif
+	DPRINTK("EXIT - 4MB\n");
+	return 1;
+}
+
+
+/*
+ * Computes M, N, and R pll params for freq arg.
+ * Returns 16 bits - hi 0MMMMMM lo 0RRNNNNN
+ */
+
+#define REFCLOCK 14318000
+
+static unsigned short virgefb_compute_clock(unsigned long freq)
+{
+
+	unsigned char m, n, r, rpwr;
+	unsigned long diff, ftry, save = ~0UL;
+	unsigned short mnr;
+
+	DPRINTK("ENTER\n");
+
+	for (r = 0, rpwr = 1 ; r < 4 ; r++, rpwr *= 2) {
+		if ((135000000 <= (rpwr * freq)) && ((rpwr * freq) <= 270000000)) {
+			for (n = 1 ; n < 32 ; n++) {
+				m = ((freq * (n + 2) * rpwr)/REFCLOCK) - 2;
+				if (m == 0 || m >127)
+					break;
+				ftry = ((REFCLOCK / (n + 2)) * (m + 2)) / rpwr;
+				if (ftry > freq)
+					diff = ftry - freq;
+				else
+					diff = freq - ftry;
+				if (diff < save) {
+					save = diff;
+					mnr =  (m << 8) | (r<<5) | (n & 0x7f);
+				}
+			}
+		}
+	}
+	if (save == ~0UL)
+		printk("Can't compute clock PLL values for %ld Hz clock\n", freq);
+	DPRINTK("EXIT\n");
+	return(mnr);
+}
+
+static void virgefb_load_video_mode(struct fb_var_screeninfo *video_mode)
+{
+	unsigned char lace, dblscan, tmp;
+	unsigned short mnr;
+	unsigned short HT, HDE, HBS, HBW, HSS, HSW;
+	unsigned short VT, VDE, VBS, VBW, VSS, VSW;
+	unsigned short SCO;
+	int cr11;
+	int cr67;
+	int hmul;
+	int xres, xres_virtual, hfront, hsync, hback;
+	int yres, vfront, vsync, vback;
+	int bpp;
+	int i;
+	long freq;
+
+	DPRINTK("ENTER : %dx%d-%d\n",video_mode->xres, video_mode->yres,
+				video_mode->bits_per_pixel);
+
+	bpp = video_mode->bits_per_pixel;
+	xres = video_mode->xres;
+	xres_virtual = video_mode->xres_virtual;
+	hfront = video_mode->right_margin;
+	hsync = video_mode->hsync_len;
+	hback = video_mode->left_margin;
+
+	lace = 0;
+	dblscan = 0;
+
+	if (video_mode->vmode & FB_VMODE_DOUBLE) {
+		yres = video_mode->yres * 2;
+		vfront = video_mode->lower_margin * 2;
+		vsync = video_mode->vsync_len * 2;
+		vback = video_mode->upper_margin * 2;
+		dblscan = 1;
+	} else if (video_mode->vmode & FB_VMODE_INTERLACED) {
+		yres = (video_mode->yres + 1) / 2;
+		vfront = (video_mode->lower_margin + 1) / 2;
+		vsync = (video_mode->vsync_len + 1) / 2;
+		vback = (video_mode->upper_margin + 1) / 2;
+		lace = 1;
+	} else {
+		yres = video_mode->yres;
+		vfront = video_mode->lower_margin;
+		vsync = video_mode->vsync_len;
+		vback = video_mode->upper_margin;
+	}
+
+	switch (bpp) {
+		case 8:
+			video_mode->red.offset = 0;
+			video_mode->green.offset = 0;
+			video_mode->blue.offset = 0;
+			video_mode->transp.offset = 0;
+			video_mode->red.length = 8;
+			video_mode->green.length = 8;
+			video_mode->blue.length = 8;
+			video_mode->transp.length = 0;
+			hmul = 1;
+			cr67 = 0x00;
+			SCO = xres_virtual / 8;
+			break;
+		case 16:
+			video_mode->red.offset = 11;
+			video_mode->green.offset = 5;
+			video_mode->blue.offset = 0;
+			video_mode->transp.offset = 0;
+			video_mode->red.length = 5;
+			video_mode->green.length = 6;
+			video_mode->blue.length = 5;
+			video_mode->transp.length = 0;
+			hmul = 2;
+			cr67 = 0x50;
+			SCO = xres_virtual / 4;
+			break;
+		case 32:
+			video_mode->red.offset = 16;
+			video_mode->green.offset = 8;
+			video_mode->blue.offset = 0;
+			video_mode->transp.offset = 24;
+			video_mode->red.length = 8;
+			video_mode->green.length = 8;
+			video_mode->blue.length = 8;
+			video_mode->transp.length = 8;
+			hmul = 1;
+			cr67 = 0xd0;
+			SCO = xres_virtual / 2;
+			break;
+	}
+
+	HT  = (((xres + hfront + hsync + hback) / 8) * hmul) - 5;
+	HDE = ((xres / 8) * hmul) - 1;
+	HBS = (xres / 8) * hmul;
+	HSS = ((xres + hfront) / 8) * hmul;
+	HSW = (hsync / 8) * hmul;
+	HBW = (((hfront + hsync + hback) / 8) * hmul) - 2;
+
+	VT  = yres + vfront + vsync + vback - 2;
+	VDE = yres - 1;
+	VBS = yres - 1;
+	VSS = yres + vfront;
+	VSW = vsync;
+	VBW = vfront + vsync + vback - 2;
+
+#ifdef VIRGEFBDEBUG
+	DPRINTK("HDE       : 0x%4.4x, %4.4d\n", HDE, HDE);
+	DPRINTK("HBS       : 0x%4.4x, %4.4d\n", HBS, HBS);
+	DPRINTK("HSS       : 0x%4.4x, %4.4d\n", HSS, HSS);
+	DPRINTK("HSW       : 0x%4.4x, %4.4d\n", HSW, HSW);
+	DPRINTK("HBW       : 0x%4.4x, %4.4d\n", HBW, HBW);
+	DPRINTK("HSS + HSW : 0x%4.4x, %4.4d\n", HSS+HSW, HSS+HSW);
+	DPRINTK("HBS + HBW : 0x%4.4x, %4.4d\n", HBS+HBW, HBS+HBW);
+	DPRINTK("HT        : 0x%4.4x, %4.4d\n", HT, HT);
+	DPRINTK("VDE       : 0x%4.4x, %4.4d\n", VDE, VDE);
+	DPRINTK("VBS       : 0x%4.4x, %4.4d\n", VBS, VBS);
+	DPRINTK("VSS       : 0x%4.4x, %4.4d\n", VSS, VSS);
+	DPRINTK("VSW       : 0x%4.4x, %4.4d\n", VSW, VSW);
+	DPRINTK("VBW       : 0x%4.4x, %4.4d\n", VBW, VBW);
+	DPRINTK("VT        : 0x%4.4x, %4.4d\n", VT, VT);
+#endif
+
+/* turn gfx off, don't mess up the display */
+
+ 	gfx_on_off(1);
+
+/* H and V sync polarity */
+
+	tmp = rb_mmio(GREG_MISC_OUTPUT_R) & 0x2f;		/* colour, ram enable, clk sr12/s13 sel */
+	if (!(video_mode->sync & FB_SYNC_HOR_HIGH_ACT))
+		tmp |= 0x40;					/* neg H sync polarity */
+	if (!(video_mode->sync & FB_SYNC_VERT_HIGH_ACT))
+		tmp |= 0x80;					/* neg V sync polarity */
+	tmp |= 0x0c;						/* clk from sr12/sr13 */
+	wb_mmio(GREG_MISC_OUTPUT_W, tmp);
+
+/* clocks */
+
+	wseq(SEQ_ID_BUS_REQ_CNTL, 0xc0);			/* 2 clk mem wr and /RAS1 */
+	wseq(SEQ_ID_CLKSYN_CNTL_2, 0x80);			/* b7 is 2 mem clk wr */
+	mnr = virgefb_compute_clock(MEMCLOCK);
+	DPRINTK("mem clock %d, m %d, n %d, r %d.\n", MEMCLOCK, ((mnr>>8)&0x7f), (mnr&0x1f), ((mnr >> 5)&0x03));
+	wseq(SEQ_ID_MCLK_LO, (mnr & 0x7f));
+	wseq(SEQ_ID_MCLK_HI, ((mnr & 0x7f00) >> 8));
+	freq = (1000000000 / video_mode->pixclock) * 1000;	/* pixclock is in ps ... convert to Hz */
+	mnr = virgefb_compute_clock(freq);
+	DPRINTK("dot clock %ld, m %d, n %d, r %d.\n", freq, ((mnr>>8)&0x7f), (mnr&0x1f), ((mnr>>5)&0x03));
+	wseq(SEQ_ID_DCLK_LO, (mnr & 0x7f));
+	wseq(SEQ_ID_DCLK_HI, ((mnr & 0x7f00) >> 8));
+	wseq(SEQ_ID_CLKSYN_CNTL_2, 0xa0);
+	wseq(SEQ_ID_CLKSYN_CNTL_2, 0x80);
+	udelay(100);
+
+/* load display parameters into board */
+
+	/* not sure about sync and blanking extensions bits in cr5d and cr5 */
+
+	wcrt(CRT_ID_EXT_HOR_OVF,			/* 0x5d */
+		((HT & 0x100) ?         0x01 : 0x00) |
+		((HDE & 0x100) ?        0x02 : 0x00) |
+		((HBS & 0x100) ?        0x04 : 0x00) |
+	/*	(((HBS + HBW) & 0x40) ? 0x08 : 0x00) |	*/
+		((HSS & 0x100) ?        0x10 : 0x00) |
+	/*	(((HSS + HSW) & 0x20) ? 0x20 : 0x00) |	*/
+		((HSW >= 0x20) ?        0x20 : 0x00) |
+		(((HT-5) & 0x100) ?     0x40 : 0x00));
+
+	wcrt(CRT_ID_EXT_VER_OVF,			/* 0x5e */
+		((VT & 0x400) ? 0x01 : 0x00) |
+		((VDE & 0x400) ? 0x02 : 0x00) |
+		((VBS & 0x400) ? 0x04 : 0x00) |
+		((VSS & 0x400) ? 0x10 : 0x00) |
+		0x40);					/* line compare */
+
+	wcrt(CRT_ID_START_VER_RETR, VSS);
+	cr11 = rcrt(CRT_ID_END_VER_RETR) | 0x20;	/* vert interrupt flag */
+	wcrt(CRT_ID_END_VER_RETR, ((cr11 & 0x20) | ((VSS + VSW) & 0x0f)));	/* keeps vert irq enable state, also has unlock bit cr0 to 7 */
+	wcrt(CRT_ID_VER_DISP_ENA_END, VDE);
+	wcrt(CRT_ID_START_VER_BLANK, VBS);
+	wcrt(CRT_ID_END_VER_BLANK, VBS + VBW);		/* might be +/- 1 out */
+	wcrt(CRT_ID_HOR_TOTAL, HT);
+	wcrt(CRT_ID_DISPLAY_FIFO, HT - 5);
+	wcrt(CRT_ID_BACKWAD_COMP_3, 0x10);		/* enable display fifo */
+	wcrt(CRT_ID_HOR_DISP_ENA_END, HDE);
+	wcrt(CRT_ID_START_HOR_BLANK , HBS);
+	wcrt(CRT_ID_END_HOR_BLANK, (HBS + HBW) & 0x1f);
+	wcrt(CRT_ID_START_HOR_RETR, HSS);
+	wcrt(CRT_ID_END_HOR_RETR,			/* cr5 */
+		((HSS + HSW) & 0x1f) |
+		(((HBS + HBW) & 0x20) ? 0x80 : 0x00));
+	wcrt(CRT_ID_VER_TOTAL, VT);
+	wcrt(CRT_ID_OVERFLOW,
+		((VT & 0x100) ? 0x01 : 0x00) |
+		((VDE & 0x100) ? 0x02 : 0x00) |
+		((VSS & 0x100) ? 0x04 : 0x00) |
+		((VBS & 0x100) ? 0x08 : 0x00) |
+		0x10 |
+		((VT & 0x200) ? 0x20 : 0x00) |
+		((VDE & 0x200) ? 0x40 : 0x00) |
+		((VSS & 0x200) ? 0x80 : 0x00));
+	wcrt(CRT_ID_MAX_SCAN_LINE,
+		(dblscan ? 0x80 : 0x00) |
+		0x40 |
+		((VBS & 0x200) ? 0x20 : 0x00));
+	wcrt(CRT_ID_LINE_COMPARE, 0xff);
+	wcrt(CRT_ID_LACE_RETR_START, HT / 2);		/* (HT-5)/2 ? */
+	wcrt(CRT_ID_LACE_CONTROL, (lace ? 0x20 : 0x00));
+
+	wcrt(CRT_ID_SCREEN_OFFSET, SCO);
+	wcrt(CRT_ID_EXT_SYS_CNTL_2, (SCO >> 4) & 0x30 );
+
+	/* wait for vert sync before cr67 update */
+
+	for (i=0; i < 10000; i++) {
+		udelay(10);
+		mb();
+		if (rb_mmio(GREG_INPUT_STATUS1_R) & 0x08)
+			break;
+	}
+
+	wl_mmio(0x8200, 0x0000c000);	/* fifo control  (0x00110400 ?) */
+	wcrt(CRT_ID_EXT_MISC_CNTL_2, cr67);
+
+/* enable video */
+
+	tmp = rb_mmio(ACT_ADDRESS_RESET);
+	wb_mmio(ACT_ADDRESS_W, ((bpp == 8) ? 0x20 : 0x00));	/* set b5, ENB PLT in attr idx reg) */
+	tmp = rb_mmio(ACT_ADDRESS_RESET);
+
+/* turn gfx on again */
+
+	gfx_on_off(0);
+
+/* pass-through */
+
+	SetVSwitch(1);		/* cv3d */
+
+	DUMP;
+	DPRINTK("EXIT\n");
+}
+
+static inline void gfx_on_off(int toggle)
+{
+	unsigned char tmp;
+
+	DPRINTK("ENTER gfx %s\n", (toggle ? "off" : "on"));
+
+	toggle = (toggle & 0x01) << 5;
+	tmp = rseq(SEQ_ID_CLOCKING_MODE) & (~(0x01 << 5));
+	wseq(SEQ_ID_CLOCKING_MODE, tmp | toggle);
+
+	DPRINTK("EXIT\n");
+}
+
+#if defined (VIRGEFBDUMP)
+
+/*
+ * Dump board registers
+ */
+
+static void cv64_dump(void)
+{
+	int i;
+	u8 c, b;
+        u16 w;
+	u32 l;
+
+	/* crt, seq, gfx and atr regs */
+
+	SelectMMIO;
+
+	printk("\n");
+	for (i = 0; i <= 0x6f; i++) {
+		wb_mmio(CRT_ADDRESS, i);
+		printk("crt idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(CRT_ADDRESS_R));
+	}
+	for (i = 0; i <= 0x1c; i++) {
+		wb_mmio(SEQ_ADDRESS, i);
+		printk("seq idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(SEQ_ADDRESS_R));
+	}
+	for (i = 0; i <= 8; i++) {
+		wb_mmio(GCT_ADDRESS, i);
+		printk("gfx idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(GCT_ADDRESS_R));
+	}
+	for (i = 0; i <= 0x14; i++) {
+		c = rb_mmio(ACT_ADDRESS_RESET);
+		wb_mmio(ACT_ADDRESS_W, i);
+		printk("atr idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(ACT_ADDRESS_R));
+	}
+
+	/* re-enable video access to palette */
+
+	c = rb_mmio(ACT_ADDRESS_RESET);
+	udelay(10);
+	wb_mmio(ACT_ADDRESS_W, 0x20);
+	c = rb_mmio(ACT_ADDRESS_RESET);
+	udelay(10);
+
+	/* general regs */
+
+	printk("0x3cc(w 0x3c2) : 0x%2.2x\n", rb_mmio(0x3cc));	/* GREG_MISC_OUTPUT READ */
+	printk("0x3c2(-------) : 0x%2.2x\n", rb_mmio(0x3c2));	/* GREG_INPUT_STATUS 0 READ */
+	printk("0x3c3(w 0x3c3) : 0x%2.2x\n", rb_vgaio(0x3c3));	/* GREG_VIDEO_SUBS_ENABLE */
+	printk("0x3ca(w 0x3da) : 0x%2.2x\n", rb_vgaio(0x3ca));	/* GREG_FEATURE_CONTROL read */
+	printk("0x3da(-------) : 0x%2.2x\n", rb_mmio(0x3da));	/* GREG_INPUT_STATUS 1 READ */
+
+	/* engine regs */
+
+	for (i = 0x8180; i <= 0x8200; i = i + 4)
+		printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
+
+	i = 0x8504;
+	printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
+	i = 0x850c;
+	printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
+	for (i = 0xa4d4; i <= 0xa50c; i = i + 4)
+		printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
+
+	/* PCI regs */
+
+	SelectCFG;
+
+	for (c = 0; c < 0x08; c = c + 2) {
+		w = (*((u16 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 2)));
+		printk("pci 0x%2.2x : 0x%4.4x\n", c, w);
+	}
+	c = 8;
+	l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)))));
+	printk("pci 0x%2.2x : 0x%8.8x\n", c, l);
+	c = 0x0d;
+	b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3)));
+	printk("pci 0x%2.2x : 0x%2.2x\n", c, b);
+	c = 0x10;
+	l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)))));
+	printk("pci 0x%2.2x : 0x%8.8x\n", c, l);
+	c = 0x30;
+	l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)))));
+	printk("pci 0x%2.2x : 0x%8.8x\n", c, l);
+	c = 0x3c;
+	b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3)));
+	printk("pci 0x%2.2x : 0x%2.2x\n", c, b);
+	c = 0x3d;
+	b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3)));
+	printk("pci 0x%2.2x : 0x%2.2x\n", c, b);
+	c = 0x3e;
+	w = (*((u16 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 2)));
+	printk("pci 0x%2.2x : 0x%4.4x\n", c, w);
+	SelectMMIO;
+}
+#endif
diff -Nru a/drivers/video/virgefb.h b/drivers/video/virgefb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/virgefb.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,288 @@
+/*
+ * linux/drivers/video/virgefb.h -- CyberVision64 definitions for the
+ *                                  text console driver.
+ *
+ *   Copyright (c) 1998 Alan Bair
+ *
+ * This file is based on the initial port to Linux of grf_cvreg.h:
+ *
+ *   Copyright (c) 1997 Antonio Santos
+ *
+ * The original work is from the NetBSD CyberVision 64 framebuffer driver 
+ * and support files (grf_cv.c, grf_cvreg.h, ite_cv.c):
+ * Permission to use the source of this driver was obtained from the
+ * author Michael Teske by Alan Bair.
+ *
+ *   Copyright (c) 1995 Michael Teske
+ *
+ * History:
+ *
+ *
+ *
+ * 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.
+ */
+
+/* Enhanced register mapping (MMIO mode) */
+
+#define S3_CRTC_ADR    0x03d4
+#define S3_CRTC_DATA   0x03d5
+
+#define S3_REG_LOCK2	0x39
+#define S3_HGC_MODE	0x45
+
+#define S3_HWGC_ORGX_H	0x46
+#define S3_HWGC_ORGX_L	0x47
+#define S3_HWGC_ORGY_H	0x48
+#define S3_HWGC_ORGY_L	0x49
+#define S3_HWGC_DX	0x4e
+#define S3_HWGC_DY	0x4f
+
+#define S3_LAW_CTL	0x58
+
+/**************************************************/
+
+/*
+ * Defines for the used register addresses (mw)
+ *
+ * NOTE: There are some registers that have different addresses when
+ *       in mono or color mode. We only support color mode, and thus
+ *       some addresses won't work in mono-mode!
+ *
+ * General and VGA-registers taken from retina driver. Fixed a few
+ * bugs in it. (SR and GR read address is Port + 1, NOT Port)
+ *
+ */
+
+/* General Registers: */
+#define GREG_MISC_OUTPUT_R	0x03CC
+#define GREG_MISC_OUTPUT_W	0x03C2	
+#define GREG_FEATURE_CONTROL_R	0x03CA 
+#define GREG_FEATURE_CONTROL_W	0x03DA
+#define GREG_INPUT_STATUS0_R	0x03C2
+#define GREG_INPUT_STATUS1_R	0x03DA
+
+/* Setup Registers: */
+#define SREG_VIDEO_SUBS_ENABLE	0x03C3	/* virge */
+
+/* Attribute Controller: */
+#define ACT_ADDRESS		0x03C0
+#define ACT_ADDRESS_R		0x03C1
+#define ACT_ADDRESS_W		0x03C0
+#define ACT_ADDRESS_RESET	0x03DA
+#define ACT_ID_PALETTE0		0x00
+#define ACT_ID_PALETTE1		0x01
+#define ACT_ID_PALETTE2		0x02
+#define ACT_ID_PALETTE3		0x03
+#define ACT_ID_PALETTE4		0x04
+#define ACT_ID_PALETTE5		0x05
+#define ACT_ID_PALETTE6		0x06
+#define ACT_ID_PALETTE7		0x07
+#define ACT_ID_PALETTE8		0x08
+#define ACT_ID_PALETTE9		0x09
+#define ACT_ID_PALETTE10	0x0A
+#define ACT_ID_PALETTE11	0x0B
+#define ACT_ID_PALETTE12	0x0C
+#define ACT_ID_PALETTE13	0x0D
+#define ACT_ID_PALETTE14	0x0E
+#define ACT_ID_PALETTE15	0x0F
+#define ACT_ID_ATTR_MODE_CNTL	0x10
+#define ACT_ID_OVERSCAN_COLOR	0x11
+#define ACT_ID_COLOR_PLANE_ENA	0x12
+#define ACT_ID_HOR_PEL_PANNING	0x13
+#define ACT_ID_COLOR_SELECT	0x14    /* virge PX_PADD  pixel padding register */
+
+/* Graphics Controller: */
+#define GCT_ADDRESS		0x03CE
+#define GCT_ADDRESS_R		0x03CF
+#define GCT_ADDRESS_W		0x03CF
+#define GCT_ID_SET_RESET	0x00
+#define GCT_ID_ENABLE_SET_RESET	0x01
+#define GCT_ID_COLOR_COMPARE	0x02
+#define GCT_ID_DATA_ROTATE	0x03
+#define GCT_ID_READ_MAP_SELECT	0x04
+#define GCT_ID_GRAPHICS_MODE	0x05
+#define GCT_ID_MISC		0x06
+#define GCT_ID_COLOR_XCARE	0x07
+#define GCT_ID_BITMASK		0x08
+
+/* Sequencer: */
+#define SEQ_ADDRESS		0x03C4
+#define SEQ_ADDRESS_R		0x03C5
+#define SEQ_ADDRESS_W		0x03C5
+#define SEQ_ID_RESET		0x00
+#define SEQ_ID_CLOCKING_MODE	0x01
+#define SEQ_ID_MAP_MASK		0x02
+#define SEQ_ID_CHAR_MAP_SELECT	0x03
+#define SEQ_ID_MEMORY_MODE	0x04
+#define SEQ_ID_UNKNOWN1		0x05
+#define SEQ_ID_UNKNOWN2		0x06
+#define SEQ_ID_UNKNOWN3		0x07
+/* S3 extensions */
+#define SEQ_ID_UNLOCK_EXT	0x08
+#define SEQ_ID_EXT_SEQ_REG9	0x09	/* b7 = 1 extended reg access by MMIO only */
+#define SEQ_ID_BUS_REQ_CNTL	0x0A
+#define SEQ_ID_EXT_MISC_SEQ	0x0B
+#define SEQ_ID_UNKNOWN4		0x0C
+#define SEQ_ID_EXT_SEQ		0x0D
+#define SEQ_ID_UNKNOWN5		0x0E
+#define SEQ_ID_UNKNOWN6		0x0F
+#define SEQ_ID_MCLK_LO		0x10
+#define SEQ_ID_MCLK_HI		0x11
+#define SEQ_ID_DCLK_LO		0x12
+#define SEQ_ID_DCLK_HI		0x13
+#define SEQ_ID_CLKSYN_CNTL_1	0x14
+#define SEQ_ID_CLKSYN_CNTL_2	0x15
+#define SEQ_ID_CLKSYN_TEST_HI	0x16	/* reserved for S3 testing of the */
+#define SEQ_ID_CLKSYN_TEST_LO	0x17	/* internal clock synthesizer   */
+#define SEQ_ID_RAMDAC_CNTL	0x18
+#define SEQ_ID_MORE_MAGIC	0x1A
+#define SEQ_ID_SIGNAL_SELECT	0x1C	/* new for virge */
+
+/* CRT Controller: */
+#define CRT_ADDRESS		0x03D4
+#define CRT_ADDRESS_R		0x03D5
+#define CRT_ADDRESS_W		0x03D5
+#define CRT_ID_HOR_TOTAL	0x00
+#define CRT_ID_HOR_DISP_ENA_END	0x01
+#define CRT_ID_START_HOR_BLANK	0x02
+#define CRT_ID_END_HOR_BLANK	0x03
+#define CRT_ID_START_HOR_RETR	0x04
+#define CRT_ID_END_HOR_RETR	0x05
+#define CRT_ID_VER_TOTAL	0x06
+#define CRT_ID_OVERFLOW		0x07
+#define CRT_ID_PRESET_ROW_SCAN	0x08
+#define CRT_ID_MAX_SCAN_LINE	0x09
+#define CRT_ID_CURSOR_START	0x0A
+#define CRT_ID_CURSOR_END	0x0B
+#define CRT_ID_START_ADDR_HIGH	0x0C
+#define CRT_ID_START_ADDR_LOW	0x0D
+#define CRT_ID_CURSOR_LOC_HIGH	0x0E
+#define CRT_ID_CURSOR_LOC_LOW	0x0F
+#define CRT_ID_START_VER_RETR	0x10
+#define CRT_ID_END_VER_RETR	0x11
+#define CRT_ID_VER_DISP_ENA_END	0x12
+#define CRT_ID_SCREEN_OFFSET	0x13
+#define CRT_ID_UNDERLINE_LOC	0x14
+#define CRT_ID_START_VER_BLANK	0x15
+#define CRT_ID_END_VER_BLANK	0x16
+#define CRT_ID_MODE_CONTROL	0x17
+#define CRT_ID_LINE_COMPARE	0x18
+#define CRT_ID_GD_LATCH_RBACK	0x22
+#define CRT_ID_ACT_TOGGLE_RBACK	0x24
+#define CRT_ID_ACT_INDEX_RBACK	0x26
+/* S3 extensions: S3 VGA Registers */
+#define CRT_ID_DEVICE_HIGH	0x2D
+#define CRT_ID_DEVICE_LOW	0x2E
+#define CRT_ID_REVISION 	0x2F
+#define CRT_ID_CHIP_ID_REV	0x30
+#define CRT_ID_MEMORY_CONF	0x31
+#define CRT_ID_BACKWAD_COMP_1	0x32
+#define CRT_ID_BACKWAD_COMP_2	0x33
+#define CRT_ID_BACKWAD_COMP_3	0x34
+#define CRT_ID_REGISTER_LOCK	0x35
+#define CRT_ID_CONFIG_1 	0x36
+#define CRT_ID_CONFIG_2 	0x37
+#define CRT_ID_REGISTER_LOCK_1	0x38
+#define CRT_ID_REGISTER_LOCK_2	0x39
+#define CRT_ID_MISC_1		0x3A
+#define CRT_ID_DISPLAY_FIFO	0x3B
+#define CRT_ID_LACE_RETR_START	0x3C
+/* S3 extensions: System Control Registers  */
+#define CRT_ID_SYSTEM_CONFIG	0x40
+#define CRT_ID_BIOS_FLAG	0x41
+#define CRT_ID_LACE_CONTROL	0x42
+#define CRT_ID_EXT_MODE 	0x43
+#define CRT_ID_HWGC_MODE	0x45	/* HWGC = Hardware Graphics Cursor */
+#define CRT_ID_HWGC_ORIGIN_X_HI	0x46
+#define CRT_ID_HWGC_ORIGIN_X_LO	0x47
+#define CRT_ID_HWGC_ORIGIN_Y_HI	0x48
+#define CRT_ID_HWGC_ORIGIN_Y_LO	0x49
+#define CRT_ID_HWGC_FG_STACK	0x4A
+#define CRT_ID_HWGC_BG_STACK	0x4B
+#define CRT_ID_HWGC_START_AD_HI	0x4C
+#define CRT_ID_HWGC_START_AD_LO	0x4D
+#define CRT_ID_HWGC_DSTART_X	0x4E
+#define CRT_ID_HWGC_DSTART_Y	0x4F
+/* S3 extensions: System Extension Registers  */
+#define CRT_ID_EXT_SYS_CNTL_1	0x50	/* NOT a virge register */
+#define CRT_ID_EXT_SYS_CNTL_2	0x51
+#define CRT_ID_EXT_BIOS_FLAG_1	0x52
+#define CRT_ID_EXT_MEM_CNTL_1	0x53
+#define CRT_ID_EXT_MEM_CNTL_2	0x54
+#define CRT_ID_EXT_DAC_CNTL	0x55
+#define CRT_ID_EX_SYNC_1	0x56
+#define CRT_ID_EX_SYNC_2	0x57
+#define CRT_ID_LAW_CNTL		0x58	/* LAW = Linear Address Window */
+#define CRT_ID_LAW_POS_HI	0x59
+#define CRT_ID_LAW_POS_LO	0x5A
+#define CRT_ID_GOUT_PORT	0x5C
+#define CRT_ID_EXT_HOR_OVF	0x5D
+#define CRT_ID_EXT_VER_OVF	0x5E
+#define CRT_ID_EXT_MEM_CNTL_3	0x60	/* NOT a virge register */
+#define CRT_ID_EXT_MEM_CNTL_4	0x61
+#define CRT_ID_EX_SYNC_3	0x63	/* NOT a virge register */
+#define CRT_ID_EXT_MISC_CNTL	0x65
+#define CRT_ID_EXT_MISC_CNTL_1	0x66
+#define CRT_ID_EXT_MISC_CNTL_2	0x67
+#define CRT_ID_CONFIG_3 	0x68
+#define CRT_ID_EXT_SYS_CNTL_3	0x69
+#define CRT_ID_EXT_SYS_CNTL_4	0x6A
+#define CRT_ID_EXT_BIOS_FLAG_3	0x6B
+#define CRT_ID_EXT_BIOS_FLAG_4	0x6C
+/* S3 virge extensions: more System Extension Registers  */
+#define CRT_ID_EXT_BIOS_FLAG_5	0x6D
+#define CRT_ID_EXT_DAC_TEST	0x6E
+#define CRT_ID_CONFIG_4 	0x6F
+
+/* Video DAC */
+#define VDAC_ADDRESS		0x03c8
+#define VDAC_ADDRESS_W		0x03c8
+#define VDAC_ADDRESS_R		0x03c7
+#define VDAC_STATE		0x03c7
+#define VDAC_DATA		0x03c9
+#define VDAC_MASK		0x03c6
+
+/* Miscellaneous Registers */
+#define MR_SUBSYSTEM_STATUS_R		0x8504	/* new for virge */
+#define MR_SUBSYSTEM_CNTL_W		0x8504	/* new for virge */
+#define MR_ADVANCED_FUNCTION_CONTROL	0x850C	/* new for virge */
+
+/* Blitter  */
+#define BLT_COMMAND_SET		0xA500
+#define BLT_SIZE_X_Y		0xA504
+#define BLT_SRC_X_Y		0xA508
+#define BLT_DEST_X_Y		0xA50C
+
+#define BLT_SRC_BASE		0xa4d4
+#define BLT_DEST_BASE		0xa4d8
+#define BLT_CLIP_LEFT_RIGHT	0xa4dc
+#define BLT_CLIP_TOP_BOTTOM	0xa4e0
+#define BLT_SRC_DEST_STRIDE	0xa4e4
+#define BLT_MONO_PATTERN_0	0xa4e8
+#define BLT_MONO_PATTERN_1	0xa4ec
+#define BLT_PATTERN_COLOR	0xa4f4
+
+#define L2D_COMMAND_SET		0xA900
+#define L2D_CLIP_LEFT_RIGHT	0xA8DC
+#define L2D_CLIP_TOP_BOTTOM	0xA8E0
+
+#define P2D_COMMAND_SET		0xAD00
+#define P2D_CLIP_LEFT_RIGHT	0xACDC
+#define P2D_CLIP_TOP_BOTTOM	0xACE0
+
+#define CMD_NOP		(0xf << 27)	/* %1111 << 27, was 0x07 */ 
+#define S3V_BITBLT	(0x0 << 27)
+#define S3V_RECTFILL	(0x2 << 27)
+#define S3V_AUTOEXE	0x01
+#define S3V_HWCLIP	0x02
+#define S3V_DRAW	0x20
+#define S3V_DST_8BPP	0x00
+#define S3V_DST_16BPP	0x04
+#define S3V_DST_24BPP	0x08
+#define S3V_MONO_PAT	0x100
+
+#define S3V_BLT_COPY	(0xcc<<17)
+#define S3V_BLT_CLEAR	(0x00<<17)
+#define S3V_BLT_SET	(0xff<<17)
diff -Nru a/drivers/zorro/Makefile b/drivers/zorro/Makefile
--- a/drivers/zorro/Makefile	Wed Jul 24 14:03:37 2002
+++ b/drivers/zorro/Makefile	Wed Jul 24 14:03:37 2002
@@ -7,7 +7,7 @@
 obj-$(CONFIG_ZORRO)	+= zorro.o names.o
 obj-$(CONFIG_PROC_FS)	+= proc.o
 
-host-progs 		:= gen_devlist
+host-progs 		:= gen-devlist
 
 include $(TOPDIR)/Rules.make
 
diff -Nru a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
--- a/drivers/zorro/zorro.c	Wed Jul 24 14:03:35 2002
+++ b/drivers/zorro/zorro.c	Wed Jul 24 14:03:35 2002
@@ -80,7 +80,7 @@
      *  FIXME: use the normal resource management
      */
 
-u32 zorro_unused_z2ram[4] = { 0, 0, 0, 0 };
+bitmap_member(zorro_unused_z2ram, 128);
 
 
 static void __init mark_region(unsigned long start, unsigned long end,
diff -Nru a/drivers/zorro/zorro.ids b/drivers/zorro/zorro.ids
--- a/drivers/zorro/zorro.ids	Wed Jul 24 14:03:39 2002
+++ b/drivers/zorro/zorro.ids	Wed Jul 24 14:03:39 2002
@@ -42,7 +42,7 @@
 	5000  A2620 68020 [Accelerator and RAM Expansion]
 	5100  A2630 68030 [Accelerator and RAM Expansion]
 	5400  A4091 [SCSI Host Adapter]
-	5a00  A2065 [Ethernet Card]]
+	5a00  A2065 [Ethernet Card]
 	6000  Romulator Card
 	6100  A3000 Test Fixture [Miscellaneous Expansion Card]
 	6700  A2386-SX [ISA Bus Bridge]
@@ -56,7 +56,7 @@
 02ff  Kolff Computer Supplies
 	0000  KCS Power PC [ISA Bus Bridge]
 03ec  Cardco Ltd.
-	0400  Kronos 2000 [SCSI Host Adapter]]
+	0400  Kronos 2000 [SCSI Host Adapter]
 	0c00  A1000 [SCSI Host Adapter]
 	0e00  Escort [SCSI Host Adapter]
 	f500  A2410 HiRes [Graphics Card]
diff -Nru a/fs/block_dev.c b/fs/block_dev.c
--- a/fs/block_dev.c	Wed Jul 24 14:03:39 2002
+++ b/fs/block_dev.c	Wed Jul 24 14:03:39 2002
@@ -37,14 +37,6 @@
 	return retval;
 }
 
-static loff_t blkdev_size(kdev_t dev)
-{
-	loff_t sz = blkdev_size_in_bytes(dev);
-	if (sz)
-		return sz;
-	return ~0ULL;
-}
-
 /* Kill _all_ buffers, dirty or not.. */
 static void kill_bdev(struct block_device *bdev)
 {
@@ -301,6 +293,8 @@
 			new_bdev->bd_queue = NULL;
 			new_bdev->bd_contains = NULL;
 			new_bdev->bd_inode = inode;
+			new_bdev->bd_part_count = 0;
+			sema_init(&new_bdev->bd_part_sem, 1);
 			inode->i_mode = S_IFBLK;
 			inode->i_rdev = kdev;
 			inode->i_bdev = new_bdev;
@@ -423,9 +417,9 @@
 	Return the function table of a device.
 	Load the driver if needed.
 */
-const struct block_device_operations * get_blkfops(unsigned int major)
+struct block_device_operations * get_blkfops(unsigned int major)
 {
-	const struct block_device_operations *ret = NULL;
+	struct block_device_operations *ret = NULL;
 
 	/* major 0 is used for non-device mounts */
 	if (major && major < MAX_BLKDEV) {
@@ -487,7 +481,7 @@
 int check_disk_change(kdev_t dev)
 {
 	int i;
-	const struct block_device_operations * bdops = NULL;
+	struct block_device_operations * bdops = NULL;
 
 	i = major(dev);
 	if (i < MAX_BLKDEV)
@@ -520,35 +514,28 @@
 	return 1;
 }
 
-int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
-{
-	int res;
-	mm_segment_t old_fs = get_fs();
-
-	if (!bdev->bd_op->ioctl)
-		return -EINVAL;
-	set_fs(KERNEL_DS);
-	res = bdev->bd_op->ioctl(bdev->bd_inode, NULL, cmd, arg);
-	set_fs(old_fs);
-	return res;
-}
-
 static int do_open(struct block_device *bdev, struct inode *inode, struct file *file)
 {
 	int ret = -ENXIO;
 	kdev_t dev = to_kdev_t(bdev->bd_dev);
 	struct module *owner = NULL;
+	struct block_device_operations *ops, *current_ops;
 
-	down(&bdev->bd_sem);
 	lock_kernel();
-	if (!bdev->bd_op) {
-		bdev->bd_op = get_blkfops(major(dev));
-		if (!bdev->bd_op)
-			goto out;
-		owner = bdev->bd_op->owner;
+	ops = get_blkfops(major(dev));
+	if (ops) {
+		owner = ops->owner;
 		if (owner)
 			__MOD_INC_USE_COUNT(owner);
 	}
+
+	down(&bdev->bd_sem);
+	if (!bdev->bd_op)
+		current_ops = ops;
+	else
+		current_ops = bdev->bd_op;
+	if (!current_ops)
+		goto out;
 	if (!bdev->bd_contains) {
 		unsigned minor = minor(dev);
 		struct gendisk *g = get_gendisk(dev);
@@ -569,15 +556,36 @@
 			}
 		}
 	}
-	if (bdev->bd_op->open) {
-		ret = bdev->bd_op->open(inode, file);
-		if (ret)
-			goto out2;
-	}
-	bdev->bd_inode->i_size = blkdev_size(dev);
+	if (bdev->bd_contains == bdev) {
+		if (current_ops->open) {
+			ret = current_ops->open(inode, file);
+			if (ret)
+				goto out2;
+		}
+	} else {
+		down(&bdev->bd_contains->bd_part_sem);
+		bdev->bd_contains->bd_part_count++;
+		up(&bdev->bd_contains->bd_part_sem);
+	}
+	if (!bdev->bd_op)
+		bdev->bd_op = ops;
+	else if (owner)
+		__MOD_DEC_USE_COUNT(owner);
 	if (!bdev->bd_openers) {
 		struct blk_dev_struct *p = blk_dev + major(dev);
+		struct gendisk *g = get_gendisk(dev);
 		unsigned bsize = bdev_hardsect_size(bdev);
+
+		bdev->bd_offset = 0;
+		if (g) {
+			bdev->bd_inode->i_size =
+				(loff_t) g->part[minor(dev)].nr_sects << 9;
+			bdev->bd_offset = g->part[minor(dev)].start_sect;
+		} else if (blk_size[major(dev)])
+			bdev->bd_inode->i_size =
+				(loff_t) blk_size[major(dev)][minor(dev)] << 10;
+		else
+			bdev->bd_inode->i_size = 0;
 		while (bsize < PAGE_CACHE_SIZE) {
 			if (bdev->bd_inode->i_size & bsize)
 				break;
@@ -601,14 +609,12 @@
 		}
 	}
 	bdev->bd_openers++;
-	unlock_kernel();
 	up(&bdev->bd_sem);
+	unlock_kernel();
 	return 0;
 
 out2:
 	if (!bdev->bd_openers) {
-		bdev->bd_op = NULL;
-		bdev->bd_queue = NULL;
 		bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
 		if (bdev != bdev->bd_contains) {
 			blkdev_put(bdev->bd_contains, BDEV_RAW);
@@ -619,8 +625,8 @@
 	if (owner)
 		__MOD_DEC_USE_COUNT(owner);
 out:
-	unlock_kernel();
 	up(&bdev->bd_sem);
+	unlock_kernel();
 	if (ret)
 		bdput(bdev);
 	return ret;
@@ -677,11 +683,17 @@
 	}
 	if (!--bdev->bd_openers)
 		kill_bdev(bdev);
-	if (bdev->bd_op->release)
-		ret = bdev->bd_op->release(bd_inode, NULL);
-	if (bdev->bd_op->owner)
-		__MOD_DEC_USE_COUNT(bdev->bd_op->owner);
+	if (bdev->bd_contains == bdev) {
+		if (bdev->bd_op->release)
+			ret = bdev->bd_op->release(bd_inode, NULL);
+	} else {
+		down(&bdev->bd_contains->bd_part_sem);
+		bdev->bd_contains->bd_part_count--;
+		up(&bdev->bd_contains->bd_part_sem);
+	}
 	if (!bdev->bd_openers) {
+		if (bdev->bd_op->owner)
+			__MOD_DEC_USE_COUNT(bdev->bd_op->owner);
 		bdev->bd_op = NULL;
 		bdev->bd_queue = NULL;
 		bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
@@ -706,15 +718,37 @@
 {
 	int ret = -EINVAL;
 	switch (cmd) {
+	/*
+	 * deprecated, use the /proc/iosched interface instead
+	 */
+	case BLKELVGET:
+	case BLKELVSET:
+		ret = -ENOTTY;
+		break;
 	case BLKRAGET:
+	case BLKROGET:
+	case BLKBSZGET:
+	case BLKSSZGET:
 	case BLKFRAGET:
+	case BLKSECTGET:
 	case BLKRASET:
 	case BLKFRASET:
+	case BLKBSZSET:
+	case BLKPG:
 		ret = blk_ioctl(inode->i_bdev, cmd, arg);
 		break;
 	default:
 		if (inode->i_bdev->bd_op->ioctl)
 			ret =inode->i_bdev->bd_op->ioctl(inode, file, cmd, arg);
+		if (ret == -EINVAL) {
+			switch (cmd) {
+				case BLKGETSIZE:
+				case BLKGETSIZE64:
+				case BLKFLSBUF:
+				case BLKROSET:
+					ret = blk_ioctl(inode->i_bdev,cmd,arg);
+			}
+		}
 		break;
 	}
 	return ret;
@@ -741,6 +775,16 @@
 	fsync:		block_fsync,
 	ioctl:		blkdev_ioctl,
 };
+
+int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
+{
+	int res;
+	mm_segment_t old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	res = blkdev_ioctl(bdev->bd_inode, NULL, cmd, arg);
+	set_fs(old_fs);
+	return res;
+}
 
 const char *__bdevname(kdev_t dev)
 {
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Wed Jul 24 14:03:35 2002
+++ b/fs/buffer.c	Wed Jul 24 14:03:35 2002
@@ -62,10 +62,7 @@
 	printk("buffer layer error at %s:%d\n", file, line);
 #ifdef CONFIG_X86
 	printk("Pass this trace through ksymoops for reporting\n");
-	{
-		extern void show_stack(long *esp);
-		show_stack(0);
-	}
+	show_stack(0);
 #endif
 }
 EXPORT_SYMBOL(__buffer_error);
diff -Nru a/fs/devfs/base.c b/fs/devfs/base.c
--- a/fs/devfs/base.c	Wed Jul 24 14:03:36 2002
+++ b/fs/devfs/base.c	Wed Jul 24 14:03:36 2002
@@ -633,6 +633,12 @@
     20020514   Richard Gooch <rgooch@atnf.csiro.au>
 	       Minor cleanup of <scan_dir_for_removable>.
   v1.17
+    20020721   Richard Gooch <rgooch@atnf.csiro.au>
+	       Switched to ISO C structure field initialisers.
+	       Switch to set_current_state() and move before add_wait_queue().
+    20020722   Richard Gooch <rgooch@atnf.csiro.au>
+	       Fixed devfs entry leak in <devfs_readdir> when *readdir fails.
+  v1.18
 */
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -665,7 +671,7 @@
 #include <asm/bitops.h>
 #include <asm/atomic.h>
 
-#define DEVFS_VERSION            "1.17 (20020514)"
+#define DEVFS_VERSION            "1.18 (20020722)"
 
 #define DEVFS_NAME "devfs"
 
@@ -877,7 +883,7 @@
 			  loff_t *ppos);
 static struct file_operations stat_fops =
 {
-    read:    stat_read,
+    .read    = stat_read,
 };
 #endif
 
@@ -885,9 +891,9 @@
 /*  Devfs daemon file operations  */
 static struct file_operations devfsd_fops =
 {
-    read:    devfsd_read,
-    ioctl:   devfsd_ioctl,
-    release: devfsd_close,
+    .read    = devfsd_read,
+    .ioctl   = devfsd_ioctl,
+    .release = devfsd_close,
 };
 
 
@@ -1446,12 +1452,12 @@
     if (fs_info->devfsd_task == NULL) return (TRUE);
     if (devfsd_queue_empty (fs_info) && fs_info->devfsd_sleeping) return TRUE;
     if ( is_devfsd_or_child (fs_info) ) return (FALSE);
+    set_current_state (TASK_UNINTERRUPTIBLE);
     add_wait_queue (&fs_info->revalidate_wait_queue, &wait);
-    current->state = TASK_UNINTERRUPTIBLE;
     if (!devfsd_queue_empty (fs_info) || !fs_info->devfsd_sleeping)
 	if (fs_info->devfsd_task) schedule ();
     remove_wait_queue (&fs_info->revalidate_wait_queue, &wait);
-    current->state = TASK_RUNNING;
+    __set_current_state (TASK_RUNNING);
     return (TRUE);
 }   /*  End Function wait_for_devfsd_finished  */
 
@@ -2576,9 +2582,9 @@
 
 static struct super_operations devfs_sops =
 { 
-    drop_inode:    generic_delete_inode,
-    clear_inode:   devfs_clear_inode,
-    statfs:        simple_statfs,
+    .drop_inode    = generic_delete_inode,
+    .clear_inode   = devfs_clear_inode,
+    .statfs        = simple_statfs,
 };
 
 
@@ -2724,19 +2730,20 @@
 	    {
 		err = (*filldir) (dirent, de->name, de->namelen,
 				  file->f_pos, de->inode.ino, de->mode >> 12);
-		if (err >= 0)
+		if (err < 0) devfs_put (de);
+		else
 		{
 		    file->f_pos++;
 		    ++stored;
 		}
 	    }
+	    if (err == -EINVAL) break;
+	    if (err < 0) return err;
 	    read_lock (&parent->u.dir.lock);
 	    next = devfs_get (de->next);
 	    read_unlock (&parent->u.dir.lock);
 	    devfs_put (de);
 	    de = next;
-	    if (err == -EINVAL) break;
-	    if (err < 0) return err;
 	}
 	break;
     }
@@ -2795,14 +2802,14 @@
 
 static struct file_operations devfs_fops =
 {
-    open:    devfs_open,
+    .open    = devfs_open,
 };
 
 static struct file_operations devfs_dir_fops =
 {
-    read:    generic_read_dir,
-    readdir: devfs_readdir,
-    open:    devfs_open,
+    .read    = generic_read_dir,
+    .readdir = devfs_readdir,
+    .open    = devfs_open,
 };
 
 
@@ -2844,19 +2851,19 @@
 
 static struct dentry_operations devfs_dops =
 {
-    d_delete:     devfs_d_delete,
-    d_release:    devfs_d_release,
-    d_iput:       devfs_d_iput,
+    .d_delete     = devfs_d_delete,
+    .d_release    = devfs_d_release,
+    .d_iput       = devfs_d_iput,
 };
 
 static int devfs_d_revalidate_wait (struct dentry *dentry, int flags);
 
 static struct dentry_operations devfs_wait_dops =
 {
-    d_delete:     devfs_d_delete,
-    d_release:    devfs_d_release,
-    d_iput:       devfs_d_iput,
-    d_revalidate: devfs_d_revalidate_wait,
+    .d_delete     = devfs_d_delete,
+    .d_release    = devfs_d_release,
+    .d_iput       = devfs_d_iput,
+    .d_revalidate = devfs_d_revalidate_wait,
 };
 
 /**
@@ -2943,8 +2950,8 @@
     read_lock (&parent->u.dir.lock);
     if (dentry->d_fsdata)
     {
+	set_current_state (TASK_UNINTERRUPTIBLE);
 	add_wait_queue (&lookup_info->wait_queue, &wait);
-	current->state = TASK_UNINTERRUPTIBLE;
 	read_unlock (&parent->u.dir.lock);
 	schedule ();
     }
@@ -3223,25 +3230,25 @@
 
 static struct inode_operations devfs_iops =
 {
-    setattr:        devfs_notify_change,
+    .setattr        = devfs_notify_change,
 };
 
 static struct inode_operations devfs_dir_iops =
 {
-    lookup:         devfs_lookup,
-    unlink:         devfs_unlink,
-    symlink:        devfs_symlink,
-    mkdir:          devfs_mkdir,
-    rmdir:          devfs_rmdir,
-    mknod:          devfs_mknod,
-    setattr:        devfs_notify_change,
+    .lookup         = devfs_lookup,
+    .unlink         = devfs_unlink,
+    .symlink        = devfs_symlink,
+    .mkdir          = devfs_mkdir,
+    .rmdir          = devfs_rmdir,
+    .mknod          = devfs_mknod,
+    .setattr        = devfs_notify_change,
 };
 
 static struct inode_operations devfs_symlink_iops =
 {
-    readlink:       devfs_readlink,
-    follow_link:    devfs_follow_link,
-    setattr:        devfs_notify_change,
+    .readlink       = devfs_readlink,
+    .follow_link    = devfs_follow_link,
+    .setattr        = devfs_notify_change,
 };
 
 static int devfs_fill_super (struct super_block *sb, void *data, int silent)
@@ -3279,9 +3286,9 @@
 
 static struct file_system_type devfs_fs_type =
 {
-    name:	DEVFS_NAME,
-    get_sb:	devfs_get_sb,
-    kill_sb:	kill_anon_super,
+    .name	= DEVFS_NAME,
+    .get_sb	= devfs_get_sb,
+    .kill_sb	= kill_anon_super,
 };
 
 /*  File operations for devfsd follow  */
@@ -3305,8 +3312,8 @@
     info->major = 0;
     info->minor = 0;
     /*  Block for a new entry  */
+    set_current_state (TASK_INTERRUPTIBLE);
     add_wait_queue (&fs_info->devfsd_wait_queue, &wait);
-    current->state = TASK_INTERRUPTIBLE;
     while ( devfsd_queue_empty (fs_info) )
     {
 	fs_info->devfsd_sleeping = TRUE;
@@ -3316,13 +3323,13 @@
 	if ( signal_pending (current) )
 	{
 	    remove_wait_queue (&fs_info->devfsd_wait_queue, &wait);
-	    current->state = TASK_RUNNING;
+	    __set_current_state (TASK_RUNNING);
 	    return -EINTR;
 	}
 	set_current_state (TASK_INTERRUPTIBLE);
     }
     remove_wait_queue (&fs_info->devfsd_wait_queue, &wait);
-    current->state = TASK_RUNNING;
+    __set_current_state (TASK_RUNNING);
     /*  Now play with the data  */
     ival = atomic_read (&fs_info->devfsd_overrun_count);
     info->overrun_count = ival;
diff -Nru a/fs/driverfs/inode.c b/fs/driverfs/inode.c
--- a/fs/driverfs/inode.c	Wed Jul 24 14:03:36 2002
+++ b/fs/driverfs/inode.c	Wed Jul 24 14:03:36 2002
@@ -267,7 +267,7 @@
 	if (count > PAGE_SIZE)
 		count = PAGE_SIZE;
 
-	dev = list_entry(entry->parent,struct device, dir);
+	dev = to_device(entry->parent);
 
 	page = (unsigned char*)__get_free_page(GFP_KERNEL);
 	if (!page)
@@ -328,7 +328,7 @@
 	if (!entry->store)
 		return 0;
 
-	dev = list_entry(entry->parent,struct device, dir);
+	dev = to_device(entry->parent);
 
 	page = (char *)__get_free_page(GFP_KERNEL);
 	if (!page)
@@ -394,7 +394,7 @@
 	entry = (struct driver_file_entry *)inode->u.generic_ip;
 	if (!entry)
 		return -EFAULT;
-	dev = (struct device *)list_entry(entry->parent,struct device,dir);
+	dev = to_device(entry->parent);
 	get_device(dev);
 	filp->private_data = entry;
 	return 0;
@@ -408,7 +408,7 @@
 	entry = (struct driver_file_entry *)filp->private_data;
 	if (!entry)
 		return -EFAULT;
-	dev = (struct device *)list_entry(entry->parent,struct device,dir);
+	dev = to_device(entry->parent);
 	put_device(dev);
 	return 0;
 }
diff -Nru a/fs/ext2/ext2.h b/fs/ext2/ext2.h
--- a/fs/ext2/ext2.h	Wed Jul 24 14:03:38 2002
+++ b/fs/ext2/ext2.h	Wed Jul 24 14:03:38 2002
@@ -34,7 +34,7 @@
 
 static inline struct ext2_inode_info *EXT2_I(struct inode *inode)
 {
-	return list_entry(inode, struct ext2_inode_info, vfs_inode);
+	return container_of(inode, struct ext2_inode_info, vfs_inode);
 }
 
 /* balloc.c */
diff -Nru a/fs/hfs/binsert.c b/fs/hfs/binsert.c
--- a/fs/hfs/binsert.c	Wed Jul 24 14:03:38 2002
+++ b/fs/hfs/binsert.c	Wed Jul 24 14:03:38 2002
@@ -16,21 +16,6 @@
 #include "hfs_btree.h"
 
 /*================ File-local functions ================*/
-
-/* btree locking functions */
-static inline void hfs_btree_lock(struct hfs_btree *tree)
-{
-  while (tree->lock) 
-    hfs_sleep_on(&tree->wait);
-  tree->lock = 1;
-}
-
-static inline void hfs_btree_unlock(struct hfs_btree *tree)
-{
-  tree->lock = 0;
-  hfs_wake_up(&tree->wait);
-}
-
 /*
  * binsert_nonfull()
  *
@@ -526,11 +511,11 @@
 		/* make certain we have enough nodes to proceed */
 		if ((tree->bthFree - tree->reserved) < reserve) {
 			hfs_brec_relse(&brec, NULL);
-			hfs_btree_lock(tree);
+			down(&tree->sem);
 			if ((tree->bthFree - tree->reserved) < reserve) {
 				hfs_btree_extend(tree);
 			}
-			hfs_btree_unlock(tree);
+			up(&tree->sem);
 			if ((tree->bthFree - tree->reserved) < reserve) {
 				return -ENOSPC;
 			} else {
diff -Nru a/fs/hfs/btree.c b/fs/hfs/btree.c
--- a/fs/hfs/btree.c	Wed Jul 24 14:03:37 2002
+++ b/fs/hfs/btree.c	Wed Jul 24 14:03:37 2002
@@ -172,8 +172,7 @@
 	bt->magic = HFS_BTREE_MAGIC;
 	bt->sys_mdb = mdb->sys_mdb;
 	bt->reserved = 0;
-	bt->lock = 0;
-	hfs_init_waitqueue(&bt->wait);
+	sema_init(&bt->sem, 1);
 	bt->dirt = 0;
 	memset(bt->cache, 0, sizeof(bt->cache));
 
diff -Nru a/fs/hfs/catalog.c b/fs/hfs/catalog.c
--- a/fs/hfs/catalog.c	Wed Jul 24 14:03:39 2002
+++ b/fs/hfs/catalog.c	Wed Jul 24 14:03:39 2002
@@ -302,8 +302,7 @@
 		entry->modify_date = hfs_get_nl(cat->u.dir.MdDat);
 		entry->backup_date = hfs_get_nl(cat->u.dir.BkDat);
 		dir->dirs = dir->files = 0;
-		hfs_init_waitqueue(&dir->read_wait);
-		hfs_init_waitqueue(&dir->write_wait);
+		init_rwsem(&dir->sem);
 	} else if (cat->cdrType == HFS_CDR_FIL) {
 		struct hfs_file *fil = &entry->u.file;
 
@@ -642,51 +641,6 @@
 }
 
 /*
- * Add a writer to dir, excluding readers.
- *
- * XXX: this is wrong. it allows a move to occur when a directory
- *      is being written to. 
- */
-static inline void start_write(struct hfs_cat_entry *dir)
-{
-	if (dir->u.dir.readers || waitqueue_active(&dir->u.dir.read_wait)) {
-		hfs_sleep_on(&dir->u.dir.write_wait);
-	}
-	++dir->u.dir.writers;
-}
-
-/*
- * Add a reader to dir, excluding writers.
- */
-static inline void start_read(struct hfs_cat_entry *dir)
-{
-	if (dir->u.dir.writers || waitqueue_active(&dir->u.dir.write_wait)) {
-		hfs_sleep_on(&dir->u.dir.read_wait);
-	}
-	++dir->u.dir.readers;
-}
-
-/*
- * Remove a writer from dir, possibly admitting readers.
- */
-static inline void end_write(struct hfs_cat_entry *dir)
-{
-	if (!(--dir->u.dir.writers)) {
-		hfs_wake_up(&dir->u.dir.read_wait);
-	}
-}
-
-/*
- * Remove a reader from dir, possibly admitting writers.
- */
-static inline void end_read(struct hfs_cat_entry *dir)
-{
-	if (!(--dir->u.dir.readers)) {
-		hfs_wake_up(&dir->u.dir.write_wait);
-	}
-}
-
-/*
  * create_entry()
  *
  * Add a new file or directory to the catalog B-tree and
@@ -707,7 +661,7 @@
 	}
 
 	/* keep readers from getting confused by changing dir size */
-	start_write(parent);
+	down_write(&parent->u.dir.sem);
 
 	/* create a locked entry in the cache */
 	entry = get_entry(mdb, key, 0);
@@ -782,7 +736,7 @@
 bail2:
 	hfs_cat_put(entry);
 done:
-	end_write(parent);
+	up_write(&parent->u.dir.sem);
 	return error;
 }
 
@@ -1058,21 +1012,19 @@
 	struct hfs_cat_key key;
 	int error;
 
-	if (dir->type != HFS_CDR_DIR) {
+	if (dir->type != HFS_CDR_DIR)
 		return -EINVAL;
-	}
 	
 	/* Block writers */
-	start_read(dir);
+	down_read(&dir->u.dir.sem);
 
 	/* Find the directory */
 	hfs_cat_build_key(dir->cnid, NULL, &key);
 	error = hfs_bfind(brec, dir->mdb->cat_tree,
 			  HFS_BKEY(&key), HFS_BFIND_READ_EQ);
 
-	if (error) {
-		end_read(dir);
-	}
+	if (error)
+		up_read(&dir->u.dir.sem);
 
 	return error;
 }
@@ -1109,7 +1061,7 @@
 		*type = ((struct hfs_cat_rec *)brec->data)->cdrType;
 		*cnid = brec_to_id(brec);
 	} else {
-		end_read(dir);
+		up_read(&dir->u.dir.sem);
 	}
 	return error;
 }
@@ -1127,7 +1079,7 @@
 {
 	if (dir && brec) {
 		hfs_brec_relse(brec, NULL);
-		end_read(dir);
+		up_read(&dir->u.dir.sem);
 	}
 }
 
@@ -1260,11 +1212,11 @@
 	}
 
 	/* keep readers from getting confused by changing dir size */
-	start_write(parent);
+	down_write(&parent->u.dir.sem);
 
 	/* don't delete a busy directory */
 	if (entry->type == HFS_CDR_DIR) {
-		start_read(entry);
+		down_read(&entry->u.dir.sem);
 
 		error = -ENOTEMPTY;
 		if (entry->u.dir.files || entry->u.dir.dirs) 
@@ -1299,10 +1251,9 @@
 	unlock_entry(entry);
 
 hfs_delete_end:
-	if (entry->type == HFS_CDR_DIR) {
-		end_read(entry);
-	}
-	end_write(parent);
+	if (entry->type == HFS_CDR_DIR)
+		up_read(&entry->u.dir.sem);
+	up_write(&parent->u.dir.sem);
 	return error;
 }
 
@@ -1347,10 +1298,10 @@
 	}
 
 	/* keep readers from getting confused by changing dir size */
-	start_write(new_dir);
-	if (old_dir != new_dir) {
-		start_write(old_dir);
-	}
+	down_write(&new_dir->u.dir.sem);
+	/* AV: smells like a deadlock */
+	if (old_dir != new_dir)
+		down_write(&old_dir->u.dir.sem);
 
 	/* Don't move a directory inside itself */
 	if (is_dir) {
@@ -1556,10 +1507,9 @@
 		hfs_cat_put(dest);
 	}
 done:
-	if (new_dir != old_dir) {
-		end_write(old_dir);
-	}
-	end_write(new_dir);
+	if (new_dir != old_dir)
+		up_write(&old_dir->u.dir.sem);
+	up_write(&new_dir->u.dir.sem);
 	return error;
 }
 
diff -Nru a/fs/hfs/hfs.h b/fs/hfs/hfs.h
--- a/fs/hfs/hfs.h	Wed Jul 24 14:03:38 2002
+++ b/fs/hfs/hfs.h	Wed Jul 24 14:03:38 2002
@@ -310,10 +310,7 @@
 	hfs_u16		flags;
 	hfs_u16		dirs;		/* Number of directories in this one */
 	hfs_u16		files;		/* Number of files in this directory */
-	int		readers;
-	hfs_wait_queue	read_wait;
-	int		writers;
-	hfs_wait_queue	write_wait;
+	struct rw_semaphore	sem;
 };
 
 /*
diff -Nru a/fs/hfs/hfs_btree.h b/fs/hfs/hfs_btree.h
--- a/fs/hfs/hfs_btree.h	Wed Jul 24 14:03:36 2002
+++ b/fs/hfs/hfs_btree.h	Wed Jul 24 14:03:36 2002
@@ -194,8 +194,7 @@
 	struct hfs_bnode		       /* The bnode cache */
 				*cache[HFS_CACHELEN];
 	struct hfs_cat_entry	entry;	       /* Fake catalog entry */
-	int			lock;
-	hfs_wait_queue		wait;
+	struct semaphore	sem;
 	int			dirt;
 	int                     keySize;   
 	/* Fields from the BTHdrRec in native byte-order: */
diff -Nru a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
--- a/fs/jffs/inode-v23.c	Wed Jul 24 14:03:38 2002
+++ b/fs/jffs/inode-v23.c	Wed Jul 24 14:03:38 2002
@@ -73,14 +73,13 @@
 /* Called by the VFS at mount time to initialize the whole file system.  */
 static int jffs_fill_super(struct super_block *sb, void *data, int silent)
 {
-	kdev_t dev = to_kdev_t(sb->s_dev);
 	struct inode *root_inode;
 	struct jffs_control *c;
 
 	D1(printk(KERN_NOTICE "JFFS: Trying to mount device %s.\n",
 		  sb->s_id));
 
-	if (major(dev) != MTD_BLOCK_MAJOR) {
+	if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) {
 		printk(KERN_WARNING "JFFS: Trying to mount a "
 		       "non-mtd device.\n");
 		return -EINVAL;
@@ -115,7 +114,7 @@
 
 #ifdef CONFIG_JFFS_PROC_FS
 	/* Set up the jffs proc file system.  */
-	if (jffs_register_jffs_proc_dir(dev, c) < 0) {
+	if (jffs_register_jffs_proc_dir(MINOR(sb->s_dev), c) < 0) {
 		printk(KERN_WARNING "JFFS: Failed to initialize the JFFS "
 			"proc file system for device %s.\n",
 			sb->s_id);
diff -Nru a/fs/jffs/jffs_proc.c b/fs/jffs/jffs_proc.c
--- a/fs/jffs/jffs_proc.c	Wed Jul 24 14:03:37 2002
+++ b/fs/jffs/jffs_proc.c	Wed Jul 24 14:03:37 2002
@@ -65,52 +65,39 @@
 /*
  * Register a JFFS partition directory (called upon mount)
  */
-int jffs_register_jffs_proc_dir(kdev_t dev, struct jffs_control *c)
+int jffs_register_jffs_proc_dir(int mtd, struct jffs_control *c)
 {
 	struct jffs_partition_dir *part_dir;
 	struct proc_dir_entry *part_info = 0;
 	struct proc_dir_entry *part_layout = 0;
 	struct proc_dir_entry *part_root = 0;
+	char name[10];
 
+	sprintf(name, "%d", mtd);
 	/* Allocate structure for local JFFS partition table */
-	if (!(part_dir = (struct jffs_partition_dir *)
-		kmalloc (sizeof (struct jffs_partition_dir), GFP_KERNEL))) {
-		return -ENOMEM;
-	}
+	part_dir = (struct jffs_partition_dir *)
+		kmalloc(sizeof (struct jffs_partition_dir), GFP_KERNEL);
+	if (!part_dir)
+		goto out;
 
 	/* Create entry for this partition */
-	if ((part_root = create_proc_entry (kdevname(dev),
-		S_IFDIR | S_IRUGO | S_IXUGO, jffs_proc_root))) {
-		part_root->read_proc = jffs_proc_info_read;
-		part_root->data = (void *) c;
-	}
-	else {
-		kfree (part_dir);
-		return -ENOMEM;
-	}
+	part_root = proc_mkdir(name, jffs_proc_root);
+	if (!part_root)
+		goto out1;
 
 	/* Create entry for 'info' file */
-	if ((part_info = create_proc_entry ("info", 0, part_root))) {
-		part_info->read_proc = jffs_proc_info_read;
-		part_info->data = (void *) c;
-	}
-	else {
-		remove_proc_entry (part_root->name, jffs_proc_root);
-		kfree (part_dir);
-		return -ENOMEM;
-	}
+	part_info = create_proc_entry ("info", 0, part_root);
+	if (!part_info)
+		goto out2;
+	part_info->read_proc = jffs_proc_info_read;
+	part_info->data = (void *) c;
 
 	/* Create entry for 'layout' file */
-	if ((part_layout = create_proc_entry ("layout", 0, part_root))) {
-		part_layout->read_proc = jffs_proc_layout_read;
-		part_layout->data = (void *) c;
-	}
-	else {
-		remove_proc_entry (part_info->name, part_root);
-		remove_proc_entry (part_root->name, jffs_proc_root);
-		kfree (part_dir);
-		return -ENOMEM;
-	}
+	part_layout = create_proc_entry ("layout", 0, part_root);
+	if (!part_layout)
+		goto out3;
+	part_layout->read_proc = jffs_proc_layout_read;
+	part_layout->data = (void *) c;
 
 	/* Fill in structure for table and insert in the list */
 	part_dir->c = c;
@@ -122,6 +109,15 @@
 
 	/* Return happy */
 	return 0;
+
+out3:
+	remove_proc_entry("info", part_root);
+out2:
+	remove_proc_entry(name, jffs_proc_root);
+out1:
+	kfree(part_dir);
+out:
+	return -ENOMEM;
 }
 
 
@@ -155,11 +151,7 @@
 			 * if it is.
 			 */
 			if (jffs_part_dirs == part_dir->next)
-#if LINUX_VERSION_CODE < 0x020300
-				remove_proc_entry ("jffs", &proc_root_fs);
-#else
 				remove_proc_entry ("jffs", proc_root_fs);
-#endif
 
 			/* Free memory for entry */
 			kfree(part_dir);
diff -Nru a/fs/jffs/jffs_proc.h b/fs/jffs/jffs_proc.h
--- a/fs/jffs/jffs_proc.h	Wed Jul 24 14:03:35 2002
+++ b/fs/jffs/jffs_proc.h	Wed Jul 24 14:03:35 2002
@@ -22,7 +22,7 @@
 /* The proc_dir_entry for jffs (defined in jffs_proc.c).  */
 extern struct proc_dir_entry *jffs_proc_root;
 
-int jffs_register_jffs_proc_dir(kdev_t dev, struct jffs_control *c);
+int jffs_register_jffs_proc_dir(int mtd, struct jffs_control *c);
 int jffs_unregister_jffs_proc_dir(struct jffs_control *c);
 
 #endif /* __LINUX_JFFS_PROC_H__ */
diff -Nru a/fs/jfs/file.c b/fs/jfs/file.c
--- a/fs/jfs/file.c	Wed Jul 24 14:03:37 2002
+++ b/fs/jfs/file.c	Wed Jul 24 14:03:37 2002
@@ -45,15 +45,6 @@
 	return rc ? -EIO : 0;
 }
 
-struct file_operations jfs_file_operations = {
-	open:		generic_file_open,
-	llseek:		generic_file_llseek,
-	write:		generic_file_write,
-	read:		generic_file_read,
-	mmap:		generic_file_mmap,
-	fsync:		jfs_fsync,
-};
-
 /*
  * Guts of jfs_truncate.  Called with locks already held.  Can be called
  * with directory for truncating directory index table.
@@ -98,5 +89,14 @@
 }
 
 struct inode_operations jfs_file_inode_operations = {
-	truncate:	jfs_truncate,
+	.truncate	= jfs_truncate,
+};
+
+struct file_operations jfs_file_operations = {
+	.open		= generic_file_open,
+	.llseek		= generic_file_llseek,
+	.write		= generic_file_write,
+	.read		= generic_file_read,
+	.mmap		= generic_file_mmap,
+	.fsync		= jfs_fsync,
 };
diff -Nru a/fs/jfs/inode.c b/fs/jfs/inode.c
--- a/fs/jfs/inode.c	Wed Jul 24 14:03:35 2002
+++ b/fs/jfs/inode.c	Wed Jul 24 14:03:35 2002
@@ -300,11 +300,11 @@
 }
 
 struct address_space_operations jfs_aops = {
-	readpage:	jfs_readpage,
-	writepage:	jfs_writepage,
-	sync_page:	block_sync_page,
-	prepare_write:	jfs_prepare_write,
-	commit_write:	generic_commit_write,
-	bmap:		jfs_bmap,
-	direct_IO:	jfs_direct_IO,
+	.readpage	= jfs_readpage,
+	.writepage	= jfs_writepage,
+	.sync_page	= block_sync_page,
+	.prepare_write	= jfs_prepare_write,
+	.commit_write	= generic_commit_write,
+	.bmap		= jfs_bmap,
+	.direct_IO	= jfs_direct_IO,
 };
diff -Nru a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
--- a/fs/jfs/jfs_dtree.c	Wed Jul 24 14:03:36 2002
+++ b/fs/jfs/jfs_dtree.c	Wed Jul 24 14:03:36 2002
@@ -2368,7 +2368,7 @@
 	xlen = lengthPXD(opxd);
 
 	jEVENT(0, ("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d\n",
-		   lmxaddr, oxaddr, nxaddr, xlen));
+		   (long long)lmxaddr, (long long)oxaddr, (long long)nxaddr, xlen));
 
 	/*
 	 *      1. get the internal parent dtpage covering
@@ -3044,7 +3044,7 @@
 				if (d_namleft == 0) {
 					jERROR(1,("JFS:Dtree error: "
 					  "ino = %ld, bn=%Ld, index = %d\n",
-						  ip->i_ino, bn, i));
+						  (long)ip->i_ino, (long long)bn, i));
 					updateSuper(ip->i_sb, FM_DIRTY);
 					goto skip_one;
 				}
@@ -3101,6 +3101,7 @@
       out:
 	kfree(d_name);
 	DT_PUTPAGE(mp);
+
 	return rc;
 }
 
diff -Nru a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
--- a/fs/jfs/jfs_logmgr.c	Wed Jul 24 14:03:38 2002
+++ b/fs/jfs/jfs_logmgr.c	Wed Jul 24 14:03:38 2002
@@ -1080,8 +1080,8 @@
 	 * file system to log have 1-to-1 relationship;
 	 */
 
-	log->bdev = sb->s_bdev;
 	log->flag = JFS_INLINELOG;
+	log->bdev = sb->s_bdev;
 	log->base = addressPXD(&JFS_SBI(sb)->logpxd);
 	log->size = lengthPXD(&JFS_SBI(sb)->logpxd) >>
 	    (L2LOGPSIZE - sb->s_blocksize_bits);
diff -Nru a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
--- a/fs/jfs/jfs_mount.c	Wed Jul 24 14:03:36 2002
+++ b/fs/jfs/jfs_mount.c	Wed Jul 24 14:03:36 2002
@@ -426,14 +426,15 @@
  */
 int updateSuper(struct super_block *sb, uint state)
 {
-	int rc;
-	metapage_t *mp;
 	struct jfs_superblock *j_sb;
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	metapage_t *mp;
+	int rc;
 
 	/*
 	 * Only fsck can fix dirty state
 	 */
-	if (JFS_SBI(sb)->state == FM_DIRTY)
+	if (sbi->state == FM_DIRTY)
 		return 0;
 
 	if ((rc = readSuper(sb, &mp)))
@@ -442,13 +443,12 @@
 	j_sb = (struct jfs_superblock *) (mp->data);
 
 	j_sb->s_state = cpu_to_le32(state);
-	JFS_SBI(sb)->state = state;
+	sbi->state = state;
 
 	if (state == FM_MOUNT) {
 		/* record log's dev_t and mount serial number */
-		j_sb->s_logdev =
-			cpu_to_le32(JFS_SBI(sb)->log->bdev->bd_dev);
-		j_sb->s_logserial = cpu_to_le32(JFS_SBI(sb)->log->serial);
+		j_sb->s_logdev = cpu_to_le32(sbi->log->bdev->bd_dev);
+		j_sb->s_logserial = cpu_to_le32(sbi->log->serial);
 	} else if (state == FM_CLEAN) {
 		/*
 		 * If this volume is shared with OS/2, OS/2 will need to
diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c	Wed Jul 24 14:03:38 2002
+++ b/fs/jfs/jfs_txnmgr.c	Wed Jul 24 14:03:38 2002
@@ -2824,10 +2824,7 @@
 			 * We can be running indefinately if other processors
 			 * are adding transactions to this list
 			 */
-			if (need_resched()) {
-				current->state = TASK_RUNNING;
-				schedule();
-			}
+			cond_resched();
 			LAZY_LOCK(flags);
 		}
 
@@ -2945,10 +2942,7 @@
 				 * Just to be safe.  I don't know how
 				 * long we can run without blocking
 				 */
-				if (need_resched()) {
-					current->state = TASK_RUNNING;
-					schedule();
-				}
+				cond_resched();
 				TXN_LOCK();
 			} else {
 				/* We can't get the write lock.  It may
diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c	Wed Jul 24 14:03:39 2002
+++ b/fs/jfs/namei.c	Wed Jul 24 14:03:39 2002
@@ -1437,19 +1437,19 @@
 }
 
 struct inode_operations jfs_dir_inode_operations = {
-	create:		jfs_create,
-	lookup:		jfs_lookup,
-	link:		jfs_link,
-	unlink:		jfs_unlink,
-	symlink:	jfs_symlink,
-	mkdir:		jfs_mkdir,
-	rmdir:		jfs_rmdir,
-	mknod:		jfs_mknod,
-	rename:		jfs_rename,
+	.create		= jfs_create,
+	.lookup		= jfs_lookup,
+	.link		= jfs_link,
+	.unlink		= jfs_unlink,
+	.symlink	= jfs_symlink,
+	.mkdir		= jfs_mkdir,
+	.rmdir		= jfs_rmdir,
+	.mknod		= jfs_mknod,
+	.rename		= jfs_rename,
 };
 
 struct file_operations jfs_dir_operations = {
-	read:		generic_read_dir,
-	readdir:	jfs_readdir,
-	fsync:		jfs_fsync,
+	.read		= generic_read_dir,
+	.readdir	= jfs_readdir,
+	.fsync		= jfs_fsync,
 };
diff -Nru a/fs/jfs/super.c b/fs/jfs/super.c
--- a/fs/jfs/super.c	Wed Jul 24 14:03:38 2002
+++ b/fs/jfs/super.c	Wed Jul 24 14:03:38 2002
@@ -36,6 +36,10 @@
 
 static kmem_cache_t * jfs_inode_cachep;
 
+static struct super_operations jfs_super_operations;
+static struct export_operations jfs_export_operations;
+static struct file_system_type jfs_fs_type;
+
 int jfs_stop_threads;
 static pid_t jfsIOthread;
 static pid_t jfsCommitThread;
@@ -223,21 +227,6 @@
 	return 0;
 }
 
-static struct super_operations jfs_super_operations = {
-	alloc_inode:	jfs_alloc_inode,
-	destroy_inode:	jfs_destroy_inode,
-	dirty_inode:	jfs_dirty_inode,
-	write_inode:	jfs_write_inode,
-	delete_inode:	jfs_delete_inode,
-	put_super:	jfs_put_super,
-	statfs:		jfs_statfs,
-	remount_fs:	jfs_remount,
-};
-
-static struct export_operations jfs_export_operations = {
-	get_parent:	jfs_get_parent,
-};
-
 static int jfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct jfs_sb_info *sbi;
@@ -362,12 +351,27 @@
 	return get_sb_bdev(fs_type, flags, dev_name, data, jfs_fill_super);
 }
 
+static struct super_operations jfs_super_operations = {
+	.alloc_inode	= jfs_alloc_inode,
+	.destroy_inode	= jfs_destroy_inode,
+	.dirty_inode	= jfs_dirty_inode,
+	.write_inode	= jfs_write_inode,
+	.delete_inode	= jfs_delete_inode,
+	.put_super	= jfs_put_super,
+	.statfs		= jfs_statfs,
+	.remount_fs	= jfs_remount,
+};
+
+static struct export_operations jfs_export_operations = {
+	.get_parent	= jfs_get_parent,
+};
+
 static struct file_system_type jfs_fs_type = {
-	owner:		THIS_MODULE,
-	name:		"jfs",
-	get_sb:		jfs_get_sb,
-	kill_sb:	kill_block_super,
-	fs_flags:	FS_REQUIRES_DEV,
+	.owner		= THIS_MODULE,
+	.name		= "jfs",
+	.get_sb		= jfs_get_sb,
+	.kill_sb	= kill_block_super,
+	.fs_flags	= FS_REQUIRES_DEV,
 };
 
 extern int metapage_init(void);
diff -Nru a/fs/jfs/symlink.c b/fs/jfs/symlink.c
--- a/fs/jfs/symlink.c	Wed Jul 24 14:03:38 2002
+++ b/fs/jfs/symlink.c	Wed Jul 24 14:03:38 2002
@@ -19,17 +19,6 @@
 #include <linux/fs.h>
 #include "jfs_incore.h"
 
-static int jfs_readlink(struct dentry *, char *buffer, int buflen);
-static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd);
-
-/*
- * symlinks can't do much...
- */
-struct inode_operations jfs_symlink_inode_operations = {
-	readlink:	jfs_readlink,
-	follow_link:	jfs_follow_link,
-};
-
 static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	char *s = JFS_IP(dentry->d_inode)->i_inline;
@@ -41,3 +30,9 @@
 	char *s = JFS_IP(dentry->d_inode)->i_inline;
 	return vfs_readlink(dentry, buffer, buflen, s);
 }
+
+struct inode_operations jfs_symlink_inode_operations = {
+	.readlink	= jfs_readlink,
+	.follow_link	= jfs_follow_link,
+};
+
diff -Nru a/fs/namei.c b/fs/namei.c
--- a/fs/namei.c	Wed Jul 24 14:03:37 2002
+++ b/fs/namei.c	Wed Jul 24 14:03:37 2002
@@ -1496,14 +1496,18 @@
 static void d_unhash(struct dentry *dentry)
 {
 	dget(dentry);
+	spin_lock(&dcache_lock);
 	switch (atomic_read(&dentry->d_count)) {
 	default:
+		spin_unlock(&dcache_lock);
 		shrink_dcache_parent(dentry);
+		spin_lock(&dcache_lock);
 		if (atomic_read(&dentry->d_count) != 2)
 			break;
 	case 2:
-		d_drop(dentry);
+		list_del_init(&dentry->d_hash);
 	}
+	spin_unlock(&dcache_lock);
 }
 
 int vfs_rmdir(struct inode *dir, struct dentry *dentry)
@@ -1590,21 +1594,16 @@
 
 	DQUOT_INIT(dir);
 
-	dget(dentry);
 	down(&dentry->d_inode->i_sem);
 	if (d_mountpoint(dentry))
 		error = -EBUSY;
-	else {
+	else
 		error = dir->i_op->unlink(dir, dentry);
-		if (!error)
-			d_delete(dentry);
-	}
 	up(&dentry->d_inode->i_sem);
-	dput(dentry);
-
-	if (!error)
+	if (!error) {
+		d_delete(dentry);
 		inode_dir_notify(dir, DN_DELETE);
-
+	}
 	return error;
 }
 
diff -Nru a/fs/nfs/dir.c b/fs/nfs/dir.c
--- a/fs/nfs/dir.c	Wed Jul 24 14:03:38 2002
+++ b/fs/nfs/dir.c	Wed Jul 24 14:03:38 2002
@@ -772,10 +772,6 @@
 		dentry->d_parent->d_name.name, dentry->d_name.name, 
 		atomic_read(&dentry->d_count));
 
-	if (atomic_read(&dentry->d_count) == 1)
-		goto out;  /* No need to silly rename. */
-
-
 #ifdef NFS_PARANOIA
 if (!dentry->d_inode)
 printk("NFS: silly-renaming %s/%s, negative dentry??\n",
@@ -837,31 +833,15 @@
 {
 	struct inode *dir = dentry->d_parent->d_inode;
 	struct inode *inode = dentry->d_inode;
-	int error = -EBUSY, rehash = 0;
+	int error = -EBUSY;
 		
 	dfprintk(VFS, "NFS: safe_remove(%s/%s)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name);
 
-	/*
-	 * Unhash the dentry while we remove the file ...
-	 */
-	if (!d_unhashed(dentry)) {
-		d_drop(dentry);
-		rehash = 1;
-	}
-	if (atomic_read(&dentry->d_count) > 1) {
-#ifdef NFS_PARANOIA
-		printk("nfs_safe_remove: %s/%s busy, d_count=%d\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,
-			atomic_read(&dentry->d_count));
-#endif
-		goto out;
-	}
-
 	/* If the dentry was sillyrenamed, we simply call d_delete() */
 	if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
 		error = 0;
-		goto out_delete;
+		goto out;
 	}
 
 	nfs_zap_caches(dir);
@@ -872,15 +852,7 @@
 		goto out;
 	if (inode)
 		inode->i_nlink--;
-
- out_delete:
-	/*
-	 * Free the inode
-	 */
-	d_delete(dentry);
 out:
-	if (rehash)
-		d_rehash(dentry);
 	return error;
 }
 
@@ -892,18 +864,29 @@
 static int nfs_unlink(struct inode *dir, struct dentry *dentry)
 {
 	int error;
+	int need_rehash = 0;
 
 	dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id,
 		dir->i_ino, dentry->d_name.name);
 
 	lock_kernel();
-	error = nfs_sillyrename(dir, dentry);
-	if (error && error != -EBUSY) {
-		error = nfs_safe_remove(dentry);
-		if (!error) {
-			nfs_renew_times(dentry);
-		}
+	spin_lock(&dcache_lock);
+	if (atomic_read(&dentry->d_count) > 1) {
+		spin_unlock(&dcache_lock);
+		error = nfs_sillyrename(dir, dentry);
+		unlock_kernel();
+		return error;
+	}
+	if (!d_unhashed(dentry)) {
+		list_del_init(&dentry->d_hash);
+		need_rehash = 1;
 	}
+	spin_unlock(&dcache_lock);
+	error = nfs_safe_remove(dentry);
+	if (!error)
+		nfs_renew_times(dentry);
+	else if (need_rehash)
+		d_rehash(dentry);
 	unlock_kernel();
 	return error;
 }
diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c
--- a/fs/nfsd/export.c	Wed Jul 24 14:03:38 2002
+++ b/fs/nfsd/export.c	Wed Jul 24 14:03:38 2002
@@ -701,10 +701,10 @@
 }
 
 struct seq_operations nfs_exports_op = {
-	start:	e_start,
-	next:	e_next,
-	stop:	e_stop,
-	show:	e_show,
+	.start	= e_start,
+	.next	= e_next,
+	.stop	= e_stop,
+	.show	= e_show,
 };
 
 /*
diff -Nru a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c
--- a/fs/nfsd/lockd.c	Wed Jul 24 14:03:37 2002
+++ b/fs/nfsd/lockd.c	Wed Jul 24 14:03:37 2002
@@ -61,12 +61,12 @@
 }
 
 struct nlmsvc_binding		nfsd_nlm_ops = {
-	exp_readlock:		exp_readlock,		/* lock export table for reading */
-	exp_unlock:		exp_readunlock,		/* unlock export table */
-	exp_getclient:		exp_getclient,		/* look up NFS client */
-	fopen:			nlm_fopen,		/* open file for locking */
-	fclose:			nlm_fclose,		/* close file */
-	detach:			exp_nlmdetach,		/* lockd shutdown notification */
+	.exp_readlock	= exp_readlock,		/* lock export table for reading */
+	.exp_unlock	= exp_readunlock,		/* unlock export table */
+	.exp_getclient	= exp_getclient,		/* look up NFS client */
+	.fopen		= nlm_fopen,		/* open file for locking */
+	.fclose		= nlm_fclose,		/* close file */
+	.detach		= exp_nlmdetach,		/* lockd shutdown notification */
 };
 
 /*
diff -Nru a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
--- a/fs/nfsd/nfsctl.c	Wed Jul 24 14:03:36 2002
+++ b/fs/nfsd/nfsctl.c	Wed Jul 24 14:03:36 2002
@@ -114,14 +114,14 @@
 }
 
 static struct file_operations writer_ops = {
-	write:	fs_write,
+	.write	= fs_write,
 };
 
 static struct file_operations reader_ops = {
-	write:	fs_write,
-	read:	TA_read,
-	open:	TA_open,
-	release:TA_release,
+	.write		= fs_write,
+	.read		= TA_read,
+	.open		= TA_open,
+	.release	= TA_release,
 };
 
 extern struct seq_operations nfs_exports_op;
@@ -130,10 +130,10 @@
 	return seq_open(file, &nfs_exports_op);
 }
 static struct file_operations exports_operations = {
-	open:		exports_open,
-	read:		seq_read,
-	llseek:		seq_lseek,
-	release:	seq_release,
+	.open		= exports_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
 };
 
 /*
@@ -305,7 +305,7 @@
  */
 
 static struct super_operations s_ops = {
-	statfs:		simple_statfs,
+	.statfs		= simple_statfs,
 };
 
 static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
@@ -371,10 +371,10 @@
 }
 
 static struct file_system_type nfsd_fs_type = {
-	owner:		THIS_MODULE,
-	name:		"nfsd",
-	get_sb:		nfsd_get_sb,
-	kill_sb:	kill_litter_super,
+	.owner		= THIS_MODULE,
+	.name		= "nfsd",
+	.get_sb		= nfsd_get_sb,
+	.kill_sb	= kill_litter_super,
 };
 
 static int __init init_nfsd(void)
diff -Nru a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
--- a/fs/nfsd/nfssvc.c	Wed Jul 24 14:03:35 2002
+++ b/fs/nfsd/nfssvc.c	Wed Jul 24 14:03:35 2002
@@ -324,35 +324,33 @@
 }
 
 static struct svc_version	nfsd_version2 = {
-		vs_vers:	2,
-		vs_nproc:	18,
-		vs_proc:	nfsd_procedures2,
-		vs_dispatch:	nfsd_dispatch
+		.vs_vers	= 2,
+		.vs_nproc	= 18,
+		.vs_proc	= nfsd_procedures2,
+		.vs_dispatch	= nfsd_dispatch
 };
 #ifdef CONFIG_NFSD_V3
 static struct svc_version	nfsd_version3 = {
-		vs_vers:	3,
-		vs_nproc:	22,
-		vs_proc:	nfsd_procedures3,
-		vs_dispatch:	nfsd_dispatch
+		.vs_vers	= 3,
+		.vs_nproc	= 22,
+		.vs_proc	= nfsd_procedures3,
+		.vs_dispatch	= nfsd_dispatch
 };
 #endif
 static struct svc_version *	nfsd_version[] = {
-	NULL,
-	NULL,
-	&nfsd_version2,
+	[2] = &nfsd_version2,
 #ifdef CONFIG_NFSD_V3
-	&nfsd_version3,
+	[3] = &nfsd_version3,
 #endif
 };
 
 #define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
 struct svc_program		nfsd_program = {
-	pg_prog:		NFS_PROGRAM,		/* program number */
-	pg_lovers:		2,			// version
-	pg_hivers:		NFSD_NRVERS-1,		// range
-	pg_nvers:		NFSD_NRVERS,		/* nr of entries in nfsd_version */
-	pg_vers:		nfsd_version,		/* version table */
-	pg_name:		"nfsd",			/* program name */
-	pg_stats:		&nfsd_svcstats,		/* version table */
+	.pg_prog		= NFS_PROGRAM,		/* program number */
+	.pg_lovers		= 2,			// version
+	.pg_hivers		= NFSD_NRVERS-1,	// range
+	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
+	.pg_vers		= nfsd_version,		/* version table */
+	.pg_name		= "nfsd",		/* program name */
+	.pg_stats		= &nfsd_svcstats,	/* version table */
 };
diff -Nru a/fs/nfsd/stats.c b/fs/nfsd/stats.c
--- a/fs/nfsd/stats.c	Wed Jul 24 14:03:35 2002
+++ b/fs/nfsd/stats.c	Wed Jul 24 14:03:35 2002
@@ -37,7 +37,7 @@
 
 struct nfsd_stats	nfsdstats;
 struct svc_stat		nfsd_svcstats = {
-	program:	&nfsd_program,
+	.program	= &nfsd_program,
 };
 
 static int
diff -Nru a/fs/partitions/acorn.c b/fs/partitions/acorn.c
--- a/fs/partitions/acorn.c	Wed Jul 24 14:03:35 2002
+++ b/fs/partitions/acorn.c	Wed Jul 24 14:03:35 2002
@@ -10,33 +10,14 @@
  *  Scan ADFS partitions on hard disk drives.
  */
 #include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/genhd.h>
 #include <linux/buffer_head.h>
 
 #include "check.h"
 #include "acorn.h"
 
-static void
-adfspart_setgeometry(kdev_t dev, unsigned int secspertrack, unsigned int heads)
-{
-#ifdef CONFIG_BLK_DEV_MFM
-	extern void xd_set_geometry(kdev_t dev, unsigned char, unsigned char,
-				    unsigned long, unsigned int);
-
-	if (major(dev) == MFM_ACORN_MAJOR) {
-		unsigned long totalblocks = hd->part[MINOR(dev)].nr_sects;
-		xd_set_geometry(dev, secspertrack, heads, totalblocks, 1);
-	}
-#endif
-}
-
 static struct adfs_discrecord *
-adfs_partition(struct gendisk *hd, char *name, char *data,
-	       unsigned long first_sector, int minor)
+adfs_partition(struct parsed_partitions *state, char *name, char *data,
+	       unsigned long first_sector, int slot)
 {
 	struct adfs_discrecord *dr;
 	unsigned int nr_sects;
@@ -54,14 +35,14 @@
 
 	if (name)
 		printk(" [%s]", name);
-	add_gd_partition(hd, minor, first_sector, nr_sects);
+	put_partition(state, slot, first_sector, nr_sects);
 	return dr;
 }
 
 #ifdef CONFIG_ACORN_PARTITION_RISCIX
 static int
-riscix_partition(struct gendisk *hd, struct block_device *bdev,
-		unsigned long first_sect, int minor, unsigned long nr_sects)
+riscix_partition(struct parsed_partitions *state, struct block_device *bdev,
+		unsigned long first_sect, int slot, unsigned long nr_sects)
 {
 	Sector sect;
 	struct riscix_record *rr;
@@ -79,39 +60,38 @@
 
 		printk(" <");
 
-		add_gd_partition(hd, minor++, first_sect, size);
+		put_partition(state, slot++, first_sect, size);
 		for (part = 0; part < 8; part++) {
 			if (rr->part[part].one &&
 			    memcmp(rr->part[part].name, "All\0", 4)) {
-				add_gd_partition(hd, minor++,
-						le32_to_cpu(rr->part[part].start),
-						le32_to_cpu(rr->part[part].length));
+				put_partition(state, slot++,
+					le32_to_cpu(rr->part[part].start),
+					le32_to_cpu(rr->part[part].length));
 				printk("(%s)", rr->part[part].name);
 			}
 		}
 
 		printk(" >\n");
 	} else {
-		add_gd_partition(hd, minor++, first_sect, nr_sects);
+		put_partition(state, slot++, first_sect, nr_sects);
 	}
 
 	put_dev_sector(sect);
-	return minor;
+	return slot;
 }
 #endif
 
 static int
-linux_partition(struct gendisk *hd, struct block_device *bdev,
-		unsigned long first_sect, int minor, unsigned long nr_sects)
+linux_partition(struct parsed_partitions *state, struct block_device *bdev,
+		unsigned long first_sect, int slot, unsigned long nr_sects)
 {
 	Sector sect;
 	struct linux_part *linuxp;
-	unsigned int mask = (1 << hd->minor_shift) - 1;
 	unsigned long size = nr_sects > 2 ? 2 : nr_sects;
 
 	printk(" [Linux]");
 
-	add_gd_partition(hd, minor++, first_sect, size);
+	put_partition(state, slot++, first_sect, size);
 
 	linuxp = (struct linux_part *)read_dev_sector(bdev, first_sect, &sect);
 	if (!linuxp)
@@ -120,9 +100,9 @@
 	printk(" <");
 	while (linuxp->magic == cpu_to_le32(LINUX_NATIVE_MAGIC) ||
 	       linuxp->magic == cpu_to_le32(LINUX_SWAP_MAGIC)) {
-		if (!(minor & mask))
+		if (slot == state->limit)
 			break;
-		add_gd_partition(hd, minor++, first_sect +
+		put_partition(state, slot++, first_sect +
 				 le32_to_cpu(linuxp->start_sect),
 				 le32_to_cpu(linuxp->nr_sects));
 		linuxp ++;
@@ -130,19 +110,20 @@
 	printk(" >");
 
 	put_dev_sector(sect);
-	return minor;
+	return slot;
 }
 
 #ifdef CONFIG_ACORN_PARTITION_CUMANA
 static int
-adfspart_check_CUMANA(struct gendisk *hd, struct block_device *bdev,
-		      unsigned long first_sector, int minor)
+adfspart_check_CUMANA(struct parsed_partitions *state, struct block_device *bdev)
 {
-	unsigned int start_blk = 0, mask = (1 << hd->minor_shift) - 1;
+	unsigned long first_sector = 0;
+	unsigned int start_blk = 0;
 	Sector sect;
 	unsigned char *data;
 	char *name = "CUMANA/ADFS";
 	int first = 1;
+	int slot = 1;
 
 	/*
 	 * Try Cumana style partitions - sector 3 contains ADFS boot block
@@ -165,10 +146,10 @@
 		if (!data)
 			return -1;
 
-		if (!(minor & mask))
+		if (slot == state->limit)
 			break;
 
-		dr = adfs_partition(hd, name, data, first_sector, minor++);
+		dr = adfs_partition(state, name, data, first_sector, slot++);
 		if (!dr)
 			break;
 
@@ -193,19 +174,19 @@
 #ifdef CONFIG_ACORN_PARTITION_RISCIX
 		case PARTITION_RISCIX_SCSI:
 			/* RISCiX - we don't know how to find the next one. */
-			minor = riscix_partition(hd, bdev, first_sector,
-						 minor, nr_sects);
+			slot = riscix_partition(state, bdev, first_sector,
+						 slot, nr_sects);
 			break;
 #endif
 
 		case PARTITION_LINUX:
-			minor = linux_partition(hd, bdev, first_sector,
-						minor, nr_sects);
+			slot = linux_partition(state, bdev, first_sector,
+						slot, nr_sects);
 			break;
 		}
 		put_dev_sector(sect);
-		if (minor == -1)
-			return minor;
+		if (slot == -1)
+			return -1;
 	} while (1);
 	put_dev_sector(sect);
 	return first ? 0 : 1;
@@ -218,8 +199,6 @@
  *
  * Params : hd		- pointer to gendisk structure to store partition info.
  *	    dev		- device number to access.
- *	    first_sector- first readable sector on the device.
- *	    minor	- first available minor on device.
  *
  * Returns: -1 on error, 0 for no ADFS boot sector, 1 for ok.
  *
@@ -228,20 +207,20 @@
  *	    hda2 = non-ADFS partition.
  */
 static int
-adfspart_check_ADFS(struct gendisk *hd, struct block_device *bdev,
-		   unsigned long first_sector, int minor)
+adfspart_check_ADFS(struct parsed_partitions *state, struct block_device *bdev)
 {
 	unsigned long start_sect, nr_sects, sectscyl, heads;
 	Sector sect;
 	unsigned char *data;
 	struct adfs_discrecord *dr;
 	unsigned char id;
+	int slot = 1;
 
 	data = read_dev_sector(bdev, 6, &sect);
 	if (!data)
 		return -1;
 
-	dr = adfs_partition(hd, "ADFS", data, first_sector, minor++);
+	dr = adfs_partition(state, "ADFS", data, 0, slot++);
 	if (!dr) {
 		put_dev_sector(sect);
     		return 0;
@@ -253,9 +232,15 @@
 	id = data[0x1fc] & 15;
 	put_dev_sector(sect);
 
-	adfspart_setgeometry(to_kdev_t(bdev->bd_dev), dr->secspertrack, heads);
-	invalidate_bdev(bdev, 1);
-	truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
+#ifdef CONFIG_BLK_DEV_MFM
+	if (MAJOR(bdev->bd_dev) == MFM_ACORN_MAJOR) {
+		extern void xd_set_geometry(struct block_device *,
+			unsigned char, unsigned char, unsigned int);
+		xd_set_geometry(bdev, dr->secspertrack, heads, 1);
+		invalidate_bdev(bdev, 1);
+		truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
+	}
+#endif
 
 	/*
 	 * Work out start of non-adfs partition.
@@ -263,20 +248,18 @@
 	nr_sects = (bdev->bd_inode->i_size >> 9) - start_sect;
 
 	if (start_sect) {
-		first_sector += start_sect;
-
 		switch (id) {
 #ifdef CONFIG_ACORN_PARTITION_RISCIX
 		case PARTITION_RISCIX_SCSI:
 		case PARTITION_RISCIX_MFM:
-			minor = riscix_partition(hd, bdev, first_sector,
-						 minor, nr_sects);
+			slot = riscix_partition(state, bdev, start_sect,
+						 slot, nr_sects);
 			break;
 #endif
 
 		case PARTITION_LINUX:
-			minor = linux_partition(hd, bdev, first_sector,
-						minor, nr_sects);
+			slot = linux_partition(state, bdev, start_sect,
+						slot, nr_sects);
 			break;
 		}
 	}
@@ -304,8 +287,6 @@
  * Purpose: allocate ICS partitions.
  * Params : hd		- pointer to gendisk structure to store partition info.
  *	    dev		- device number to access.
- *	    first_sector- first readable sector on the device.
- *	    minor	- first available minor on device.
  * Returns: -1 on error, 0 for no ICS table, 1 for partitions ok.
  * Alloc  : hda  = whole drive
  *	    hda1 = ADFS partition 0 on first drive.
@@ -313,13 +294,13 @@
  *		..etc..
  */
 static int
-adfspart_check_ICS(struct gendisk *hd, struct block_device *bdev,
-		   unsigned long first_sector, int minor)
+adfspart_check_ICS(struct parsed_partitions *state, struct block_device *bdev)
 {
 	Sector sect;
 	unsigned char *data;
 	unsigned long sum;
-	unsigned int i, mask = (1 << hd->minor_shift) - 1;
+	unsigned int i;
+	int slot;
 	struct ics_part *p;
 
 	/*
@@ -343,16 +324,13 @@
 
 	printk(" [ICS]");
 
-	for (p = (struct ics_part *)data; p->size; p++) {
-		unsigned long start;
-		long size;
+	for (slot = 1, p = (struct ics_part *)data; p->size; p++) {
+		u32 start = le32_to_cpu(p->start);
+		u32 size = le32_to_cpu(p->size);
 
-		if ((minor & mask) == 0)
+		if (slot == state->limit)
 			break;
 
-		start = le32_to_cpu(p->start);
-		size  = le32_to_cpu(p->size);
-
 		if (size < 0) {
 			size = -size;
 
@@ -366,10 +344,8 @@
 			}
 		}
 
-		if (size) {
-			add_gd_partition(hd, minor, first_sector + start, size);
-			minor++;
-		}
+		if (size)
+			put_partition(state, slot++, start, size);
 	}
 
 	put_dev_sector(sect);
@@ -381,8 +357,6 @@
  * Purpose: allocate ICS partitions.
  * Params : hd		- pointer to gendisk structure to store partition info.
  *	    dev		- device number to access.
- *	    first_sector- first readable sector on the device.
- *	    minor	- first available minor on device.
  * Returns: -1 on error, 0 for no ICS table, 1 for partitions ok.
  * Alloc  : hda  = whole drive
  *	    hda1 = ADFS partition 0 on first drive.
@@ -391,13 +365,13 @@
  */
 #ifdef CONFIG_ACORN_PARTITION_POWERTEC
 static int
-adfspart_check_POWERTEC(struct gendisk *hd, struct block_device *bdev,
-			unsigned long first_sector, int minor)
+adfspart_check_POWERTEC(struct parsed_partitions *state, struct block_device *bdev)
 {
 	Sector sect;
 	unsigned char *data;
 	struct ptec_partition *p;
 	unsigned char checksum;
+	int slot = 1;
 	int i;
 
 	data = read_dev_sector(bdev, 0, &sect);
@@ -415,16 +389,11 @@
 	printk(" [POWERTEC]");
 
 	for (i = 0, p = (struct ptec_partition *)data; i < 12; i++, p++) {
-		unsigned long start;
-		unsigned long size;
-
-		start = le32_to_cpu(p->start);
-		size  = le32_to_cpu(p->size);
+		u32 start = le32_to_cpu(p->start);
+		u32 size = le32_to_cpu(p->size);
 
 		if (size)
-			add_gd_partition(hd, minor, first_sector + start,
-					 size);
-		minor++;
+			put_partition(state, slot++, start, size);
 	}
 
 	put_dev_sector(sect);
@@ -432,7 +401,7 @@
 }
 #endif
 
-static int (*partfn[])(struct gendisk *, struct block_device *, unsigned long, int) = {
+static int (*partfn[])(struct parsed_partitions *, struct block_device *) = {
 #ifdef CONFIG_ACORN_PARTITION_ICS
 	adfspart_check_ICS,
 #endif
@@ -454,18 +423,15 @@
  *
  * Params : hd		- pointer to gendisk structure
  *          dev		- device number to access
- *	    first_sect  - first available sector on the disk.
- *	    first_minor	- first available minor on this device.
  *
  * Returns: -1 on error, 0 if not ADFS format, 1 if ok.
  */
-int acorn_partition(struct gendisk *hd, struct block_device *bdev,
-		    unsigned long first_sect, int first_minor)
+int acorn_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	int i;
 
 	for (i = 0; partfn[i]; i++) {
-		int r = partfn[i](hd, bdev, first_sect, first_minor);
+		int r = partfn[i](state, bdev);
 		if (r) {
 			if (r > 0)
 				printk("\n");
diff -Nru a/fs/partitions/acorn.h b/fs/partitions/acorn.h
--- a/fs/partitions/acorn.h	Wed Jul 24 14:03:38 2002
+++ b/fs/partitions/acorn.h	Wed Jul 24 14:03:38 2002
@@ -50,6 +50,4 @@
 };
 	
 
-int acorn_partition(struct gendisk *hd, struct block_device *bdev,
-		   unsigned long first_sect, int first_minor);
-
+int acorn_partition(struct parsed_partitions *state, struct block_device *bdev);
diff -Nru a/fs/partitions/amiga.c b/fs/partitions/amiga.c
--- a/fs/partitions/amiga.c	Wed Jul 24 14:03:38 2002
+++ b/fs/partitions/amiga.c	Wed Jul 24 14:03:38 2002
@@ -7,14 +7,7 @@
  *  Re-organised Feb 1998 Russell King
  */
 
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/blk.h>
-
-#include <asm/byteorder.h>
+#include <linux/types.h>
 #include <linux/affs_hardblocks.h>
 
 #include "check.h"
@@ -31,14 +24,14 @@
 }
 
 int
-amiga_partition(struct gendisk *hd, struct block_device *bdev,
-		unsigned long first_sector, int first_part_minor)
+amiga_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	Sector sect;
 	unsigned char *data;
 	struct RigidDiskBlock *rdb;
 	struct PartitionBlock *pb;
 	int start_sect, nr_sects, blk, part, res = 0;
+	int slot = 1;
 
 	for (blk = 0; ; blk++, put_dev_sector(sect)) {
 		if (blk == RDB_ALLOCATION_LIMIT)
@@ -100,8 +93,7 @@
 		start_sect = be32_to_cpu(pb->pb_Environment[9]) *
 			     be32_to_cpu(pb->pb_Environment[3]) *
 			     be32_to_cpu(pb->pb_Environment[5]);
-		add_gd_partition(hd,first_part_minor,start_sect,nr_sects);
-		first_part_minor++;
+		put_partition(state,slot++,start_sect,nr_sects);
 		res = 1;
 	}
 	printk("\n");
diff -Nru a/fs/partitions/amiga.h b/fs/partitions/amiga.h
--- a/fs/partitions/amiga.h	Wed Jul 24 14:03:38 2002
+++ b/fs/partitions/amiga.h	Wed Jul 24 14:03:38 2002
@@ -2,7 +2,5 @@
  *  fs/partitions/amiga.h
  */
 
-int
-amiga_partition(struct gendisk *hd, struct block_device *bdev,
-		unsigned long first_sector, int first_part_minor);
+int amiga_partition(struct parsed_partitions *state, struct block_device *bdev);
 
diff -Nru a/fs/partitions/atari.c b/fs/partitions/atari.c
--- a/fs/partitions/atari.c	Wed Jul 24 14:03:37 2002
+++ b/fs/partitions/atari.c	Wed Jul 24 14:03:37 2002
@@ -7,17 +7,7 @@
  *  Re-organised Feb 1998 Russell King
  */
 
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/blk.h>
 #include <linux/ctype.h>
-
-#include <asm/byteorder.h>
-#include <asm/system.h>
-
 #include "check.h"
 #include "atari.h"
 
@@ -40,15 +30,14 @@
 		memcmp (s, "RAW", 3) == 0 ;
 }
 
-int atari_partition (struct gendisk *hd, struct block_device *bdev,
-		     unsigned long first_sector, int minor)
+int atari_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
-	int m_lim = minor + (1 << hd->minor_shift);
 	Sector sect;
 	struct rootsector *rs;
 	struct partition_info *pi;
 	u32 extensect;
 	u32 hd_size;
+	int slot;
 #ifdef ICD_PARTS
 	int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
 #endif
@@ -58,7 +47,7 @@
 		return -1;
 
 	/* Verify this is an Atari rootsector: */
-	hd_size = hd->part[minor - 1].nr_sects;
+	hd_size = bdev->bd_inode->i_size >> 9;
 	if (!VALID_PARTITION(&rs->part[0], hd_size) &&
 	    !VALID_PARTITION(&rs->part[1], hd_size) &&
 	    !VALID_PARTITION(&rs->part[2], hd_size) &&
@@ -74,7 +63,7 @@
 
 	pi = &rs->part[0];
 	printk (" AHDI");
-	for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++) {
+	for (slot = 1; pi < &rs->part[4] && slot < state->limit; slot++, pi++) {
 		struct rootsector *xrs;
 		Sector sect2;
 		ulong partsect;
@@ -84,7 +73,7 @@
 		/* active partition */
 		if (memcmp (pi->id, "XGM", 3) != 0) {
 			/* we don't care about other id's */
-			add_gd_partition (hd, minor, be32_to_cpu(pi->st),
+			put_partition (state, slot, be32_to_cpu(pi->st),
 					be32_to_cpu(pi->siz));
 			continue;
 		}
@@ -109,7 +98,7 @@
 				break;
 			}
 
-			add_gd_partition(hd, minor,
+			put_partition(state, slot,
 				   partsect + be32_to_cpu(xrs->part[0].st),
 				   be32_to_cpu(xrs->part[0].siz));
 
@@ -126,8 +115,7 @@
 
 			partsect = be32_to_cpu(xrs->part[1].st) + extensect;
 			put_dev_sector(sect2);
-			minor++;
-			if (minor >= m_lim) {
+			if (++slot == state->limit) {
 				printk( "\nMaximum number of partitions reached!\n" );
 				break;
 			}
@@ -140,12 +128,12 @@
 		/* sanity check: no ICD format if first partition invalid */
 		if (OK_id(pi->id)) {
 			printk(" ICD<");
-			for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++) {
+			for (; pi < &rs->icdpart[8] && slot < state->limit; slot++, pi++) {
 				/* accept only GEM,BGM,RAW,LNX,SWP partitions */
 				if (!((pi->flg & 1) && OK_id(pi->id)))
 					continue;
 				part_fmt = 2;
-				add_gd_partition (hd, minor,
+				put_partition (state, slot,
 						be32_to_cpu(pi->st),
 						be32_to_cpu(pi->siz));
 			}
@@ -159,4 +147,3 @@
 
 	return 1;
 }
-
diff -Nru a/fs/partitions/atari.h b/fs/partitions/atari.h
--- a/fs/partitions/atari.h	Wed Jul 24 14:03:35 2002
+++ b/fs/partitions/atari.h	Wed Jul 24 14:03:35 2002
@@ -31,6 +31,4 @@
   u16 checksum;			/* checksum for bootable disks */
 } __attribute__((__packed__));
 
-int atari_partition (struct gendisk *hd, struct block_device *bdev,
-		     unsigned long first_sector, int first_part_minor);
-
+int atari_partition(struct parsed_partitions *state, struct block_device *bdev);
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c	Wed Jul 24 14:03:37 2002
+++ b/fs/partitions/check.c	Wed Jul 24 14:03:37 2002
@@ -34,10 +34,13 @@
 #include "ultrix.h"
 #include "efi.h"
 
+#if CONFIG_BLK_DEV_MD
+extern void md_autodetect_dev(kdev_t dev);
+#endif
+
 int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
 
-static int (*check_part[])(struct gendisk *hd, struct block_device *bdev,
-			   unsigned long first_sect, int first_minor) = {
+static int (*check_part[])(struct parsed_partitions *, struct block_device *) = {
 #ifdef CONFIG_ACORN_PARTITION
 	acorn_partition,
 #endif
@@ -199,28 +202,6 @@
 	return buf;
 }
 
-/*
- * Add a partitions details to the devices partition description.
- */
-void add_gd_partition(struct gendisk *hd, int minor, int start, int size)
-{
-#ifndef CONFIG_DEVFS_FS
-	char buf[40];
-#endif
-
-	hd->part[minor].start_sect = start;
-	hd->part[minor].nr_sects   = size;
-#ifdef CONFIG_DEVFS_FS
-	printk(" p%d", (minor & ((1 << hd->minor_shift) - 1)));
-#else
-	if ((hd->major >= COMPAQ_SMART2_MAJOR+0 && hd->major <= COMPAQ_SMART2_MAJOR+7) ||
-	    (hd->major >= COMPAQ_CISS_MAJOR+0 && hd->major <= COMPAQ_CISS_MAJOR+7))
-		printk(" p%d", (minor & ((1 << hd->minor_shift) - 1)));
-	else
-		printk(" %s", disk_name(hd, minor, buf));
-#endif
-}
-
 /* Driverfs file support */
 static ssize_t partition_device_kdev_read(struct device *driverfs_dev, 
 			char *page, size_t count, loff_t off)
@@ -255,6 +236,7 @@
 	int max_p;
 	int part;
 	devfs_handle_t dir = 0;
+	struct hd_struct *p = hd->part + minor;
 	
 	/* get parent driverfs device structure */
 	if (hd->driverfs_dev_arr)
@@ -279,9 +261,9 @@
 	
 	/* for all partitions setup parents and device node names */
 	for(part=0; part < max_p; part++) {
-		if ((part == 0) || (hd->part[minor + part].nr_sects >= 1)) {
+		if ((part == 0) || (p[part].nr_sects >= 1)) {
 			struct device * current_driverfs_dev = 
-				&hd->part[minor+part].hd_driverfs_dev;
+				&p[part].hd_driverfs_dev;
 			current_driverfs_dev->parent = parent;
 			/* handle disc case */
 			current_driverfs_dev->driver_data =
@@ -319,7 +301,6 @@
 					&partition_device_kdev_file);
 		}
 	}
-	return;
 }
 
 void driverfs_remove_partitions(struct gendisk *hd, int minor)
@@ -327,14 +308,14 @@
 	int max_p;
 	int part;
 	struct device * current_driverfs_dev;
+	struct hd_struct *p = hd->part + minor;
 	
 	max_p=(1 << hd->minor_shift);
 	
 	/* for all parts setup parent relationships and device node names */
 	for(part=1; part < max_p; part++) {
-		if ((hd->part[minor + part].nr_sects >= 1)) {
-			current_driverfs_dev = 
-				&hd->part[minor + part].hd_driverfs_dev;
+		if ((p[part].nr_sects >= 1)) {
+			current_driverfs_dev = &p[part].hd_driverfs_dev;
 			device_remove_file(current_driverfs_dev,
 					partition_device_type_file.name);
 			device_remove_file(current_driverfs_dev,
@@ -342,7 +323,7 @@
 			put_device(current_driverfs_dev);	
 		}
 	}
-	current_driverfs_dev = &hd->part[minor].hd_driverfs_dev;
+	current_driverfs_dev = &p->hd_driverfs_dev;
 	device_remove_file(current_driverfs_dev, 
 				partition_device_type_file.name);
 	device_remove_file(current_driverfs_dev, 
@@ -351,12 +332,13 @@
 	return;
 }
 
-static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor)
+static void check_partition(struct gendisk *hd, kdev_t dev)
 {
 	devfs_handle_t de = NULL;
 	unsigned long first_sector;
 	struct block_device *bdev;
 	char buf[64];
+	struct parsed_partitions *state;
 	int i;
 
 	first_sector = hd->part[minor(dev)].start_sect;
@@ -369,56 +351,66 @@
 		hd->part[minor(dev)].start_sect = 0;
 		return;
 	}
+	if (first_sector != 0)
+		BUG();
+
+	state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL);
+	if (!state)
+		return;
 
 	if (hd->de_arr)
 		de = hd->de_arr[minor(dev) >> hd->minor_shift];
 	i = devfs_generate_path (de, buf, sizeof buf);
-	if (i >= 0)
+	if (i >= 0) {
 		printk(KERN_INFO " /dev/%s:", buf + i);
-	else
-		printk(KERN_INFO " %s:", disk_name(hd, minor(dev), buf));
-	bdev = bdget(kdev_t_to_nr(dev));
-	bdev->bd_contains = bdev;
-	bdev->bd_inode->i_size = (loff_t)hd->part[minor(dev)].nr_sects << 9;
-	if (!bdev->bd_openers) {
-		struct blk_dev_struct *p = blk_dev + major(dev);
-		unsigned bsize = bdev_hardsect_size(bdev);
-		while (bsize < PAGE_CACHE_SIZE) {
-			if (bdev->bd_inode->i_size & bsize)
-				break;
-			bsize <<= 1;
-		}
-		if (p->queue)
-			bdev->bd_queue =  p->queue(dev);
-		else
-			bdev->bd_queue = &p->request_queue;
-		bdev->bd_block_size = bsize;
-		bdev->bd_inode->i_blkbits = blksize_bits(bsize);
+		sprintf(state->name, "p");
+	} else {
+		unsigned n = hd->major;
+		disk_name(hd, minor(dev), state->name);
+		printk(KERN_INFO " %s:", state->name);
+		if (n - COMPAQ_SMART2_MAJOR <= 7 || n - COMPAQ_CISS_MAJOR <= 7)
+			sprintf(state->name, "p");
 	}
+	bdev = bdget(kdev_t_to_nr(dev));
+	if (blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW))
+		goto out;
+	state->limit = 1<<hd->minor_shift;
 	for (i = 0; check_part[i]; i++) {
-		int res;
-		res = check_part[i](hd, bdev, first_sector, first_part_minor);
-		if (res) {
-			if (res < 0 &&  warn_no_part)
+		int res, j;
+		memset(&state->parts, 0, sizeof(state->parts));
+		res = check_part[i](state, bdev);
+		if (!res)
+			continue;
+		if (res < 0) {
+			if (warn_no_part)
 				printk(" unable to read partition table\n");
 			goto setup_devfs;
 		}
+		for (j = 1; j < state->limit; j++) {
+			hd->part[j + minor(dev)].start_sect =
+				state->parts[j].from;
+			hd->part[j + minor(dev)].nr_sects =
+				state->parts[j].size;
+#if CONFIG_BLK_DEV_MD
+			if (!state->parts[j].flags)
+				continue;
+			md_autodetect_dev(mk_kdev(major(dev),minor(dev)+j));
+#endif
+		}
+		goto setup_devfs;
 	}
 
 	printk(" unknown partition table\n");
 setup_devfs:
-	invalidate_bdev(bdev, 1);
-	truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
-	bdput(bdev);
-	i = first_part_minor - 1;
-
+	blkdev_put(bdev, BDEV_RAW);
+out:
 	/* Setup driverfs tree */
 	if (hd->sizes)
-		driverfs_create_partitions(hd, i);
+		driverfs_create_partitions(hd, minor(dev));
 	else
-		driverfs_remove_partitions(hd, i);
+		driverfs_remove_partitions(hd, minor(dev));
 
-	devfs_register_partitions (hd, i, hd->sizes ? 0 : 1);
+	devfs_register_partitions (hd, minor(dev), hd->sizes ? 0 : 1);
 }
 
 #ifdef CONFIG_DEVFS_FS
@@ -564,7 +556,7 @@
 	if (!size)
 		return;
 
-	check_partition(g, mk_kdev(g->major, first_minor), 1 + first_minor);
+	check_partition(g, mk_kdev(g->major, first_minor));
 
  	/*
  	 * We need to set the sizes array before we will be able to access
@@ -630,30 +622,5 @@
 		g->part[minor].start_sect = 0;
 		g->part[minor].nr_sects = 0;
 	}
-	return 0;
-}
-
-/*
- * Make sure that a proposed subpartition is strictly contained inside
- * the parent partition.  If all is well, call add_gd_partition().
- */
-int
-check_and_add_subpartition(struct gendisk *hd, int super_minor, int minor,
-			   int sub_start, int sub_size)
-{
-	int start = hd->part[super_minor].start_sect;
-	int size = hd->part[super_minor].nr_sects;
-
-	if (start == sub_start && size == sub_size) {
-		/* full parent partition, we have it already */
-		return 0;
-	}
-
-	if (start <= sub_start && start+size >= sub_start+sub_size) {
-		add_gd_partition(hd, minor, sub_start, sub_size);
-		return 1;
-	}
-
-	printk("bad subpartition - ignored\n");
 	return 0;
 }
diff -Nru a/fs/partitions/check.h b/fs/partitions/check.h
--- a/fs/partitions/check.h	Wed Jul 24 14:03:37 2002
+++ b/fs/partitions/check.h	Wed Jul 24 14:03:37 2002
@@ -5,12 +5,28 @@
  * add_gd_partition adds a partitions details to the devices partition
  * description.
  */
-void add_gd_partition(struct gendisk *hd, int minor, int start, int size);
 
-/*
- * check_and_add_subpartition does the same for subpartitions
- */
-int check_and_add_subpartition(struct gendisk *hd, int super_minor,
-			       int minor, int sub_start, int sub_size);
+enum { MAX_PART = 256 };
+
+struct parsed_partitions {
+	char name[40];
+	struct {
+		unsigned long from;
+		unsigned long size;
+		int flags;
+	} parts[MAX_PART];
+	int next;
+	int limit;
+};
+
+static inline void
+put_partition(struct parsed_partitions *p, int n, int from, int size)
+{
+	if (n < p->limit) {
+		p->parts[n].from = from;
+		p->parts[n].size = size;
+		printk(" %s%d", p->name, n);
+	}
+}
 
 extern int warn_no_part;
diff -Nru a/fs/partitions/efi.c b/fs/partitions/efi.c
--- a/fs/partitions/efi.c	Wed Jul 24 14:03:35 2002
+++ b/fs/partitions/efi.c	Wed Jul 24 14:03:35 2002
@@ -87,26 +87,10 @@
  *
  ************************************************************/
 #include <linux/config.h>
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/blk.h>
-#include <linux/blkpg.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
 #include <linux/crc32.h>
-#include <asm/system.h>
-#include <asm/byteorder.h>
 #include "check.h"
 #include "efi.h"
 
-#if CONFIG_BLK_DEV_MD
-extern void md_autodetect_dev(kdev_t dev);
-#endif
-
 /* Handle printing of 64-bit values */
 /* Borrowed from /usr/include/inttypes.h */
 # if BITS_PER_LONG == 64 
@@ -184,7 +168,6 @@
 
 /**
  * last_lba(): return number of last logical block of device
- * @hd: gendisk with partition list
  * @bdev: block device
  * 
  * Description: Returns last LBA value on success, 0 on error.
@@ -193,16 +176,13 @@
  *  physical sectors available on the disk.
  */
 static u64
-last_lba(struct gendisk *hd, struct block_device *bdev)
+last_lba(struct block_device *bdev)
 {
-	if (!hd || !hd->part || !bdev)
-		return 0;
-	return hd->part[minor(to_kdev_t(bdev->bd_dev))].nr_sects - 1;
+	return (bdev->bd_inode->i_size >> 9) - 1;
 }
 
 /**
  * read_lba(): Read bytes from disk, starting at given LBA
- * @hd
  * @bdev
  * @lba
  * @buffer
@@ -212,39 +192,26 @@
  * Returns number of bytes read on success, 0 on error.
  */
 static size_t
-read_lba(struct gendisk *hd, struct block_device *bdev, u64 lba,
-	 u8 * buffer, size_t count)
+read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
 {
+	size_t totalreadcount = 0;
 
-	size_t totalreadcount = 0, bytesread = 0;
-	unsigned long blocksize;
-	int i;
-	Sector sect;
-	unsigned char *data = NULL;
-
-	if (!hd || !bdev || !buffer || !count)
+	if (!bdev || !buffer)
 		return 0;
 
-	blocksize = bdev_hardsect_size(bdev);
-	if (!blocksize)
-		blocksize = 512;
-
-	for (i = 0; count > 0; i++) {
-		data = read_dev_sector(bdev, lba, &sect);
+	while (count) {
+		int copied = 512;
+		Sector sect;
+		unsigned char *data = read_dev_sector(bdev, lba++, &sect);
 		if (!data)
-			return totalreadcount;
-
-		bytesread =
-		    PAGE_CACHE_SIZE - (data -
-				       (unsigned char *) page_address(sect.v));
-		bytesread = min(bytesread, count);
-		memcpy(buffer, data, bytesread);
+			break;
+		if (copied > count)
+			copied = count;
+		memcpy(buffer, data, copied);
 		put_dev_sector(sect);
-
-		buffer += bytesread;
-		totalreadcount += bytesread;
-		count -= bytesread;
-		lba += (bytesread / blocksize);
+		buffer += copied;
+		totalreadcount +=copied;
+		count -= copied;
 	}
 	return totalreadcount;
 }
@@ -252,7 +219,6 @@
 
 /**
  * alloc_read_gpt_entries(): reads partition entries from disk
- * @hd
  * @bdev
  * @gpt - GPT header
  * 
@@ -261,12 +227,11 @@
  * Notes: remember to free pte when you're done!
  */
 static gpt_entry *
-alloc_read_gpt_entries(struct gendisk *hd,
-		       struct block_device *bdev, gpt_header *gpt)
+alloc_read_gpt_entries(struct block_device *bdev, gpt_header *gpt)
 {
 	size_t count;
 	gpt_entry *pte;
-	if (!hd || !bdev || !gpt)
+	if (!bdev || !gpt)
 		return NULL;
 
 	count = le32_to_cpu(gpt->num_partition_entries) *
@@ -278,7 +243,7 @@
 		return NULL;
 	memset(pte, 0, count);
 
-	if (read_lba(hd, bdev, le64_to_cpu(gpt->partition_entry_lba),
+	if (read_lba(bdev, le64_to_cpu(gpt->partition_entry_lba),
                      (u8 *) pte,
 		     count) < count) {
 		kfree(pte);
@@ -290,7 +255,6 @@
 
 /**
  * alloc_read_gpt_header(): Allocates GPT header, reads into it from disk
- * @hd
  * @bdev
  * @lba is the Logical Block Address of the partition table
  * 
@@ -299,10 +263,10 @@
  * Note: remember to free gpt when finished with it.
  */
 static gpt_header *
-alloc_read_gpt_header(struct gendisk *hd, struct block_device *bdev, u64 lba)
+alloc_read_gpt_header(struct block_device *bdev, u64 lba)
 {
 	gpt_header *gpt;
-	if (!hd || !bdev)
+	if (!bdev)
 		return NULL;
 
 	gpt = kmalloc(sizeof (gpt_header), GFP_KERNEL);
@@ -310,7 +274,7 @@
 		return NULL;
 	memset(gpt, 0, sizeof (gpt_header));
 
-	if (read_lba(hd, bdev, lba, (u8 *) gpt,
+	if (read_lba(bdev, lba, (u8 *) gpt,
 		     sizeof (gpt_header)) < sizeof (gpt_header)) {
 		kfree(gpt);
                 gpt=NULL;
@@ -322,7 +286,6 @@
 
 /**
  * is_gpt_valid() - tests one GPT header and PTEs for validity
- * @hd
  * @bdev
  * @lba is the logical block address of the GPT header to test
  * @gpt is a GPT header ptr, filled on return.
@@ -332,14 +295,14 @@
  * If valid, returns pointers to newly allocated GPT header and PTEs.
  */
 static int
-is_gpt_valid(struct gendisk *hd, struct block_device *bdev, u64 lba,
+is_gpt_valid(struct block_device *bdev, u64 lba,
 	     gpt_header **gpt, gpt_entry **ptes)
 {
 	u32 crc, origcrc;
 
-	if (!hd || !bdev || !gpt || !ptes)
+	if (!bdev || !gpt || !ptes)
 		return 0;
-	if (!(*gpt = alloc_read_gpt_header(hd, bdev, lba)))
+	if (!(*gpt = alloc_read_gpt_header(bdev, lba)))
 		return 0;
 
 	/* Check the GUID Partition Table signature */
@@ -377,7 +340,7 @@
 		return 0;
 	}
 
-	if (!(*ptes = alloc_read_gpt_entries(hd, bdev, *gpt))) {
+	if (!(*ptes = alloc_read_gpt_entries(bdev, *gpt))) {
 		kfree(*gpt);
 		*gpt = NULL;
 		return 0;
@@ -502,7 +465,6 @@
 
 /**
  * find_valid_gpt() - Search disk for valid GPT headers and PTEs
- * @hd
  * @bdev
  * @gpt is a GPT header ptr, filled on return.
  * @ptes is a PTEs ptr, filled on return.
@@ -512,31 +474,30 @@
  * or the Alternate GPT header and PTEs valid, and the PMBR valid.
  */
 static int
-find_valid_gpt(struct gendisk *hd, struct block_device *bdev,
-	       gpt_header **gpt, gpt_entry **ptes)
+find_valid_gpt(struct block_device *bdev, gpt_header **gpt, gpt_entry **ptes)
 {
 	int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
 	gpt_header *pgpt = NULL, *agpt = NULL;
 	gpt_entry *pptes = NULL, *aptes = NULL;
 	legacy_mbr *legacymbr = NULL;
 	u64 lastlba;
-	if (!hd || !bdev || !gpt || !ptes)
+	if (!bdev || !gpt || !ptes)
 		return 0;
 
-	lastlba = last_lba(hd, bdev);
-	good_pgpt = is_gpt_valid(hd, bdev, GPT_PRIMARY_PARTITION_TABLE_LBA,
+	lastlba = last_lba(bdev);
+	good_pgpt = is_gpt_valid(bdev, GPT_PRIMARY_PARTITION_TABLE_LBA,
 				 &pgpt, &pptes);
         if (good_pgpt) {
-		good_agpt = is_gpt_valid(hd, bdev,
+		good_agpt = is_gpt_valid(bdev,
                                          le64_to_cpu(pgpt->alternate_lba),
 					 &agpt, &aptes);
                 if (!good_agpt) {
-                        good_agpt = is_gpt_valid(hd, bdev, lastlba,
+                        good_agpt = is_gpt_valid(bdev, lastlba,
                                                  &agpt, &aptes);
                 }
         }
         else {
-                good_agpt = is_gpt_valid(hd, bdev, lastlba,
+                good_agpt = is_gpt_valid(bdev, lastlba,
                                          &agpt, &aptes);
         }
 
@@ -549,7 +510,7 @@
         legacymbr = kmalloc(sizeof (*legacymbr), GFP_KERNEL);
         if (legacymbr) {
                 memset(legacymbr, 0, sizeof (*legacymbr));
-                read_lba(hd, bdev, 0, (u8 *) legacymbr,
+                read_lba(bdev, 0, (u8 *) legacymbr,
                          sizeof (*legacymbr));
                 good_pmbr = is_pmbr_valid(legacymbr);
                 kfree(legacymbr);
@@ -616,12 +577,16 @@
 }
 
 /**
- * add_gpt_partitions(struct gendisk *hd, struct block_device *bdev,
- * @hd
+ * efi_partition(struct parsed_partitions *state, struct block_device *bdev)
+ * @state
  * @bdev
  *
- * Description: Create devices for each entry in the GUID Partition Table
- * Entries.
+ * Description: called from check.c, if the disk contains GPT
+ * partitions, sets up partition entries in the kernel.
+ *
+ * If the first block on the disk is a legacy MBR,
+ * it will get handled by msdos_partition().
+ * If it's a Protective MBR, we'll handle it here.
  *
  * We do not create a Linux partition for GPT, but
  * only for the actual data partitions.
@@ -631,104 +596,39 @@
  *  1 if successful
  *
  */
-static int
-add_gpt_partitions(struct gendisk *hd, struct block_device *bdev, int nextminor)
+int
+efi_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	gpt_header *gpt = NULL;
 	gpt_entry *ptes = NULL;
 	u32 i;
-	int max_p; 
-
-	if (!hd || !bdev)
-		return -1;
 
-	if (!find_valid_gpt(hd, bdev, &gpt, &ptes) || !gpt || !ptes) {
-		if (gpt) {
-			kfree(gpt);
-                        gpt = NULL;
-                }
-		if (ptes) {
-			kfree(ptes);
-                        ptes = NULL;
-                }
+	if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) {
+		kfree(gpt);
+		kfree(ptes);
 		return 0;
 	}
 
 	Dprintk("GUID Partition Table is valid!  Yea!\n");
 
-	max_p = (1 << hd->minor_shift) - 1;
-	for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < max_p; i++) {
+	for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) {
 		if (!efi_guidcmp(ptes[i].partition_type_guid, NULL_GUID))
 			continue;
 
-		add_gd_partition(hd, nextminor+i,
-                                 le64_to_cpu(ptes[i].starting_lba),
+		put_partition(state, i+1, le64_to_cpu(ptes[i].starting_lba),
 				 (le64_to_cpu(ptes[i].ending_lba) -
                                   le64_to_cpu(ptes[i].starting_lba) +
 				  1));
 
 		/* If there's this is a RAID volume, tell md */
-#if CONFIG_BLK_DEV_MD
 		if (!efi_guidcmp(ptes[i].partition_type_guid,
-                                 PARTITION_LINUX_RAID_GUID)) {
-			md_autodetect_dev(mk_kdev(hd->major,
-                                                  nextminor));
-		}
-#endif
+				 PARTITION_LINUX_RAID_GUID))
+			state->parts[i+1].flags = 1;
 	}
 	kfree(ptes);
-        ptes=NULL;
 	kfree(gpt);
-        gpt=NULL;
 	printk("\n");
 	return 1;
-}
-
-/**
- * efi_partition(): EFI GPT partition handling entry function
- * @hd
- * @bdev
- * @first_sector: unused
- * @first_part_minor: minor number assigned to first GPT partition found
- *
- * Description: called from check.c, if the disk contains GPT
- * partitions, sets up partition entries in the kernel.
- *
- * If the first block on the disk is a legacy MBR,
- * it will get handled by msdos_partition().
- * If it's a Protective MBR, we'll handle it here.
- *
- * set_blocksize() calls are necessary to be able to read
- * a disk with an odd number of 512-byte sectors, as the
- * default BLOCK_SIZE of 1024 bytes won't let that last
- * sector be read otherwise.
- *
- * Returns:
- * -1 if unable to read the partition table
- *  0 if this isn't our partitoin table
- *  1 if successful
- */
-int
-efi_partition(struct gendisk *hd, struct block_device *bdev,
-	      unsigned long first_sector, int first_part_minor)
-{
-
-	int hardblocksize = bdev_hardsect_size(bdev);
-	int orig_blksize_size = block_size(bdev);
-	int rc = 0;
-
-	/* Need to change the block size that the block layer uses */
-
-	if (orig_blksize_size != hardblocksize)
-		set_blocksize(bdev, hardblocksize);
-
-	rc = add_gpt_partitions(hd, bdev, first_part_minor);
-
-	/* change back */
-	if (orig_blksize_size != hardblocksize)
-		set_blocksize(bdev, orig_blksize_size);
-
-	return rc;
 }
 
 /*
diff -Nru a/fs/partitions/efi.h b/fs/partitions/efi.h
--- a/fs/partitions/efi.h	Wed Jul 24 14:03:36 2002
+++ b/fs/partitions/efi.h	Wed Jul 24 14:03:36 2002
@@ -112,9 +112,7 @@
 } __attribute__ ((packed)) legacy_mbr;
 
 /* Functions */
-extern int
- efi_partition(struct gendisk *hd, struct block_device *bdev,
-	      unsigned long first_sector, int first_part_minor);
+extern int efi_partition(struct parsed_partitions *state, struct block_device *bdev);
 
 #endif
 
diff -Nru a/fs/partitions/ibm.c b/fs/partitions/ibm.c
--- a/fs/partitions/ibm.c	Wed Jul 24 14:03:39 2002
+++ b/fs/partitions/ibm.c	Wed Jul 24 14:03:39 2002
@@ -88,8 +88,7 @@
 /*
  */
 int 
-ibm_partition(struct gendisk *hd, struct block_device *bdev,
-	      unsigned long first_sector, int first_part_minor)
+ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	int blocksize, offset, size;
 	dasd_information_t *info;
@@ -100,9 +99,6 @@
 	unsigned char *data;
 	Sector sect;
 
-	if ( first_sector != 0 )
-		BUG();
-
 	if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL)
 		goto out_noinfo;
 	if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
@@ -155,9 +151,7 @@
 			offset = (info->label_block + 1);
 			size = bdev->bd_inode->i_size >> 9;
 		}
-		// add_gd_partition(hd, first_part_minor - 1, 0, size);
-		add_gd_partition(hd, first_part_minor,
-				 offset*(blocksize >> 9),
+		put_partition(state, 1, offset*(blocksize >> 9),
 				 size-offset*(blocksize >> 9));
 	} else if (strncmp(type, "VOL1", 4) == 0) {
 		/*
@@ -194,9 +188,9 @@
 		        offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
 			size  = cchh2blk(&f1.DS1EXT1.ulimit, geo) - 
 				offset + geo->sectors;
-			if (counter >= (1 << hd->minor_shift))
+			if (counter >= state->limit)
 				break;
-			add_gd_partition(hd, first_part_minor + counter, 
+			put_partition(state, counter + 1, 
 					 offset * (blocksize >> 9),
 					 size * (blocksize >> 9));
 			counter++;
@@ -212,9 +206,7 @@
 			printk("(nonl)/%8s:", name);
 		offset = (info->label_block + 1);
 		size = (bdev->bd_inode->i_size >> 9);
-		// add_gd_partition(hd, first_part_minor - 1, 0, size);
-		add_gd_partition(hd, first_part_minor,
-				 offset*(blocksize >> 9),
+		put_partition(state, 1, offset*(blocksize >> 9),
 				 size-offset*(blocksize >> 9));
 	}
 
diff -Nru a/fs/partitions/ibm.h b/fs/partitions/ibm.h
--- a/fs/partitions/ibm.h	Wed Jul 24 14:03:35 2002
+++ b/fs/partitions/ibm.h	Wed Jul 24 14:03:35 2002
@@ -1 +1 @@
-int ibm_partition(struct gendisk *, struct block_device *, unsigned long, int);
+int ibm_partition(struct parsed_partitions *, struct block_device *);
diff -Nru a/fs/partitions/ldm.c b/fs/partitions/ldm.c
--- a/fs/partitions/ldm.c	Wed Jul 24 14:03:37 2002
+++ b/fs/partitions/ldm.c	Wed Jul 24 14:03:37 2002
@@ -23,12 +23,6 @@
  *
  * 28/10/2001 - Added sorting of ldm partitions. (AIA)
  */
-#include <linux/types.h>
-#include <asm/unaligned.h>
-#include <asm/byteorder.h>
-#include <linux/pagemap.h>
-#include <linux/genhd.h>
-#include <linux/blkdev.h>
 #include <linux/slab.h>
 #include "check.h"
 #include "ldm.h"
@@ -57,7 +51,6 @@
 #endif	/* !CONFIG_LDM_DEBUG */
 
 /* Necessary forward declarations. */
-static int create_partition(struct gendisk *, int, int, int);
 static int parse_privhead(const u8 *, struct privhead *);
 static u64 get_vnum(const u8 *, int *);
 static int get_vstr(const u8 *, u8 *, const int);
@@ -161,8 +154,7 @@
 /**
  * add_partition_to_list - insert partition into a partition list
  * @pl:		sorted list of partitions
- * @hd:		gendisk structure to which the data partition belongs
- * @disk_minor:	minor number of the disk device
+ * @disk_size:	number of sectors on the disk device
  * @start:	first sector within the disk device
  * @size:	number of sectors on the partition device
  *
@@ -174,16 +166,15 @@
  *
  * TODO: Add sanity check for overlapping partitions. (AIA)
  */ 
-static int add_partition_to_list(struct list_head *pl, const struct gendisk *hd,
-		const int disk_minor, const unsigned long start,
+static int add_partition_to_list(struct list_head *pl,
+		const unsigned long disk_size,
+		const unsigned long start,
 		const unsigned long size)
 {
 	struct ldm_part *lp, *lptmp;
 	struct list_head *tmp;
 
-	if (!hd->part)
-		return -1;
-	if ((start < 1) || ((start + size) > hd->part[disk_minor].nr_sects)) {
+	if (start < 1 || start + size > disk_size) {
 		printk(LDM_CRIT "LDM partition exceeds physical disk. "
 				"Skipping.\n");
 		return -1;
@@ -215,7 +206,6 @@
 /**
  * create_data_partitions - create the data partition devices
  * @hd:			gendisk structure in which to create the data partitions
- * @first_sector:	first sector within the disk device
  * @first_part_minor:	first minor number of data partition devices
  * @dev:		partition device holding the LDM database
  * @vm:			in memory vmdb structure of @dev
@@ -234,9 +224,8 @@
  *
  * Return 1 on success and -1 on error.
  */
-static int create_data_partitions(struct gendisk *hd,
-		const unsigned long first_sector, int first_part_minor,
-		struct block_device *bdev, const struct vmdb *vm,
+static int create_data_partitions(struct parsed_partitions *state,
+		int slot, struct block_device *bdev, const struct vmdb *vm,
 		const struct privhead *ph, const struct ldmdisk *dk,
 		unsigned long base)
 {
@@ -249,7 +238,7 @@
 	int vblk;
 	int vsize;		/* VBLK size. */
 	int perbuf;		/* VBLKs per buffer. */
-	int buffer, lastbuf, lastofs, err, disk_minor;
+	int buffer, lastbuf, lastofs, err;
 
 	vb = (struct vblk*)kmalloc(sizeof(struct vblk), GFP_KERNEL);
 	if (!vb)
@@ -268,11 +257,6 @@
 	if (OFF_VBLK * LDM_BLOCKSIZE + vm->last_vblk_seq * vsize >
 			ph->config_size * 512)
 		goto err_out;
-	/*
-	 * Get the minor number of the parent device so we can check we don't
-	 * go beyond the end of the device.
-	 */
-	disk_minor = (first_part_minor >> hd->minor_shift) << hd->minor_shift;
 	for (buffer = 0; buffer < lastbuf; buffer++) {
 		data = read_dev_sector(bdev, base + 2*OFF_VBLK + buffer, &sect);
 		if (!data)
@@ -292,8 +276,9 @@
 			if (dk->obj_id != vb->disk_id)
 				continue;
 			/* Ignore invalid partition errors. */
-			if (add_partition_to_list(&pl, hd, disk_minor,
-					first_sector + vb->start_sector +
+			if (add_partition_to_list(&pl,
+					bdev->bd_inode->i_size>>9,
+					vb->start_sector +
 					ph->logical_disk_start,
 					vb->num_sectors) < -1)
 				goto brelse_out;
@@ -306,7 +291,7 @@
 	printk(" <");
 	list_for_each(tmp, &pl) {
 		lp = list_entry(tmp, struct ldm_part, part_list);
-		add_gd_partition(hd, first_part_minor++, lp->start, lp->size);
+		put_partition(state, slot++, lp->start, lp->size);
 	}
 	printk(" >\n");
 	if (!list_empty(&pl)) {
@@ -820,42 +805,6 @@
 }
 
 /**
- * create_partition - validate input and create a kernel partition device
- * @hd:		gendisk structure in which to create partition
- * @minor:	minor number for device to create
- * @start:	starting offset of the partition into the parent device
- * @size:	size of the partition
- *
- * This validates the range, then puts an entry into the kernel's partition
- * table.
- *
- * @start and @size are numbers of sectors.
- *
- * Return 1 on succes and -1 on error.
- */
-static int create_partition(struct gendisk *hd, const int minor,
-		const int start, const int size)
-{
-	int disk_minor;
-
-	if (!hd->part)
-		return -1;
-	/*
-	 * Get the minor number of the parent device so we can check we don't
-	 * go beyond the end of the device.
-	 */
-	disk_minor = (minor >> hd->minor_shift) << hd->minor_shift;
-	if ((start < 1) || ((start + size) > hd->part[disk_minor].nr_sects)) {
-		printk(LDM_CRIT "LDM Partition exceeds physical disk. "
-				"Aborting.\n");
-		return -1;
-	}
-	add_gd_partition(hd, minor, start, size);
-	ldm_debug("Created partition successfully.\n");
-	return 1;
-}
-
-/**
  * parse_privhead - parse the LDM database PRIVHEAD structure
  * @buffer:	LDM database privhead structure loaded from the device
  * @ph:		in memory privhead structure to return parsed information in
@@ -901,19 +850,16 @@
 }
 
 /**
- * create_db_partition - create a dedicated partition for our database
- * @hd:		gendisk structure in which to create partition
+ * find_db_partition - find our database
  * @dev:	device of which to create partition
  * @ph:		@dev's LDM database private header
  *
- * Find the primary private header, locate the LDM database, then create a
+ * Find the primary private header and the LDM database
  * partition to wrap it.
  *
  * Return 1 on succes, 0 if device is not a dynamic disk and -1 on error.
  */
-static int create_db_partition(struct gendisk *hd, struct block_device *bdev,
-		const unsigned long first_sector, const int first_part_minor,
-		struct privhead *ph)
+static int find_db_partition(struct block_device *bdev, struct privhead *ph)
 {
 	Sector sect;
 	unsigned char *data;
@@ -930,10 +876,15 @@
 		return 0;
 	}
 	err = parse_privhead(data, ph);
-	if (err == 1)
-		err = create_partition(hd, first_part_minor, first_sector +
-				ph->config_start, ph->config_size);
 	put_dev_sector(sect);
+	if (err <= 0)
+		return err;
+	if (ph->config_start < 1 ||
+	    ph->config_start + ph->config_size > bdev->bd_inode->i_size >> 9) {
+		printk(LDM_CRIT "LDM Partition exceeds physical disk. "
+				"Aborting.\n");
+		err = -1;
+	}
 	return err;
 }
 
@@ -990,8 +941,6 @@
  * ldm_partition - find out whether a device is a dynamic disk and handle it
  * @hd:			gendisk structure in which to return the handled disk
  * @dev:		device we need to look at
- * @first_sector:	first sector within the device
- * @first_part_minor:	first minor number of partitions for the device
  *
  * Description:
  *
@@ -1010,8 +959,7 @@
  *	 0 if @dev is not a dynamic disk,
  *	-1 if an error occured.
  */
-int ldm_partition(struct gendisk *hd, struct block_device *bdev,
-		unsigned long first_sector, int first_part_minor)
+int ldm_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	struct privhead *ph  = NULL;
 	struct tocblock *toc = NULL;
@@ -1020,8 +968,6 @@
 	unsigned long db_first;
 	int err;
 
-	if (!hd)
-		return 0;
 	/* Check the partition table. */
 	err = validate_partition_table(bdev);
 	if (err != 1)
@@ -1029,10 +975,11 @@
 	if (!(ph = (struct privhead*)kmalloc(sizeof(*ph), GFP_KERNEL)))
 		goto no_mem;
 	/* Create the LDM database device. */
-	err = create_db_partition(hd, bdev, first_sector, first_part_minor, ph);
+	err = find_db_partition(bdev, ph);
 	if (err != 1)
 		goto out;
-	db_first = hd->part[first_part_minor].start_sect;
+	db_first = ph->config_start;
+	put_partition(state, 1, db_first, ph->config_size);
 	/* Check the backup privheads. */
 	err = validate_privheads(bdev, ph, db_first);
 	if (err != 1)
@@ -1056,8 +1003,8 @@
 	if (err != 1)
 		goto out;
 	/* Finally, create the data partition devices. */
-	err = create_data_partitions(hd, first_sector, first_part_minor +
-			LDM_FIRST_PART_OFFSET, bdev, vm, ph, dk, db_first);
+	err = create_data_partitions(state, 1 + LDM_FIRST_PART_OFFSET,
+					bdev, vm, ph, dk, db_first);
 	if (err == 1)
 		ldm_debug("Parsed LDM database successfully.\n");
 out:
@@ -1071,4 +1018,3 @@
 	err = -1;
 	goto out;
 }
-
diff -Nru a/fs/partitions/ldm.h b/fs/partitions/ldm.h
--- a/fs/partitions/ldm.h	Wed Jul 24 14:03:37 2002
+++ b/fs/partitions/ldm.h	Wed Jul 24 14:03:37 2002
@@ -150,8 +150,7 @@
 	unsigned long size;
 };
 
-int ldm_partition(struct gendisk *hd, struct block_device *bdev,
-		unsigned long first_sector, int first_part_minor);
+int ldm_partition(struct parsed_partitions *state, struct block_device *bdev);
 
 #endif /* _FS_PT_LDM_H_ */
 
diff -Nru a/fs/partitions/mac.c b/fs/partitions/mac.c
--- a/fs/partitions/mac.c	Wed Jul 24 14:03:36 2002
+++ b/fs/partitions/mac.c	Wed Jul 24 14:03:36 2002
@@ -7,16 +7,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/blk.h>
 #include <linux/ctype.h>
-
-#include <asm/system.h>
-
 #include "check.h"
 #include "mac.h"
 
@@ -36,9 +27,9 @@
 		stg[i] = 0;
 }
 
-int mac_partition(struct gendisk *hd, struct block_device *bdev,
-		unsigned long fsec, int first_part_minor)
+int mac_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
+	int slot = 1;
 	Sector sect;
 	unsigned char *data;
 	int blk, blocks_in_map;
@@ -79,8 +70,8 @@
 		part = (struct mac_partition *) (data + pos%512);
 		if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
 			break;
-		add_gd_partition(hd, first_part_minor,
-			fsec + be32_to_cpu(part->start_block) * (secsize/512),
+		put_partition(state, slot,
+			be32_to_cpu(part->start_block) * (secsize/512),
 			be32_to_cpu(part->block_count) * (secsize/512));
 
 #ifdef CONFIG_ALL_PPC
@@ -126,7 +117,7 @@
 		}
 #endif /* CONFIG_ALL_PPC */
 
-		++first_part_minor;
+		++slot;
 	}
 #ifdef CONFIG_ALL_PPC
 	if (found_root_goodness)
@@ -138,4 +129,3 @@
 	printk("\n");
 	return 1;
 }
-
diff -Nru a/fs/partitions/mac.h b/fs/partitions/mac.h
--- a/fs/partitions/mac.h	Wed Jul 24 14:03:39 2002
+++ b/fs/partitions/mac.h	Wed Jul 24 14:03:39 2002
@@ -41,4 +41,4 @@
     /* ... more stuff */
 };
 
-int mac_partition(struct gendisk *hd, struct block_device *bdev, unsigned long fsec, int first_part_minor);
+int mac_partition(struct parsed_partitions *state, struct block_device *bdev);
diff -Nru a/fs/partitions/msdos.c b/fs/partitions/msdos.c
--- a/fs/partitions/msdos.c	Wed Jul 24 14:03:35 2002
+++ b/fs/partitions/msdos.c	Wed Jul 24 14:03:35 2002
@@ -20,12 +20,6 @@
  */
 
 #include <linux/config.h>
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/blk.h>
 #include <linux/buffer_head.h>		/* for invalidate_bdev() */
 
 #ifdef CONFIG_BLK_DEV_IDE
@@ -38,16 +32,10 @@
 #define ide_xlate_1024 ide_xlate_1024_hook
 #endif
 
-#include <asm/system.h>
-
 #include "check.h"
 #include "msdos.h"
 #include "efi.h"
 
-#if CONFIG_BLK_DEV_MD
-extern void md_autodetect_dev(kdev_t dev);
-#endif
-
 /*
  * Many architectures don't like unaligned accesses, which is
  * frequently the case with the nr_sects and start_sect partition
@@ -73,23 +61,6 @@
 		SYS_IND(p) == LINUX_EXTENDED_PARTITION);
 }
 
-/*
- * partition_name() formats the short partition name into the supplied
- * buffer, and returns a pointer to that buffer.
- * Used by several partition types which makes conditional inclusion messy,
- * use __attribute__ ((unused)) instead.
- */
-static char __attribute__ ((unused))
-	*partition_name (struct gendisk *hd, int minor, char *buf)
-{
-#ifdef CONFIG_DEVFS_FS
-	sprintf(buf, "p%d", (minor & ((1 << hd->minor_shift) - 1)));
-	return buf;
-#else
-	return disk_name(hd, minor, buf);
-#endif
-}
-
 #define MSDOS_LABEL_MAGIC1	0x55
 #define MSDOS_LABEL_MAGIC2	0xAA
 
@@ -110,26 +81,26 @@
  * only for the actual data partitions.
  */
 
-static void extended_partition(struct gendisk *hd, struct block_device *bdev,
-			int minor, unsigned long first_size, int *current_minor)
+static void
+parse_extended(struct parsed_partitions *state, struct block_device *bdev,
+			u32 first_sector, u32 first_size)
 {
 	struct partition *p;
 	Sector sect;
 	unsigned char *data;
-	unsigned long first_sector, this_sector, this_size;
-	int mask = (1 << hd->minor_shift) - 1;
+	u32 this_sector, this_size;
 	int sector_size = bdev_hardsect_size(bdev) / 512;
 	int loopct = 0;		/* number of links followed
 				   without finding a data partition */
 	int i;
 
-	this_sector = first_sector = hd->part[minor].start_sect;
+	this_sector = first_sector;
 	this_size = first_size;
 
 	while (1) {
 		if (++loopct > 100)
 			return;
-		if ((*current_minor & mask) == 0)
+		if (state->next == state->limit)
 			return;
 		data = read_dev_sector(bdev, this_sector, &sect);
 		if (!data)
@@ -153,7 +124,7 @@
 		 * First process the data partition(s)
 		 */
 		for (i=0; i<4; i++, p++) {
-			unsigned long offs, size, next;
+			u32 offs, size, next;
 			if (!NR_SECTS(p) || is_extended_partition(p))
 				continue;
 
@@ -171,27 +142,19 @@
 					continue;
 			}
 
-			add_gd_partition(hd, *current_minor, next, size);
-#if CONFIG_BLK_DEV_MD
-			if (SYS_IND(p) == LINUX_RAID_PARTITION) {
-			    md_autodetect_dev(mk_kdev(hd->major,*current_minor));
-			}
-#endif
-
-			(*current_minor)++;
+			put_partition(state, state->next, next, size);
+			if (SYS_IND(p) == LINUX_RAID_PARTITION)
+				state->parts[state->next].flags = 1;
 			loopct = 0;
-			if ((*current_minor & mask) == 0)
+			if (++state->next == state->limit)
 				goto done;
 		}
 		/*
 		 * Next, process the (first) extended partition, if present.
 		 * (So far, there seems to be no reason to make
-		 *  extended_partition()  recursive and allow a tree
+		 *  parse_extended()  recursive and allow a tree
 		 *  of extended partitions.)
 		 * It should be a link to the next logical partition.
-		 * Create a minor for this just long enough to get the next
-		 * partition table.  The minor will be reused for the next
-		 * data partition.
 		 */
 		p -= 4;
 		for (i=0; i<4; i++, p++)
@@ -202,7 +165,6 @@
 
 		this_sector = first_sector + START_SECT(p) * sector_size;
 		this_size = NR_SECTS(p) * sector_size;
-		minor = *current_minor;
 		put_dev_sector(sect);
 	}
 done:
@@ -213,18 +175,13 @@
    indicates linux swap.  Be careful before believing this is Solaris. */
 
 static void
-solaris_x86_partition(struct gendisk *hd, struct block_device *bdev,
-		int minor, int *current_minor)
+parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
+			u32 offset, u32 size, int origin)
 {
-
 #ifdef CONFIG_SOLARIS_X86_PARTITION
-	long offset = hd->part[minor].start_sect;
 	Sector sect;
 	struct solaris_x86_vtoc *v;
-	struct solaris_x86_slice *s;
-	int mask = (1 << hd->minor_shift) - 1;
 	int i;
-	char buf[40];
 
 	v = (struct solaris_x86_vtoc *)read_dev_sector(bdev, offset+1, &sect);
 	if (!v)
@@ -233,29 +190,23 @@
 		put_dev_sector(sect);
 		return;
 	}
-	printk(" %s: <solaris:", partition_name(hd, minor, buf));
+	printk(" %s%d: <solaris:", state->name, origin);
 	if (le32_to_cpu(v->v_version) != 1) {
 		printk("  cannot handle version %d vtoc>\n",
 			le32_to_cpu(v->v_version));
 		put_dev_sector(sect);
 		return;
 	}
-	for (i=0; i<SOLARIS_X86_NUMSLICE; i++) {
-		if ((*current_minor & mask) == 0)
-			break;
-		s = &v->v_slice[i];
-
+	for (i=0; i<SOLARIS_X86_NUMSLICE && state->next<state->limit; i++) {
+		struct solaris_x86_slice *s = &v->v_slice[i];
 		if (s->s_size == 0)
 			continue;
 		printk(" [s%d]", i);
 		/* solaris partitions are relative to current MS-DOS
-		 * one but add_gd_partition starts relative to sector
-		 * zero of the disk.  Therefore, must add the offset
-		 * of the current partition */
-		add_gd_partition(hd, *current_minor,
+		 * one; must add the offset of the current partition */
+		put_partition(state, state->next++,
 				 le32_to_cpu(s->s_start)+offset,
 				 le32_to_cpu(s->s_size));
-		(*current_minor)++;
 	}
 	put_dev_sector(sect);
 	printk(" >\n");
@@ -265,17 +216,16 @@
 #ifdef CONFIG_BSD_DISKLABEL
 /* 
  * Create devices for BSD partitions listed in a disklabel, under a
- * dos-like partition. See extended_partition() for more information.
+ * dos-like partition. See parse_extended() for more information.
  */
-static void do_bsd_partition(struct gendisk *hd, struct block_device *bdev,
-	int minor, int *current_minor, char *name, int max_partitions)
+static void
+parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
+		u32 offset, u32 size, int origin, char *flavour,
+		int max_partitions)
 {
-	long offset = hd->part[minor].start_sect;
 	Sector sect;
 	struct bsd_disklabel *l;
 	struct bsd_partition *p;
-	int mask = (1 << hd->minor_shift) - 1;
-	char buf[40];
 
 	l = (struct bsd_disklabel *)read_dev_sector(bdev, offset+1, &sect);
 	if (!l)
@@ -284,69 +234,75 @@
 		put_dev_sector(sect);
 		return;
 	}
-	printk(" %s: <%s:", partition_name(hd, minor, buf), name);
+	printk(" %s%d: <%s:", state->name, origin, flavour);
 
 	if (le16_to_cpu(l->d_npartitions) < max_partitions)
 		max_partitions = le16_to_cpu(l->d_npartitions);
 	for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) {
-		int bsd_start, bsd_size;
+		u32 bsd_start, bsd_size;
 
-		if ((*current_minor & mask) == 0)
+		if (state->next == state->limit)
 			break;
 		if (p->p_fstype == BSD_FS_UNUSED) 
 			continue;
 		bsd_start = le32_to_cpu(p->p_offset);
 		bsd_size = le32_to_cpu(p->p_size);
-		if (check_and_add_subpartition(hd, minor, *current_minor,
-					       bsd_start, bsd_size))
-			(*current_minor)++;
+		if (offset == bsd_start && size == bsd_size)
+			/* full parent partition, we have it already */
+			continue;
+		if (offset > bsd_start || offset+size < bsd_start+bsd_size) {
+			printk("bad subpartition - ignored\n");
+			continue;
+		}
+		put_partition(state, state->next++, bsd_start, bsd_size);
 	}
 	put_dev_sector(sect);
 	printk(" >\n");
 }
 #endif
 
-static void bsd_partition(struct gendisk *hd, struct block_device *bdev,
-	int minor, int *current_minor)
+static void
+parse_freebsd(struct parsed_partitions *state, struct block_device *bdev,
+		u32 offset, u32 size, int origin)
 {
 #ifdef CONFIG_BSD_DISKLABEL
-	do_bsd_partition(hd, bdev, minor, current_minor, "bsd",
-		BSD_MAXPARTITIONS);
+	parse_bsd(state, bdev, offset, size, origin,
+			"bsd", BSD_MAXPARTITIONS);
 #endif
 }
 
-static void netbsd_partition(struct gendisk *hd, struct block_device *bdev,
-		int minor, int *current_minor)
+static void
+parse_netbsd(struct parsed_partitions *state, struct block_device *bdev,
+		u32 offset, u32 size, int origin)
 {
 #ifdef CONFIG_BSD_DISKLABEL
-	do_bsd_partition(hd, bdev, minor, current_minor, "netbsd",
-			BSD_MAXPARTITIONS);
+	parse_bsd(state, bdev, offset, size, origin,
+			"netbsd", BSD_MAXPARTITIONS);
 #endif
 }
 
-static void openbsd_partition(struct gendisk *hd, struct block_device *bdev,
-		int minor, int *current_minor)
+static void
+parse_openbsd(struct parsed_partitions *state, struct block_device *bdev,
+		u32 offset, u32 size, int origin)
 {
 #ifdef CONFIG_BSD_DISKLABEL
-	do_bsd_partition(hd, bdev, minor, current_minor,
+	parse_bsd(state, bdev, offset, size, origin,
 			"openbsd", OPENBSD_MAXPARTITIONS);
 #endif
 }
 
 /*
  * Create devices for Unixware partitions listed in a disklabel, under a
- * dos-like partition. See extended_partition() for more information.
+ * dos-like partition. See parse_extended() for more information.
  */
-static void unixware_partition(struct gendisk *hd, struct block_device *bdev,
-		int minor, int *current_minor)
+static void
+parse_unixware(struct parsed_partitions *state, struct block_device *bdev,
+		u32 offset, u32 size, int origin)
 {
 #ifdef CONFIG_UNIXWARE_DISKLABEL
-	long offset = hd->part[minor].start_sect;
 	Sector sect;
 	struct unixware_disklabel *l;
 	struct unixware_slice *p;
-	int mask = (1 << hd->minor_shift) - 1;
-	char buf[40];
 
 	l = (struct unixware_disklabel *)read_dev_sector(bdev, offset+29, &sect);
 	if (!l)
@@ -356,18 +312,16 @@
 		put_dev_sector(sect);
 		return;
 	}
-	printk(" %s: <unixware:", partition_name(hd, minor, buf));
+	printk(" %s%d: <unixware:", state->name, origin);
 	p = &l->vtoc.v_slice[1];
 	/* I omit the 0th slice as it is the same as whole disk. */
 	while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
-		if ((*current_minor & mask) == 0)
+		if (state->next == state->limit)
 			break;
 
-		if (p->s_label != UNIXWARE_FS_UNUSED) {
-			add_gd_partition(hd, *current_minor, START_SECT(p),
-					 NR_SECTS(p));
-			(*current_minor)++;
-		}
+		if (p->s_label != UNIXWARE_FS_UNUSED)
+			put_partition(state, state->next++,
+						START_SECT(p), NR_SECTS(p));
 		p++;
 	}
 	put_dev_sector(sect);
@@ -380,17 +334,15 @@
  * Anand Krishnamurthy <anandk@wiproge.med.ge.com>
  * Rajeev V. Pillai    <rajeevvp@yahoo.com>
  */
-static void minix_partition(struct gendisk *hd, struct block_device *bdev,
-		int minor, int *current_minor)
+static void
+parse_minix(struct parsed_partitions *state, struct block_device *bdev,
+		u32 offset, u32 size, int origin)
 {
 #ifdef CONFIG_MINIX_SUBPARTITION
-	long offset = hd->part[minor].start_sect;
 	Sector sect;
 	unsigned char *data;
 	struct partition *p;
-	int mask = (1 << hd->minor_shift) - 1;
 	int i;
-	char buf[40];
 
 	data = read_dev_sector(bdev, offset, &sect);
 	if (!data)
@@ -404,16 +356,14 @@
 	if (msdos_magic_present (data + 510) &&
 	    SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */
 
-		printk(" %s: <minix:", partition_name(hd, minor, buf));
+		printk(" %s%d: <minix:", state->name, origin);
 		for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) {
-			if ((*current_minor & mask) == 0)
+			if (state->next == state->limit)
 				break;
 			/* add each partition in use */
-			if (SYS_IND(p) == MINIX_PARTITION) {
-				add_gd_partition(hd, *current_minor,
+			if (SYS_IND(p) == MINIX_PARTITION)
+				put_partition(state, state->next++,
 					      START_SECT(p), NR_SECTS(p));
-				(*current_minor)++;
-			}
 		}
 		printk(" >\n");
 	}
@@ -423,14 +373,15 @@
 
 static struct {
 	unsigned char id;
-	void (*parse)(struct gendisk *, struct block_device *, int, int *);
+	void (*parse)(struct parsed_partitions *, struct block_device *,
+			u32, u32, int);
 } subtypes[] = {
-	{BSD_PARTITION, bsd_partition},
-	{NETBSD_PARTITION, netbsd_partition},
-	{OPENBSD_PARTITION, openbsd_partition},
-	{MINIX_PARTITION, minix_partition},
-	{UNIXWARE_PARTITION, unixware_partition},
-	{SOLARIS_X86_PARTITION, solaris_x86_partition},
+	{BSD_PARTITION, parse_freebsd},
+	{NETBSD_PARTITION, parse_netbsd},
+	{OPENBSD_PARTITION, parse_openbsd},
+	{MINIX_PARTITION, parse_minix},
+	{UNIXWARE_PARTITION, parse_unixware},
+	{SOLARIS_X86_PARTITION, parse_solaris_x86},
 	{0, NULL},
 };
 /*
@@ -515,16 +466,13 @@
 	return 1;
 }
  
-int msdos_partition(struct gendisk *hd, struct block_device *bdev,
-		    unsigned long first_sector, int first_part_minor)
+int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
-	int i, minor = first_part_minor;
+	int sector_size = bdev_hardsect_size(bdev) / 512;
 	Sector sect;
-	struct partition *p;
 	unsigned char *data;
-	int mask = (1 << hd->minor_shift) - 1;
-	int sector_size = bdev_hardsect_size(bdev) / 512;
-	int current_minor = first_part_minor;
+	struct partition *p;
+	int slot;
 	int err;
 
 	err = handle_ide_mess(bdev);
@@ -539,7 +487,7 @@
 	}
 	p = (struct partition *) (data + 0x1be);
 #ifdef CONFIG_EFI_PARTITION
-	for (i=1 ; i<=4 ; i++,p++) {
+	for (slot = 1 ; slot <= 4 ; slot++, p++) {
 		/* If this is an EFI GPT disk, msdos should ignore it. */
 		if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) {
 			put_dev_sector(sect);
@@ -555,28 +503,24 @@
 	 * On the second pass look inside *BSD, Unixware and Solaris partitions.
 	 */
 
-	current_minor += 4;
-	for (i=1 ; i<=4 ; minor++,i++,p++) {
-		if (!NR_SECTS(p))
+	state->next = 5;
+	for (slot = 1 ; slot <= 4 ; slot++, p++) {
+		u32 start = START_SECT(p)*sector_size;
+		u32 size = NR_SECTS(p)*sector_size;
+		if (!size)
 			continue;
-		add_gd_partition(hd, minor,
-				first_sector+START_SECT(p)*sector_size,
-				NR_SECTS(p)*sector_size);
-#if CONFIG_BLK_DEV_MD
-		if (SYS_IND(p) == LINUX_RAID_PARTITION) {
-			md_autodetect_dev(mk_kdev(hd->major,minor));
-		}
-#endif
 		if (is_extended_partition(p)) {
-			unsigned long size = hd->part[minor].nr_sects;
-			printk(" <");
 			/* prevent someone doing mkfs or mkswap on an
 			   extended partition, but leave room for LILO */
-			if (size > 2)
-				hd->part[minor].nr_sects = 2;
-			extended_partition(hd, bdev, minor, size, &current_minor);
+			put_partition(state, slot, start, size == 1 ? 1 : 2);
+			printk(" <");
+			parse_extended(state, bdev, start, size);
 			printk(" >");
+			continue;
 		}
+		put_partition(state, slot, start, size);
+		if (SYS_IND(p) == LINUX_RAID_PARTITION)
+			state->parts[slot].flags = 1;
 	}
 
 	/*
@@ -584,21 +528,21 @@
 	 */
 	if (msdos_magic_present(data + 0xfc)) {
 		p = (struct partition *) (0x1be + data);
-		for (i = 4 ; i < 16 ; i++, current_minor++) {
+		for (slot = 4 ; slot < 16 ; slot++, state->next++) {
 			p--;
-			if ((current_minor & mask) == 0)
+			if (state->next == state->limit)
 				break;
 			if (!(START_SECT(p) && NR_SECTS(p)))
 				continue;
-			add_gd_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
+			put_partition(state, state->next,
+						START_SECT(p), NR_SECTS(p));
 		}
 	}
 	printk("\n");
 
 	/* second pass - output for each on a separate line */
-	minor -= 4;
 	p = (struct partition *) (0x1be + data);
-	for (i=1 ; i<=4 ; minor++,i++,p++) {
+	for (slot = 1 ; slot <= 4 ; slot++, p++) {
 		unsigned char id = SYS_IND(p);
 		int n;
 
@@ -608,8 +552,10 @@
 		for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++)
 			;
 
-		if (subtypes[n].parse)
-			subtypes[n].parse(hd, bdev, minor, &current_minor);
+		if (!subtypes[n].parse)
+			continue;
+		subtypes[n].parse(state, bdev, START_SECT(p)*sector_size,
+						NR_SECTS(p)*sector_size, n);
 	}
 	put_dev_sector(sect);
 	return 1;
diff -Nru a/fs/partitions/msdos.h b/fs/partitions/msdos.h
--- a/fs/partitions/msdos.h	Wed Jul 24 14:03:38 2002
+++ b/fs/partitions/msdos.h	Wed Jul 24 14:03:38 2002
@@ -4,6 +4,5 @@
 
 #define MSDOS_LABEL_MAGIC		0xAA55
 
-int msdos_partition(struct gendisk *hd, struct block_device *bdev,
-		    unsigned long first_sector, int first_part_minor);
+int msdos_partition(struct parsed_partitions *state, struct block_device *bdev);
 
diff -Nru a/fs/partitions/osf.c b/fs/partitions/osf.c
--- a/fs/partitions/osf.c	Wed Jul 24 14:03:36 2002
+++ b/fs/partitions/osf.c	Wed Jul 24 14:03:36 2002
@@ -7,23 +7,15 @@
  *  Re-organised Feb 1998 Russell King
  */
 
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/blk.h>
-
 #include "check.h"
 #include "osf.h"
 
-int osf_partition(struct gendisk *hd, struct block_device *bdev,
-		unsigned long first_sector, int current_minor)
+int osf_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	int i;
+	int slot = 1;
 	Sector sect;
 	unsigned char *data;
-	int mask = (1 << hd->minor_shift) - 1;
 	struct disklabel {
 		u32 d_magic;
 		u16 d_type,d_subtype;
@@ -72,16 +64,14 @@
 		return 0;
 	}
 	for (i = 0 ; i < le16_to_cpu(label->d_npartitions); i++, partition++) {
-		if ((current_minor & mask) == 0)
+		if (slot == state->limit)
 		        break;
 		if (le32_to_cpu(partition->p_size))
-			add_gd_partition(hd, current_minor,
-				first_sector+le32_to_cpu(partition->p_offset),
+			put_partition(state, slot++,
+				le32_to_cpu(partition->p_offset),
 				le32_to_cpu(partition->p_size));
-		current_minor++;
 	}
 	printk("\n");
 	put_dev_sector(sect);
 	return 1;
 }
-
diff -Nru a/fs/partitions/osf.h b/fs/partitions/osf.h
--- a/fs/partitions/osf.h	Wed Jul 24 14:03:36 2002
+++ b/fs/partitions/osf.h	Wed Jul 24 14:03:36 2002
@@ -4,6 +4,4 @@
 
 #define DISKLABELMAGIC (0x82564557UL)
 
-int osf_partition(struct gendisk *hd, struct block_device *bdev,
-		unsigned long first_sector, int current_minor);
-
+int osf_partition(struct parsed_partitions *state, struct block_device *bdev);
diff -Nru a/fs/partitions/sgi.c b/fs/partitions/sgi.c
--- a/fs/partitions/sgi.c	Wed Jul 24 14:03:36 2002
+++ b/fs/partitions/sgi.c	Wed Jul 24 14:03:36 2002
@@ -4,22 +4,13 @@
  *  Code extracted from drivers/block/genhd.c
  */
 
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/blk.h>
-
-#include <asm/byteorder.h>
-#include <asm/system.h>
-
 #include "check.h"
 #include "sgi.h"
 
-int sgi_partition(struct gendisk *hd, struct block_device *bdev, unsigned long first_sector, int current_minor)
+int sgi_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	int i, csum, magic;
+	int slot = 1;
 	unsigned int *ui, start, blocks, cs;
 	Sector sect;
 	struct sgi_disklabel {
@@ -73,10 +64,8 @@
 	for(i = 0; i < 16; i++, p++) {
 		blocks = be32_to_cpu(p->num_blocks);
 		start  = be32_to_cpu(p->first_block);
-		if(!blocks)
-			continue;
-		add_gd_partition(hd, current_minor, start, blocks);
-		current_minor++;
+		if (blocks)
+			put_partition(state, slot++, start, blocks);
 	}
 	printk("\n");
 	put_dev_sector(sect);
diff -Nru a/fs/partitions/sgi.h b/fs/partitions/sgi.h
--- a/fs/partitions/sgi.h	Wed Jul 24 14:03:37 2002
+++ b/fs/partitions/sgi.h	Wed Jul 24 14:03:37 2002
@@ -2,8 +2,7 @@
  *  fs/partitions/sgi.h
  */
 
-extern int sgi_partition(struct gendisk *hd, struct block_device *bdev,
-	 unsigned long first_sector, int first_part_minor);
+extern int sgi_partition(struct parsed_partitions *state, struct block_device *bdev);
 
 #define SGI_LABEL_MAGIC 0x0be5a941
 
diff -Nru a/fs/partitions/sun.c b/fs/partitions/sun.c
--- a/fs/partitions/sun.c	Wed Jul 24 14:03:37 2002
+++ b/fs/partitions/sun.c	Wed Jul 24 14:03:37 2002
@@ -7,21 +7,13 @@
  *  Re-organised Feb 1998 Russell King
  */
 
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/blk.h>
-
-#include <asm/system.h>
-
 #include "check.h"
 #include "sun.h"
 
-int sun_partition(struct gendisk *hd, struct block_device *bdev, unsigned long first_sector, int first_part_minor)
+int sun_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	int i, csum;
+	int slot = 1;
 	unsigned short *ush;
 	Sector sect;
 	struct sun_disklabel {
@@ -74,11 +66,10 @@
 		unsigned long st_sector;
 		int num_sectors;
 
-		st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc;
+		st_sector = be32_to_cpu(p->start_cylinder) * spc;
 		num_sectors = be32_to_cpu(p->num_sectors);
 		if (num_sectors)
-			add_gd_partition(hd, first_part_minor, st_sector, num_sectors);
-		first_part_minor++;
+			put_partition(state, slot++, st_sector, num_sectors);
 	}
 	printk("\n");
 	put_dev_sector(sect);
diff -Nru a/fs/partitions/sun.h b/fs/partitions/sun.h
--- a/fs/partitions/sun.h	Wed Jul 24 14:03:38 2002
+++ b/fs/partitions/sun.h	Wed Jul 24 14:03:38 2002
@@ -4,6 +4,4 @@
 
 #define SUN_LABEL_MAGIC          0xDABE
 
-int sun_partition(struct gendisk *hd, struct block_device *bdev,
-		  unsigned long first_sector, int first_part_minor);
-
+int sun_partition(struct parsed_partitions *state, struct block_device *bdev);
diff -Nru a/fs/partitions/ultrix.c b/fs/partitions/ultrix.c
--- a/fs/partitions/ultrix.c	Wed Jul 24 14:03:36 2002
+++ b/fs/partitions/ultrix.c	Wed Jul 24 14:03:36 2002
@@ -6,16 +6,9 @@
  *  Re-organised Jul 1999 Russell King
  */
 
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/blk.h>
-
 #include "check.h"
 
-int ultrix_partition(struct gendisk *hd, struct block_device *bdev,
-                            unsigned long first_sector, int first_part_minor)
+int ultrix_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	int i;
 	Sector sect;
@@ -39,9 +32,9 @@
 	label = (struct ultrix_disklabel *)(data + 512 - sizeof(*label));
 
 	if (label->pt_magic == PT_MAGIC && label->pt_valid == PT_VALID) {
-		for (i=0; i<8; i++, first_part_minor++)
+		for (i=0; i<8; i++)
 			if (label->pt_part[i].pi_nblocks)
-				add_gd_partition(hd, first_part_minor, 
+				put_partition(state, i+1, 
 					      label->pt_part[i].pi_blkoff,
 					      label->pt_part[i].pi_nblocks);
 		put_dev_sector(sect);
diff -Nru a/fs/partitions/ultrix.h b/fs/partitions/ultrix.h
--- a/fs/partitions/ultrix.h	Wed Jul 24 14:03:38 2002
+++ b/fs/partitions/ultrix.h	Wed Jul 24 14:03:38 2002
@@ -2,6 +2,4 @@
  *  fs/partitions/ultrix.h
  */
 
-int ultrix_partition(struct gendisk *hd, struct block_device *bdev,
-                     unsigned long first_sector, int first_part_minor);
-
+int ultrix_partition(struct parsed_partitions *state, struct block_device *bdev);
diff -Nru a/fs/proc/array.c b/fs/proc/array.c
--- a/fs/proc/array.c	Wed Jul 24 14:03:38 2002
+++ b/fs/proc/array.c	Wed Jul 24 14:03:38 2002
@@ -277,15 +277,11 @@
 int proc_pid_status(struct task_struct *task, char * buffer)
 {
 	char * orig = buffer;
-	struct mm_struct *mm;
+	struct mm_struct *mm = get_task_mm(task);
 
 	buffer = task_name(task, buffer);
 	buffer = task_state(task, buffer);
-	task_lock(task);
-	mm = task->mm;
-	if(mm)
-		atomic_inc(&mm->mm_users);
-	task_unlock(task);
+ 
 	if (mm) {
 		buffer = task_mem(mm, buffer);
 		mmput(mm);
@@ -481,14 +477,9 @@
 
 int proc_pid_statm(struct task_struct *task, char * buffer)
 {
-	struct mm_struct *mm;
 	int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
+	struct mm_struct *mm = get_task_mm(task);
 
-	task_lock(task);
-	mm = task->mm;
-	if(mm)
-		atomic_inc(&mm->mm_users);
-	task_unlock(task);
 	if (mm) {
 		struct vm_area_struct * vma;
 		down_read(&mm->mmap_sem);
@@ -626,11 +617,8 @@
 	if (!tmp)
 		goto out_free1;
 
-	task_lock(task);
-	mm = task->mm;
-	if (mm)
-		atomic_inc(&mm->mm_users);
-	task_unlock(task);
+	mm = get_task_mm(task);
+ 
 	retval = 0;
 	if (!mm)
 		goto out_free2;
diff -Nru a/fs/proc/base.c b/fs/proc/base.c
--- a/fs/proc/base.c	Wed Jul 24 14:03:35 2002
+++ b/fs/proc/base.c	Wed Jul 24 14:03:35 2002
@@ -131,16 +131,11 @@
 
 static int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
-	struct mm_struct * mm;
 	struct vm_area_struct * vma;
 	int result = -ENOENT;
 	struct task_struct *task = proc_task(inode);
+	struct mm_struct * mm = get_task_mm(task);
 
-	task_lock(task);
-	mm = task->mm;
-	if (mm)
-		atomic_inc(&mm->mm_users);
-	task_unlock(task);
 	if (!mm)
 		goto out;
 	down_read(&mm->mmap_sem);
@@ -203,13 +198,8 @@
 
 static int proc_pid_environ(struct task_struct *task, char * buffer)
 {
-	struct mm_struct *mm;
 	int res = 0;
-	task_lock(task);
-	mm = task->mm;
-	if (mm)
-		atomic_inc(&mm->mm_users);
-	task_unlock(task);
+	struct mm_struct *mm = get_task_mm(task);
 	if (mm) {
 		int len = mm->env_end - mm->env_start;
 		if (len > PAGE_SIZE)
@@ -222,38 +212,36 @@
 
 static int proc_pid_cmdline(struct task_struct *task, char * buffer)
 {
-	struct mm_struct *mm;
 	int res = 0;
-	task_lock(task);
-	mm = task->mm;
-	if (mm)
-		atomic_inc(&mm->mm_users);
-	task_unlock(task);
-	if (mm) {
-		int len = mm->arg_end - mm->arg_start;
-		if (len > PAGE_SIZE)
-			len = PAGE_SIZE;
-		res = access_process_vm(task, mm->arg_start, buffer, len, 0);
-		// If the nul at the end of args has been overwritten, then
-		// assume application is using setproctitle(3).
-		if ( res > 0 && buffer[res-1] != '\0' )
-		{
-			len = strnlen( buffer, res );
-			if ( len < res )
-			{
-			    res = len;
-			}
-			else
-			{
-				len = mm->env_end - mm->env_start;
-				if (len > PAGE_SIZE - res)
-					len = PAGE_SIZE - res;
-				res += access_process_vm(task, mm->env_start, buffer+res, len, 0);
-				res = strnlen( buffer, res );
-			}
+	int len;
+	struct mm_struct *mm = get_task_mm(task);
+	if (!mm)
+		goto out;
+
+ 	len = mm->arg_end - mm->arg_start;
+ 
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+ 
+	res = access_process_vm(task, mm->arg_start, buffer, len, 0);
+
+	// If the nul at the end of args has been overwritten, then
+	// assume application is using setproctitle(3).
+	if (res > 0 && buffer[res-1] != '\0') {
+		len = strnlen(buffer, res);
+		if (len < res) {
+		    res = len;
+		} else {
+			len = mm->env_end - mm->env_start;
+			if (len > PAGE_SIZE - res)
+				len = PAGE_SIZE - res;
+			res += access_process_vm(task, mm->env_start, buffer+res, len, 0);
+			res = strnlen(buffer, res);
 		}
-		mmput(mm);
 	}
+	mmput(mm);
+
+out:
 	return res;
 }
 
@@ -421,54 +409,59 @@
 	struct task_struct *task = proc_task(file->f_dentry->d_inode);
 	char *page;
 	unsigned long src = *ppos;
-	int copied = 0;
+	int ret = -ESRCH;
 	struct mm_struct *mm;
 
-
 	if (!MAY_PTRACE(task))
-		return -ESRCH;
+		goto out;
 
+	ret = -ENOMEM;
 	page = (char *)__get_free_page(GFP_USER);
 	if (!page)
-		return -ENOMEM;
+		goto out;
 
-	task_lock(task);
-	mm = task->mm;
-	if (mm)
-		atomic_inc(&mm->mm_users);
-	task_unlock(task);
+	ret = 0;
+ 
+	mm = get_task_mm(task);
 	if (!mm)
-		return 0;
+		goto out_free;
 
-	if (file->private_data != (void*)((long)current->self_exec_id) ) {
-		mmput(mm);
-		return -EIO;
-	}
-		
+	ret = -EIO;
+ 
+	if (file->private_data != (void*)((long)current->self_exec_id))
+		goto out_put;
 
+	ret = 0;
+ 
 	while (count > 0) {
 		int this_len, retval;
 
 		this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
 		retval = access_process_vm(task, src, page, this_len, 0);
 		if (!retval) {
-			if (!copied)
-				copied = -EIO;
+			if (!ret)
+				ret = -EIO;
 			break;
 		}
+
 		if (copy_to_user(buf, page, retval)) {
-			copied = -EFAULT;
+			ret = -EFAULT;
 			break;
 		}
-		copied += retval;
+ 
+		ret += retval;
 		src += retval;
 		buf += retval;
 		count -= retval;
 	}
 	*ppos = src;
+
+out_put:
 	mmput(mm);
+out_free:
 	free_page((unsigned long) page);
-	return copied;
+out:
+	return ret;
 }
 
 #define mem_write NULL
diff -Nru a/include/asm-alpha/io.h b/include/asm-alpha/io.h
--- a/include/asm-alpha/io.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-alpha/io.h	Wed Jul 24 14:03:37 2002
@@ -31,7 +31,7 @@
 static inline void __set_hae(unsigned long new_hae)
 {
 	unsigned long flags;
-	__save_and_cli(flags);
+	local_irq_save(flags);
 
 	alpha_mv.hae_cache = new_hae;
 	*alpha_mv.hae_register = new_hae;
@@ -39,7 +39,7 @@
 	/* Re-read to make sure it was written.  */
 	new_hae = *alpha_mv.hae_register;
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void set_hae(unsigned long new_hae)
diff -Nru a/include/asm-alpha/smplock.h b/include/asm-alpha/smplock.h
--- a/include/asm-alpha/smplock.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-alpha/smplock.h	Wed Jul 24 14:03:37 2002
@@ -20,7 +20,7 @@
 	if (task->lock_depth >= 0)
 		spin_unlock(&kernel_flag);
 	release_irqlock(cpu);
-	__sti();
+	local_irq_enable();
 }
 
 /*
diff -Nru a/include/asm-alpha/system.h b/include/asm-alpha/system.h
--- a/include/asm-alpha/system.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-alpha/system.h	Wed Jul 24 14:03:38 2002
@@ -303,16 +303,11 @@
 #define getipl()		(rdps() & 7)
 #define setipl(ipl)		((void) swpipl(ipl))
 
-#define __cli()			do { setipl(IPL_MAX); barrier(); } while(0)
-#define __sti()			do { barrier(); setipl(IPL_MIN); } while(0)
-#define __save_flags(flags)	((flags) = rdps())
-#define __save_and_cli(flags)	do { (flags) = swpipl(IPL_MAX); barrier(); } while(0)
-#define __restore_flags(flags)	do { barrier(); setipl(flags); barrier(); } while(0)
-
-#define local_irq_save(flags)		__save_and_cli(flags)
-#define local_irq_restore(flags)	__restore_flags(flags)
-#define local_irq_disable()		__cli()
-#define local_irq_enable()		__sti()
+#define local_irq_disable()			do { setipl(IPL_MAX); barrier(); } while(0)
+#define local_irq_enable()			do { barrier(); setipl(IPL_MIN); } while(0)
+#define local_save_flags(flags)	((flags) = rdps())
+#define local_irq_save(flags)	do { (flags) = swpipl(IPL_MAX); barrier(); } while(0)
+#define local_irq_restore(flags)	do { barrier(); setipl(flags); barrier(); } while(0)
 
 #ifdef CONFIG_SMP
 
@@ -332,11 +327,11 @@
 
 #else /* CONFIG_SMP */
 
-#define cli()			__cli()
-#define sti()			__sti()
-#define save_flags(flags)	__save_flags(flags)
-#define save_and_cli(flags)	__save_and_cli(flags)
-#define restore_flags(flags)	__restore_flags(flags)
+#define cli()			local_irq_disable()
+#define sti()			local_irq_enable()
+#define save_flags(flags)	local_save_flags(flags)
+#define save_and_cli(flags)	local_irq_save(flags)
+#define restore_flags(flags)	local_irq_restore(flags)
 
 #endif /* CONFIG_SMP */
 
diff -Nru a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
--- a/include/asm-arm/atomic.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-arm/atomic.h	Wed Jul 24 14:03:36 2002
@@ -36,36 +36,36 @@
 {
 	unsigned long flags;
 
-	__save_flags_cli(flags);
+	local_save_flags_cli(flags);
 	v->counter += i;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void atomic_sub(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 
-	__save_flags_cli(flags);
+	local_save_flags_cli(flags);
 	v->counter -= i;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void atomic_inc(volatile atomic_t *v)
 {
 	unsigned long flags;
 
-	__save_flags_cli(flags);
+	local_save_flags_cli(flags);
 	v->counter += 1;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void atomic_dec(volatile atomic_t *v)
 {
 	unsigned long flags;
 
-	__save_flags_cli(flags);
+	local_save_flags_cli(flags);
 	v->counter -= 1;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline int atomic_dec_and_test(volatile atomic_t *v)
@@ -73,10 +73,10 @@
 	unsigned long flags;
 	int val;
 
-	__save_flags_cli(flags);
+	local_save_flags_cli(flags);
 	val = v->counter;
 	v->counter = val -= 1;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return val == 0;
 }
@@ -86,10 +86,10 @@
 	unsigned long flags;
 	int val;
 
-	__save_flags_cli(flags);
+	local_save_flags_cli(flags);
 	val = v->counter;
 	v->counter = val += i;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	return val < 0;
 }
@@ -98,9 +98,9 @@
 {
 	unsigned long flags;
 
-	__save_flags_cli(flags);
+	local_save_flags_cli(flags);
 	*addr &= ~mask;
-	__restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /* Atomic operations are already serializing on ARM */
diff -Nru a/include/asm-arm/proc-armo/system.h b/include/asm-arm/proc-armo/system.h
--- a/include/asm-arm/proc-armo/system.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-arm/proc-armo/system.h	Wed Jul 24 14:03:37 2002
@@ -39,7 +39,7 @@
 /*
  * Save the current interrupt enable state & disable IRQs
  */
-#define __save_flags_cli(x)				\
+#define local_save_flags_cli(x)				\
 	do {						\
 	  unsigned long temp;				\
 	  __asm__ __volatile__(				\
@@ -55,7 +55,7 @@
 /*
  * Enable IRQs
  */
-#define __sti()					\
+#define local_irq_enable()					\
 	do {					\
 	  unsigned long temp;			\
 	  __asm__ __volatile__(			\
@@ -70,7 +70,7 @@
 /*
  * Disable IRQs
  */
-#define __cli()					\
+#define local_irq_disable()					\
 	do {					\
 	  unsigned long temp;			\
 	  __asm__ __volatile__(			\
@@ -103,7 +103,7 @@
 /*
  * save current IRQ & FIQ state
  */
-#define __save_flags(x)				\
+#define local_save_flags(x)				\
 	do {					\
 	  __asm__ __volatile__(			\
 "	mov	%0, pc		@ save_flags\n"	\
@@ -114,7 +114,7 @@
 /*
  * restore saved IRQ & FIQ state
  */
-#define __restore_flags(x)				\
+#define local_irq_restore(x)				\
 	do {						\
 	  unsigned long temp;				\
 	  __asm__ __volatile__(				\
diff -Nru a/include/asm-arm/proc-armv/system.h b/include/asm-arm/proc-armv/system.h
--- a/include/asm-arm/proc-armv/system.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-arm/proc-armv/system.h	Wed Jul 24 14:03:35 2002
@@ -49,7 +49,7 @@
 /*
  * Save the current interrupt enable state & disable IRQs
  */
-#define __save_flags_cli(x)					\
+#define local_save_flags_cli(x)					\
 	({							\
 		unsigned long temp;				\
 	__asm__ __volatile__(					\
@@ -64,7 +64,7 @@
 /*
  * Enable IRQs
  */
-#define __sti()							\
+#define local_irq_enable()							\
 	({							\
 		unsigned long temp;				\
 	__asm__ __volatile__(					\
@@ -79,7 +79,7 @@
 /*
  * Disable IRQs
  */
-#define __cli()							\
+#define local_irq_disable()							\
 	({							\
 		unsigned long temp;				\
 	__asm__ __volatile__(					\
@@ -124,7 +124,7 @@
 /*
  * save current IRQ & FIQ state
  */
-#define __save_flags(x)						\
+#define local_save_flags(x)						\
 	__asm__ __volatile__(					\
 	"mrs	%0, cpsr		@ save_flags\n"		\
 	  : "=r" (x)						\
@@ -134,7 +134,7 @@
 /*
  * restore saved IRQ & FIQ state
  */
-#define __restore_flags(x)					\
+#define local_irq_restore(x)					\
 	__asm__ __volatile__(					\
 	"msr	cpsr_c, %0		@ restore_flags\n"	\
 	:							\
@@ -168,17 +168,17 @@
 	switch (size) {
 #ifdef swp_is_buggy
 		case 1:
-			__save_flags_cli(flags);
+			local_save_flags_cli(flags);
 			ret = *(volatile unsigned char *)ptr;
 			*(volatile unsigned char *)ptr = x;
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			break;
 
 		case 4:
-			__save_flags_cli(flags);
+			local_save_flags_cli(flags);
 			ret = *(volatile unsigned long *)ptr;
 			*(volatile unsigned long *)ptr = x;
-			__restore_flags(flags);
+			local_irq_restore(flags);
 			break;
 #else
 		case 1:	__asm__ __volatile__ ("swpb %0, %1, [%2]"
diff -Nru a/include/asm-arm/system.h b/include/asm-arm/system.h
--- a/include/asm-arm/system.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-arm/system.h	Wed Jul 24 14:03:36 2002
@@ -76,10 +76,7 @@
 	} while (0)
 
 /* For spinlocks etc */
-#define local_irq_save(x)	__save_flags_cli(x)
-#define local_irq_restore(x)	__restore_flags(x)
-#define local_irq_disable()	__cli()
-#define local_irq_enable()	__sti()
+#define local_irq_save(x)	local_save_flags_cli(x)
 
 #ifdef CONFIG_SMP
 #error SMP not supported
@@ -94,12 +91,12 @@
 #define smp_rmb()		barrier()
 #define smp_wmb()		barrier()
 
-#define cli()			__cli()
-#define sti()			__sti()
+#define cli()			local_irq_disable()
+#define sti()			local_irq_enable()
 #define clf()			__clf()
 #define stf()			__stf()
-#define save_flags(x)		__save_flags(x)
-#define restore_flags(x)	__restore_flags(x)
+#define save_flags(x)		local_save_flags(x)
+#define restore_flags(x)	local_irq_restore(x)
 
 #endif /* CONFIG_SMP */
 
diff -Nru a/include/asm-arm/tlb.h b/include/asm-arm/tlb.h
--- a/include/asm-arm/tlb.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-arm/tlb.h	Wed Jul 24 14:03:35 2002
@@ -11,7 +11,7 @@
 #define tlb_end_vma(tlb,vma)	\
 	flush_tlb_range(vma, vma->vm_start, vma->vm_end)
 
-#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+#define tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
 
 #include <asm-generic/tlb.h>
 
diff -Nru a/include/asm-cris/softirq.h b/include/asm-cris/softirq.h
--- a/include/asm-cris/softirq.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-cris/softirq.h	Wed Jul 24 14:03:36 2002
@@ -21,7 +21,7 @@
         if (!--local_bh_count(smp_processor_id())       \
             && softirq_pending(smp_processor_id())) {   \
                 do_softirq();                           \
-                __sti();                                \
+                local_irq_enable();                                \
         }                                               \
 } while (0)
 
diff -Nru a/include/asm-cris/sv_addr.agh b/include/asm-cris/sv_addr.agh
--- a/include/asm-cris/sv_addr.agh	Wed Jul 24 14:03:37 2002
+++ b/include/asm-cris/sv_addr.agh	Wed Jul 24 14:03:37 2002
@@ -1142,7 +1142,7 @@
 #define R_SERIAL0_CTRL__rec_stick_par__BITNR 19
 #define R_SERIAL0_CTRL__rec_stick_par__WIDTH 1
 #define R_SERIAL0_CTRL__rec_stick_par__normal 0
-#define R_SERIAL0_CTRL__rec_stick_par__stick 1
+#define R_SERIAL0_CTRL__rec_stick_parlocal_irq_enableck 1
 #define R_SERIAL0_CTRL__rec_par__BITNR 18
 #define R_SERIAL0_CTRL__rec_par__WIDTH 1
 #define R_SERIAL0_CTRL__rec_par__even 0
@@ -1172,7 +1172,7 @@
 #define R_SERIAL0_CTRL__tr_stick_par__BITNR 11
 #define R_SERIAL0_CTRL__tr_stick_par__WIDTH 1
 #define R_SERIAL0_CTRL__tr_stick_par__normal 0
-#define R_SERIAL0_CTRL__tr_stick_par__stick 1
+#define R_SERIAL0_CTRL__tr_stick_parlocal_irq_enableck 1
 #define R_SERIAL0_CTRL__tr_par__BITNR 10
 #define R_SERIAL0_CTRL__tr_par__WIDTH 1
 #define R_SERIAL0_CTRL__tr_par__even 0
@@ -1246,7 +1246,7 @@
 #define R_SERIAL0_REC_CTRL__rec_stick_par__BITNR 3
 #define R_SERIAL0_REC_CTRL__rec_stick_par__WIDTH 1
 #define R_SERIAL0_REC_CTRL__rec_stick_par__normal 0
-#define R_SERIAL0_REC_CTRL__rec_stick_par__stick 1
+#define R_SERIAL0_REC_CTRL__rec_stick_parlocal_irq_enableck 1
 #define R_SERIAL0_REC_CTRL__rec_par__BITNR 2
 #define R_SERIAL0_REC_CTRL__rec_par__WIDTH 1
 #define R_SERIAL0_REC_CTRL__rec_par__even 0
@@ -1278,7 +1278,7 @@
 #define R_SERIAL0_TR_CTRL__tr_stick_par__BITNR 3
 #define R_SERIAL0_TR_CTRL__tr_stick_par__WIDTH 1
 #define R_SERIAL0_TR_CTRL__tr_stick_par__normal 0
-#define R_SERIAL0_TR_CTRL__tr_stick_par__stick 1
+#define R_SERIAL0_TR_CTRL__tr_stick_parlocal_irq_enableck 1
 #define R_SERIAL0_TR_CTRL__tr_par__BITNR 2
 #define R_SERIAL0_TR_CTRL__tr_par__WIDTH 1
 #define R_SERIAL0_TR_CTRL__tr_par__even 0
@@ -1434,7 +1434,7 @@
 #define R_SERIAL1_CTRL__rec_stick_par__BITNR 19
 #define R_SERIAL1_CTRL__rec_stick_par__WIDTH 1
 #define R_SERIAL1_CTRL__rec_stick_par__normal 0
-#define R_SERIAL1_CTRL__rec_stick_par__stick 1
+#define R_SERIAL1_CTRL__rec_stick_parlocal_irq_enableck 1
 #define R_SERIAL1_CTRL__rec_par__BITNR 18
 #define R_SERIAL1_CTRL__rec_par__WIDTH 1
 #define R_SERIAL1_CTRL__rec_par__even 0
@@ -1464,7 +1464,7 @@
 #define R_SERIAL1_CTRL__tr_stick_par__BITNR 11
 #define R_SERIAL1_CTRL__tr_stick_par__WIDTH 1
 #define R_SERIAL1_CTRL__tr_stick_par__normal 0
-#define R_SERIAL1_CTRL__tr_stick_par__stick 1
+#define R_SERIAL1_CTRL__tr_stick_parlocal_irq_enableck 1
 #define R_SERIAL1_CTRL__tr_par__BITNR 10
 #define R_SERIAL1_CTRL__tr_par__WIDTH 1
 #define R_SERIAL1_CTRL__tr_par__even 0
@@ -1538,7 +1538,7 @@
 #define R_SERIAL1_REC_CTRL__rec_stick_par__BITNR 3
 #define R_SERIAL1_REC_CTRL__rec_stick_par__WIDTH 1
 #define R_SERIAL1_REC_CTRL__rec_stick_par__normal 0
-#define R_SERIAL1_REC_CTRL__rec_stick_par__stick 1
+#define R_SERIAL1_REC_CTRL__rec_stick_parlocal_irq_enableck 1
 #define R_SERIAL1_REC_CTRL__rec_par__BITNR 2
 #define R_SERIAL1_REC_CTRL__rec_par__WIDTH 1
 #define R_SERIAL1_REC_CTRL__rec_par__even 0
@@ -1570,7 +1570,7 @@
 #define R_SERIAL1_TR_CTRL__tr_stick_par__BITNR 3
 #define R_SERIAL1_TR_CTRL__tr_stick_par__WIDTH 1
 #define R_SERIAL1_TR_CTRL__tr_stick_par__normal 0
-#define R_SERIAL1_TR_CTRL__tr_stick_par__stick 1
+#define R_SERIAL1_TR_CTRL__tr_stick_parlocal_irq_enableck 1
 #define R_SERIAL1_TR_CTRL__tr_par__BITNR 2
 #define R_SERIAL1_TR_CTRL__tr_par__WIDTH 1
 #define R_SERIAL1_TR_CTRL__tr_par__even 0
@@ -1726,7 +1726,7 @@
 #define R_SERIAL2_CTRL__rec_stick_par__BITNR 19
 #define R_SERIAL2_CTRL__rec_stick_par__WIDTH 1
 #define R_SERIAL2_CTRL__rec_stick_par__normal 0
-#define R_SERIAL2_CTRL__rec_stick_par__stick 1
+#define R_SERIAL2_CTRL__rec_stick_parlocal_irq_enableck 1
 #define R_SERIAL2_CTRL__rec_par__BITNR 18
 #define R_SERIAL2_CTRL__rec_par__WIDTH 1
 #define R_SERIAL2_CTRL__rec_par__even 0
@@ -1756,7 +1756,7 @@
 #define R_SERIAL2_CTRL__tr_stick_par__BITNR 11
 #define R_SERIAL2_CTRL__tr_stick_par__WIDTH 1
 #define R_SERIAL2_CTRL__tr_stick_par__normal 0
-#define R_SERIAL2_CTRL__tr_stick_par__stick 1
+#define R_SERIAL2_CTRL__tr_stick_parlocal_irq_enableck 1
 #define R_SERIAL2_CTRL__tr_par__BITNR 10
 #define R_SERIAL2_CTRL__tr_par__WIDTH 1
 #define R_SERIAL2_CTRL__tr_par__even 0
@@ -1830,7 +1830,7 @@
 #define R_SERIAL2_REC_CTRL__rec_stick_par__BITNR 3
 #define R_SERIAL2_REC_CTRL__rec_stick_par__WIDTH 1
 #define R_SERIAL2_REC_CTRL__rec_stick_par__normal 0
-#define R_SERIAL2_REC_CTRL__rec_stick_par__stick 1
+#define R_SERIAL2_REC_CTRL__rec_stick_parlocal_irq_enableck 1
 #define R_SERIAL2_REC_CTRL__rec_par__BITNR 2
 #define R_SERIAL2_REC_CTRL__rec_par__WIDTH 1
 #define R_SERIAL2_REC_CTRL__rec_par__even 0
@@ -1862,7 +1862,7 @@
 #define R_SERIAL2_TR_CTRL__tr_stick_par__BITNR 3
 #define R_SERIAL2_TR_CTRL__tr_stick_par__WIDTH 1
 #define R_SERIAL2_TR_CTRL__tr_stick_par__normal 0
-#define R_SERIAL2_TR_CTRL__tr_stick_par__stick 1
+#define R_SERIAL2_TR_CTRL__tr_stick_parlocal_irq_enableck 1
 #define R_SERIAL2_TR_CTRL__tr_par__BITNR 2
 #define R_SERIAL2_TR_CTRL__tr_par__WIDTH 1
 #define R_SERIAL2_TR_CTRL__tr_par__even 0
@@ -2018,7 +2018,7 @@
 #define R_SERIAL3_CTRL__rec_stick_par__BITNR 19
 #define R_SERIAL3_CTRL__rec_stick_par__WIDTH 1
 #define R_SERIAL3_CTRL__rec_stick_par__normal 0
-#define R_SERIAL3_CTRL__rec_stick_par__stick 1
+#define R_SERIAL3_CTRL__rec_stick_parlocal_irq_enableck 1
 #define R_SERIAL3_CTRL__rec_par__BITNR 18
 #define R_SERIAL3_CTRL__rec_par__WIDTH 1
 #define R_SERIAL3_CTRL__rec_par__even 0
@@ -2048,7 +2048,7 @@
 #define R_SERIAL3_CTRL__tr_stick_par__BITNR 11
 #define R_SERIAL3_CTRL__tr_stick_par__WIDTH 1
 #define R_SERIAL3_CTRL__tr_stick_par__normal 0
-#define R_SERIAL3_CTRL__tr_stick_par__stick 1
+#define R_SERIAL3_CTRL__tr_stick_parlocal_irq_enableck 1
 #define R_SERIAL3_CTRL__tr_par__BITNR 10
 #define R_SERIAL3_CTRL__tr_par__WIDTH 1
 #define R_SERIAL3_CTRL__tr_par__even 0
@@ -2122,7 +2122,7 @@
 #define R_SERIAL3_REC_CTRL__rec_stick_par__BITNR 3
 #define R_SERIAL3_REC_CTRL__rec_stick_par__WIDTH 1
 #define R_SERIAL3_REC_CTRL__rec_stick_par__normal 0
-#define R_SERIAL3_REC_CTRL__rec_stick_par__stick 1
+#define R_SERIAL3_REC_CTRL__rec_stick_parlocal_irq_enableck 1
 #define R_SERIAL3_REC_CTRL__rec_par__BITNR 2
 #define R_SERIAL3_REC_CTRL__rec_par__WIDTH 1
 #define R_SERIAL3_REC_CTRL__rec_par__even 0
@@ -2154,7 +2154,7 @@
 #define R_SERIAL3_TR_CTRL__tr_stick_par__BITNR 3
 #define R_SERIAL3_TR_CTRL__tr_stick_par__WIDTH 1
 #define R_SERIAL3_TR_CTRL__tr_stick_par__normal 0
-#define R_SERIAL3_TR_CTRL__tr_stick_par__stick 1
+#define R_SERIAL3_TR_CTRL__tr_stick_parlocal_irq_enableck 1
 #define R_SERIAL3_TR_CTRL__tr_par__BITNR 2
 #define R_SERIAL3_TR_CTRL__tr_par__WIDTH 1
 #define R_SERIAL3_TR_CTRL__tr_par__even 0
diff -Nru a/include/asm-cris/system.h b/include/asm-cris/system.h
--- a/include/asm-cris/system.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-cris/system.h	Wed Jul 24 14:03:38 2002
@@ -62,10 +62,10 @@
 #define save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory");
 #define restore_flags(x) __asm__ __volatile__ ("move %0,$ccr\n\tbtstq 5,%0\n\tbpl 1f\n\tnop\n\tpush $r0\n\tmoveq 0,$r0\n\tmove.d $r0,[0x90000000]\n\tpop $r0\n1:\n" : : "r" (x) : "memory");
 #else
-#define __cli() __asm__ __volatile__ ( "di");
-#define __sti() __asm__ __volatile__ ( "ei" );
-#define __save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory");
-#define __restore_flags(x) __asm__ __volatile__ ("move %0,$ccr" : : "rm" (x) : "memory");
+#define local_irq_disable() __asm__ __volatile__ ( "di");
+#define local_irq_enable() __asm__ __volatile__ ( "ei" );
+#define local_save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory");
+#define local_irq_restore(x) __asm__ __volatile__ ("move %0,$ccr" : : "rm" (x) : "memory");
 
 /* For spinlocks etc */
 #define local_irq_save(x) __asm__ __volatile__ ("move $ccr,%0\n\tdi" : "=rm" (x) : : "memory"); 
@@ -76,11 +76,11 @@
 
 #endif
 
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
-#define save_and_cli(x) do { __save_flags(x); cli(); } while(0)
+#define cli() local_irq_disable()
+#define sti() local_irq_enable()
+#define save_flags(x) local_save_flags(x)
+#define restore_flags(x) local_irq_restore(x)
+#define save_and_cli(x) do { local_save_flags(x); cli(); } while(0)
 
 static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
 {
diff -Nru a/include/asm-generic/smplock.h b/include/asm-generic/smplock.h
--- a/include/asm-generic/smplock.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-generic/smplock.h	Wed Jul 24 14:03:35 2002
@@ -13,12 +13,11 @@
 /*
  * Release global kernel lock and global interrupt lock
  */
-#define release_kernel_lock(task, cpu) \
+#define release_kernel_lock(task) \
 do { \
 	if (task->lock_depth >= 0) \
 		spin_unlock(&kernel_flag); \
-	release_irqlock(cpu); \
-	__sti(); \
+	local_irq_enable(); \
 } while (0)
 
 /*
diff -Nru a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
--- a/include/asm-i386/acpi.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-i386/acpi.h	Wed Jul 24 14:03:39 2002
@@ -48,8 +48,8 @@
 
 #define ACPI_ASM_MACROS
 #define BREAKPOINT3
-#define ACPI_DISABLE_IRQS() __cli()
-#define ACPI_ENABLE_IRQS()  __sti()
+#define ACPI_DISABLE_IRQS() local_irq_disable()
+#define ACPI_ENABLE_IRQS()  local_irq_enable()
 #define ACPI_FLUSH_CPU_CACHE()	wbinvd()
 
 /*
diff -Nru a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h
--- a/include/asm-i386/hardirq.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-i386/hardirq.h	Wed Jul 24 14:03:39 2002
@@ -8,8 +8,6 @@
 /* assembly code in softirq.h is sensitive to the offsets of these fields */
 typedef struct {
 	unsigned int __softirq_pending;
-	unsigned int __local_irq_count;
-	unsigned int __local_bh_count;
 	unsigned int __syscall_count;
 	struct task_struct * __ksoftirqd_task; /* waitqueue is too large */
 	unsigned long idle_timestamp;
@@ -19,76 +17,84 @@
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
 /*
- * Are we in an interrupt context? Either doing bottom half
- * or hardware interrupt processing?
+ * We put the hardirq and softirq counter into the preemption
+ * counter. The bitmask has the following meaning:
+ *
+ * - bits 0-7 are the preemption count (max preemption depth: 256)
+ * - bits 8-15 are the softirq count (max # of softirqs: 256)
+ * - bits 16-23 are the hardirq count (max # of hardirqs: 256)
+ *
+ * - ( bit 26 is the PREEMPT_ACTIVE flag. )
+ *
+ * PREEMPT_MASK: 0x000000ff
+ * HARDIRQ_MASK: 0x0000ff00
+ * SOFTIRQ_MASK: 0x00ff0000
  */
-#define in_interrupt() ({ int __cpu = smp_processor_id(); \
-	(local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
 
-#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+#define PREEMPT_BITS	8
+#define SOFTIRQ_BITS	8
+#define HARDIRQ_BITS	8
+
+#define PREEMPT_SHIFT	0
+#define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)
+#define HARDIRQ_SHIFT	(SOFTIRQ_SHIFT + SOFTIRQ_BITS)
+
+#define __MASK(x)	((1UL << (x))-1)
+
+#define PREEMPT_MASK	(__MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
+#define HARDIRQ_MASK	(__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
+#define SOFTIRQ_MASK	(__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
+
+#define hardirq_count()	(preempt_count() & HARDIRQ_MASK)
+#define softirq_count()	(preempt_count() & SOFTIRQ_MASK)
+#define irq_count()	(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
+
+#define PREEMPT_OFFSET	(1UL << PREEMPT_SHIFT)
+#define SOFTIRQ_OFFSET	(1UL << SOFTIRQ_SHIFT)
+#define HARDIRQ_OFFSET	(1UL << HARDIRQ_SHIFT)
 
-#ifndef CONFIG_SMP
+/*
+ * The hardirq mask has to be large enough to have
+ * space for potentially all IRQ sources in the system
+ * nesting on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+#endif
 
-#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
-#define hardirq_endlock(cpu)	do { } while (0)
+/*
+ * Are we doing bottom half or hardware interrupt processing?
+ * Are we in a softirq context? Interrupt context?
+ */
+#define in_irq()		(hardirq_count())
+#define in_softirq()		(softirq_count())
+#define in_interrupt()		(irq_count())
 
-#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
-#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
 
-#define synchronize_irq()	barrier()
+#define hardirq_trylock()	(!in_interrupt())
+#define hardirq_endlock()	do { } while (0)
 
-#define release_irqlock(cpu)	do { } while (0)
+#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
 
+#if CONFIG_PREEMPT
+# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
+# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
+#endif
+#define irq_exit()							\
+do {									\
+		preempt_count() -= IRQ_EXIT_OFFSET;			\
+		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
+			do_softirq();					\
+		preempt_enable_no_resched();				\
+} while (0)
 
-#include <asm/atomic.h>
-#include <asm/smp.h>
-
-extern unsigned char global_irq_holder;
-extern unsigned volatile long global_irq_lock; /* long for set_bit -RR */
-
-static inline int irqs_running (void)
-{
-	int i;
-
-	for (i = 0; i < NR_CPUS; i++)
-		if (local_irq_count(i))
-			return 1;
-	return 0;
-}
-
-static inline void release_irqlock(int cpu)
-{
-	/* if we didn't own the irq lock, just ignore.. */
-	if (global_irq_holder == (unsigned char) cpu) {
-		global_irq_holder = NO_PROC_ID;
-		clear_bit(0,&global_irq_lock);
-	}
-}
-
-static inline void irq_enter(int cpu, int irq)
-{
-	++local_irq_count(cpu);
-
-	while (test_bit(0,&global_irq_lock)) {
-		cpu_relax();
-	}
-}
-
-static inline void irq_exit(int cpu, int irq)
-{
-	--local_irq_count(cpu);
-}
-
-static inline int hardirq_trylock(int cpu)
-{
-	return !local_irq_count(cpu) && !test_bit(0,&global_irq_lock);
-}
-
-#define hardirq_endlock(cpu)	do { } while (0)
-
-extern void synchronize_irq(void);
-
+#ifndef CONFIG_SMP
+# define synchronize_irq(irq)	barrier()
+#else
+  extern void synchronize_irq(unsigned int irq);
 #endif /* CONFIG_SMP */
+
+extern void show_stack(unsigned long * esp);
 
 #endif /* __ASM_HARDIRQ_H */
diff -Nru a/include/asm-i386/smplock.h b/include/asm-i386/smplock.h
--- a/include/asm-i386/smplock.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-i386/smplock.h	Wed Jul 24 14:03:37 2002
@@ -12,15 +12,9 @@
 
 #ifdef CONFIG_SMP
 #define kernel_locked()		spin_is_locked(&kernel_flag)
-#define check_irq_holder(cpu) \
-do { \
-	if (global_irq_holder == (cpu)) \
-		BUG(); \
-} while(0)
 #else
 #ifdef CONFIG_PREEMPT
-#define kernel_locked()		preempt_get_count()
-#define check_irq_holder(cpu)	do { } while(0)
+#define kernel_locked()		preempt_count()
 #else
 #define kernel_locked()		1
 #endif
@@ -29,12 +23,10 @@
 /*
  * Release global kernel lock and global interrupt lock
  */
-#define release_kernel_lock(task, cpu)		\
+#define release_kernel_lock(task)		\
 do {						\
-	if (unlikely(task->lock_depth >= 0)) {	\
+	if (unlikely(task->lock_depth >= 0))	\
 		spin_unlock(&kernel_flag);	\
-		check_irq_holder(cpu);		\
-	}					\
 } while (0)
 
 /*
diff -Nru a/include/asm-i386/softirq.h b/include/asm-i386/softirq.h
--- a/include/asm-i386/softirq.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-i386/softirq.h	Wed Jul 24 14:03:38 2002
@@ -1,50 +1,20 @@
 #ifndef __ASM_SOFTIRQ_H
 #define __ASM_SOFTIRQ_H
 
-#include <asm/atomic.h>
+#include <linux/preempt.h>
 #include <asm/hardirq.h>
 
-#define __cpu_bh_enable(cpu) \
-		do { barrier(); local_bh_count(cpu)--; preempt_enable(); } while (0)
-#define cpu_bh_disable(cpu) \
-		do { preempt_disable(); local_bh_count(cpu)++; barrier(); } while (0)
+#define local_bh_disable() \
+		do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0)
+#define __local_bh_enable() \
+		do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
 
-#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
-#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
-
-#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
-
-/*
- * NOTE: this assembly code assumes:
- *
- *    (char *)&local_bh_count - 8 == (char *)&softirq_pending
- *
- * If you change the offsets in irq_stat then you have to
- * update this code as well.
- */
-#define _local_bh_enable()						\
+#define local_bh_enable()						\
 do {									\
-	unsigned int *ptr = &local_bh_count(smp_processor_id());	\
-									\
-	barrier();							\
-	if (!--*ptr)							\
-		__asm__ __volatile__ (					\
-			"cmpl $0, -8(%0);"				\
-			"jnz 2f;"					\
-			"1:;"						\
-									\
-			LOCK_SECTION_START("")				\
-			"2: pushl %%eax; pushl %%ecx; pushl %%edx;"	\
-			"call %c1;"					\
-			"popl %%edx; popl %%ecx; popl %%eax;"		\
-			"jmp 1b;"					\
-			LOCK_SECTION_END				\
-									\
-		: /* no output */					\
-		: "r" (ptr), "i" (do_softirq)				\
-		/* no registers clobbered */ );				\
+	__local_bh_enable();						\
+	if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \
+		do_softirq();						\
+	preempt_check_resched();					\
 } while (0)
-
-#define local_bh_enable() do { _local_bh_enable(); preempt_enable(); } while (0)
 
 #endif	/* __ASM_SOFTIRQ_H */
diff -Nru a/include/asm-i386/system.h b/include/asm-i386/system.h
--- a/include/asm-i386/system.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-i386/system.h	Wed Jul 24 14:03:35 2002
@@ -11,11 +11,6 @@
 struct task_struct;	/* one of the stranger aspects of C forward declarations.. */
 extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
 
-#define prepare_arch_schedule(prev)		do { } while(0)
-#define finish_arch_schedule(prev)		do { } while(0)
-#define prepare_arch_switch(rq)			do { } while(0)
-#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
-
 #define switch_to(prev,next,last) do {					\
 	asm volatile("pushl %%esi\n\t"					\
 		     "pushl %%edi\n\t"					\
@@ -311,38 +306,22 @@
 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 /* interrupt control.. */
-#define __save_flags(x)		__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
-#define __restore_flags(x) 	__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
-#define __cli() 		__asm__ __volatile__("cli": : :"memory")
-#define __sti()			__asm__ __volatile__("sti": : :"memory")
+#define local_save_flags(x)	__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
+#define local_irq_restore(x) 	__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
+#define local_irq_disable() 	__asm__ __volatile__("cli": : :"memory")
+#define local_irq_enable()	__asm__ __volatile__("sti": : :"memory")
 /* used in the idle loop; sti takes one instruction cycle to complete */
 #define safe_halt()		__asm__ __volatile__("sti; hlt": : :"memory")
 
+#define irqs_disabled()			\
+({					\
+	unsigned long flags;		\
+	local_save_flags(flags);	\
+	!(flags & (1<<9));		\
+})
+
 /* For spinlocks etc */
 #define local_irq_save(x)	__asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
-#define local_irq_restore(x)	__restore_flags(x)
-#define local_irq_disable()	__cli()
-#define local_irq_enable()	__sti()
-
-#ifdef CONFIG_SMP
-
-extern void __global_cli(void);
-extern void __global_sti(void);
-extern unsigned long __global_save_flags(void);
-extern void __global_restore_flags(unsigned long);
-#define cli() __global_cli()
-#define sti() __global_sti()
-#define save_flags(x) ((x)=__global_save_flags())
-#define restore_flags(x) __global_restore_flags(x)
-
-#else
-
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
-
-#endif
 
 /*
  * disable hlt during certain critical i/o operations
diff -Nru a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
--- a/include/asm-i386/thread_info.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-i386/thread_info.h	Wed Jul 24 14:03:36 2002
@@ -51,6 +51,8 @@
 
 /*
  * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
  */
 #ifndef __ASSEMBLY__
 #define INIT_THREAD_INFO(tsk)			\
@@ -59,6 +61,7 @@
 	exec_domain:	&default_exec_domain,	\
 	flags:		0,			\
 	cpu:		0,			\
+	preempt_count:	1,			\
 	addr_limit:	KERNEL_DS,		\
 }
 
diff -Nru a/include/asm-i386/tlb.h b/include/asm-i386/tlb.h
--- a/include/asm-i386/tlb.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-i386/tlb.h	Wed Jul 24 14:03:37 2002
@@ -7,7 +7,7 @@
  */
 #define tlb_start_vma(tlb, vma) do { } while (0)
 #define tlb_end_vma(tlb, vma) do { } while (0)
-#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+#define tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
 
 /*
  * .. because we flush the whole mm when it
diff -Nru a/include/asm-ia64/system.h b/include/asm-ia64/system.h
--- a/include/asm-ia64/system.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-ia64/system.h	Wed Jul 24 14:03:37 2002
@@ -169,12 +169,10 @@
 
 #define local_irq_enable()	__asm__ __volatile__ (";; ssm psr.i;; srlz.d" ::: "memory")
 
-#define __cli()			local_irq_disable ()
-#define __save_flags(flags)	__asm__ __volatile__ ("mov %0=psr" : "=r" (flags) :: "memory")
-#define __save_and_cli(flags)	local_irq_save(flags)
-#define save_and_cli(flags)	__save_and_cli(flags)
-#define __sti()			local_irq_enable ()
-#define __restore_flags(flags)	local_irq_restore(flags)
+#define local_irq_disable()			local_irq_disable ()
+#define local_save_flags(flags)	__asm__ __volatile__ ("mov %0=psr" : "=r" (flags) :: "memory")
+#define local_irq_save(flags)	local_irq_save(flags)
+#define save_and_cli(flags)	local_irq_save(flags)
 
 #ifdef CONFIG_SMP
   extern void __global_cli (void);
@@ -186,10 +184,10 @@
 # define save_flags(flags)	((flags) = __global_save_flags())
 # define restore_flags(flags)	__global_restore_flags(flags)
 #else /* !CONFIG_SMP */
-# define cli()			__cli()
-# define sti()			__sti()
-# define save_flags(flags)	__save_flags(flags)
-# define restore_flags(flags)	__restore_flags(flags)
+# define cli()			local_irq_disable()
+# define sti()			local_irq_enable()
+# define save_flags(flags)	local_save_flags(flags)
+# define restore_flags(flags)	local_irq_restore(flags)
 #endif /* !CONFIG_SMP */
 
 /*
diff -Nru a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h
--- a/include/asm-ia64/tlb.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-ia64/tlb.h	Wed Jul 24 14:03:37 2002
@@ -1,7 +1,7 @@
 /* XXX fix me! */
 #define tlb_start_vma(tlb, vma)			do { } while (0)
 #define tlb_end_vma(tlb, vma)			do { } while (0)
-#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+#define tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
 #define tlb_flush(tlb)				flush_tlb_mm((tlb)->mm)
 
 #include <asm-generic/tlb.h>
diff -Nru a/include/asm-m68k/apollodma.h b/include/asm-m68k/apollodma.h
--- a/include/asm-m68k/apollodma.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-m68k/apollodma.h	Wed Jul 24 14:03:39 2002
@@ -9,7 +9,7 @@
 #define _ASM_APOLLO_DMA_H
 
 #include <asm/apollohw.h>		/* need byte IO */
-#include <asm/spinlock.h>	/* And spinlocks */
+#include <linux/spinlock.h>		/* And spinlocks */
 #include <linux/delay.h>
 
 
diff -Nru a/include/asm-m68k/atarihw.h b/include/asm-m68k/atarihw.h
--- a/include/asm-m68k/atarihw.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-m68k/atarihw.h	Wed Jul 24 14:03:35 2002
@@ -133,7 +133,7 @@
 
 
 #include <linux/mm.h>
-#include <asm/pgalloc.h>
+#include <asm/cacheflush.h>
 
 static inline void dma_cache_maintenance( unsigned long paddr,
 					  unsigned long len,
diff -Nru a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
--- a/include/asm-m68k/bitops.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/bitops.h	Wed Jul 24 14:03:38 2002
@@ -8,6 +8,8 @@
  * for more details.
  */
 
+#include <linux/compiler.h>
+
 /*
  * Require 68020 or better.
  *
@@ -19,7 +21,7 @@
    __constant_test_and_set_bit(nr, vaddr) : \
    __generic_test_and_set_bit(nr, vaddr))
 
-extern __inline__ int __constant_test_and_set_bit(int nr,volatile void * vaddr)
+extern __inline__ int __constant_test_and_set_bit(int nr,volatile unsigned long * vaddr)
 {
 	char retval;
 
@@ -30,7 +32,7 @@
 	return retval;
 }
 
-extern __inline__ int __generic_test_and_set_bit(int nr,volatile void * vaddr)
+extern __inline__ int __generic_test_and_set_bit(int nr,volatile unsigned long * vaddr)
 {
 	char retval;
 
@@ -47,13 +49,13 @@
 
 #define __set_bit(nr,vaddr) set_bit(nr,vaddr) 
 
-extern __inline__ void __constant_set_bit(int nr, volatile void * vaddr)
+extern __inline__ void __constant_set_bit(int nr, volatile unsigned long * vaddr)
 {
 	__asm__ __volatile__ ("bset %1,%0"
 	     : "+m" (((volatile char *)vaddr)[(nr^31) >> 3]) : "di" (nr & 7));
 }
 
-extern __inline__ void __generic_set_bit(int nr, volatile void * vaddr)
+extern __inline__ void __generic_set_bit(int nr, volatile unsigned long * vaddr)
 {
 	__asm__ __volatile__ ("bfset %1@{%0:#1}"
 	     : : "d" (nr^31), "a" (vaddr) : "memory");
@@ -66,7 +68,7 @@
 
 #define __test_and_clear_bit(nr,vaddr) test_and_clear_bit(nr,vaddr)
 
-extern __inline__ int __constant_test_and_clear_bit(int nr, volatile void * vaddr)
+extern __inline__ int __constant_test_and_clear_bit(int nr, volatile unsigned long * vaddr)
 {
 	char retval;
 
@@ -77,7 +79,7 @@
 	return retval;
 }
 
-extern __inline__ int __generic_test_and_clear_bit(int nr, volatile void * vaddr)
+extern __inline__ int __generic_test_and_clear_bit(int nr, volatile unsigned long * vaddr)
 {
 	char retval;
 
@@ -99,13 +101,13 @@
    __generic_clear_bit(nr, vaddr))
 #define __clear_bit(nr,vaddr) clear_bit(nr,vaddr)
 
-extern __inline__ void __constant_clear_bit(int nr, volatile void * vaddr)
+extern __inline__ void __constant_clear_bit(int nr, volatile unsigned long * vaddr)
 {
 	__asm__ __volatile__ ("bclr %1,%0"
 	     : "+m" (((volatile char *)vaddr)[(nr^31) >> 3]) : "di" (nr & 7));
 }
 
-extern __inline__ void __generic_clear_bit(int nr, volatile void * vaddr)
+extern __inline__ void __generic_clear_bit(int nr, volatile unsigned long * vaddr)
 {
 	__asm__ __volatile__ ("bfclr %1@{%0:#1}"
 	     : : "d" (nr^31), "a" (vaddr) : "memory");
@@ -119,7 +121,7 @@
 #define __test_and_change_bit(nr,vaddr) test_and_change_bit(nr,vaddr)
 #define __change_bit(nr,vaddr) change_bit(nr,vaddr)
 
-extern __inline__ int __constant_test_and_change_bit(int nr, volatile void * vaddr)
+extern __inline__ int __constant_test_and_change_bit(int nr, volatile unsigned long * vaddr)
 {
 	char retval;
 
@@ -130,7 +132,7 @@
 	return retval;
 }
 
-extern __inline__ int __generic_test_and_change_bit(int nr, volatile void * vaddr)
+extern __inline__ int __generic_test_and_change_bit(int nr, volatile unsigned long * vaddr)
 {
 	char retval;
 
@@ -145,24 +147,24 @@
    __constant_change_bit(nr, vaddr) : \
    __generic_change_bit(nr, vaddr))
 
-extern __inline__ void __constant_change_bit(int nr, volatile void * vaddr)
+extern __inline__ void __constant_change_bit(int nr, volatile unsigned long * vaddr)
 {
 	__asm__ __volatile__ ("bchg %1,%0"
 	     : "+m" (((volatile char *)vaddr)[(nr^31) >> 3]) : "di" (nr & 7));
 }
 
-extern __inline__ void __generic_change_bit(int nr, volatile void * vaddr)
+extern __inline__ void __generic_change_bit(int nr, volatile unsigned long * vaddr)
 {
 	__asm__ __volatile__ ("bfchg %1@{%0:#1}"
 	     : : "d" (nr^31), "a" (vaddr) : "memory");
 }
 
-extern __inline__ int test_bit(int nr, const volatile void * vaddr)
+extern __inline__ int test_bit(int nr, const volatile unsigned long * vaddr)
 {
-	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) vaddr)[nr >> 5])) != 0;
+	return ((1UL << (nr & 31)) & (((const volatile unsigned long *) vaddr)[nr >> 5])) != 0;
 }
 
-extern __inline__ int find_first_zero_bit(void * vaddr, unsigned size)
+extern __inline__ int find_first_zero_bit(unsigned long * vaddr, unsigned size)
 {
 	unsigned long *p = vaddr, *addr = vaddr;
 	unsigned long allones = ~0UL;
@@ -185,7 +187,7 @@
 	return ((p - addr) << 5) + (res ^ 31);
 }
 
-extern __inline__ int find_next_zero_bit (void *vaddr, int size,
+extern __inline__ int find_next_zero_bit (unsigned long *vaddr, int size,
 				      int offset)
 {
 	unsigned long *addr = vaddr;
@@ -232,16 +234,28 @@
  * differs in spirit from the above ffz (man ffs).
  */
 
-extern __inline__ int ffs(int x)
+static inline int ffs(int x)
 {
 	int cnt;
 
-	__asm__ __volatile__("bfffo %1{#0:#0},%0" : "=d" (cnt) : "dm" (x & -x));
+	asm ("bfffo %1{#0:#0},%0" : "=d" (cnt) : "dm" (x & -x));
 
 	return 32 - cnt;
 }
 #define __ffs(x) (ffs(x) - 1)
 
+/*
+ * fls: find last bit set.
+ */
+
+static inline int fls(int x)
+{
+	int cnt;
+
+	asm ("bfffo %1{#0,#0},%0" : "=d" (cnt) : "dm" (x));
+
+	return 32 - cnt;
+}
 
 /*
  * Every architecture must define this function. It's the fastest
diff -Nru a/include/asm-m68k/cache.h b/include/asm-m68k/cache.h
--- a/include/asm-m68k/cache.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/cache.h	Wed Jul 24 14:03:38 2002
@@ -5,6 +5,7 @@
 #define __ARCH_M68K_CACHE_H
 
 /* bytes per L1 cache line */
-#define        L1_CACHE_BYTES  16
+#define        L1_CACHE_SHIFT  4
+#define        L1_CACHE_BYTES  (1<< L1_CACHE_SHIFT)
 
 #endif
diff -Nru a/include/asm-m68k/cacheflush.h b/include/asm-m68k/cacheflush.h
--- a/include/asm-m68k/cacheflush.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/cacheflush.h	Wed Jul 24 14:03:38 2002
@@ -1,6 +1,8 @@
 #ifndef _M68K_CACHEFLUSH_H
 #define _M68K_CACHEFLUSH_H
 
+#include <linux/mm.h>
+
 /*
  * Cache handling functions
  */
@@ -104,15 +106,15 @@
 
 /* Push the page at kernel virtual address and clear the icache */
 /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
-#define flush_page_to_ram(page) __flush_page_to_ram((unsigned long) page_address(page))
-extern inline void __flush_page_to_ram(unsigned long address)
+#define flush_page_to_ram(page) __flush_page_to_ram(page_address(page))
+extern inline void __flush_page_to_ram(void *vaddr)
 {
 	if (CPU_IS_040_OR_060) {
 		__asm__ __volatile__("nop\n\t"
 				     ".chip 68040\n\t"
 				     "cpushp %%bc,(%0)\n\t"
 				     ".chip 68k"
-				     : : "a" (__pa((void *)address)));
+				     : : "a" (__pa(vaddr)));
 	} else {
 		unsigned long _tmp;
 		__asm__ __volatile__("movec %%cacr,%0\n\t"
diff -Nru a/include/asm-m68k/entry.h b/include/asm-m68k/entry.h
--- a/include/asm-m68k/entry.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-m68k/entry.h	Wed Jul 24 14:03:39 2002
@@ -111,6 +111,7 @@
 	movel	%sp,\reg
 	andw	#-THREAD_SIZE,\reg
 	movel	\reg,%curptr
+	movel	%curptr@,%curptr
 .endm
 
 #else /* C source */
diff -Nru a/include/asm-m68k/hw_irq.h b/include/asm-m68k/hw_irq.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68k/hw_irq.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_M68K_HW_IRQ_H
+#define __ASM_M68K_HW_IRQ_H
+
+/* Dummy include. */
+
+#endif
diff -Nru a/include/asm-m68k/io.h b/include/asm-m68k/io.h
--- a/include/asm-m68k/io.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-m68k/io.h	Wed Jul 24 14:03:35 2002
@@ -240,7 +240,7 @@
 #define readb   isa_readb
 #define readw   isa_readw
 #define writeb  isa_writeb
-#define writew  isa_writeb
+#define writew  isa_writew
 #endif /* CONFIG_ISA */
 
 #if defined(CONFIG_PCI)
diff -Nru a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h
--- a/include/asm-m68k/irq.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/irq.h	Wed Jul 24 14:03:38 2002
@@ -73,6 +73,8 @@
 #define disable_irq_nosync	disable_irq
 #define enable_irq_nosync	enable_irq
 
+struct pt_regs;
+
 extern int sys_request_irq(unsigned int, 
 	void (*)(int, void *, struct pt_regs *), 
 	unsigned long, const char *, void *);
@@ -83,7 +85,7 @@
  * mechanism like all other architectures - SA_INTERRUPT and SA_SHIRQ
  * are your friends.
  */
-#ifndef CONFIG_AMIGA
+#ifndef MACH_AMIGA_ONLY
 #define IRQ_FLG_LOCK	(0x0001)	/* handler is not replaceable	*/
 #define IRQ_FLG_REPLACE	(0x0002)	/* replace existing handler	*/
 #define IRQ_FLG_FAST	(0x0004)
diff -Nru a/include/asm-m68k/machw.h b/include/asm-m68k/machw.h
--- a/include/asm-m68k/machw.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-m68k/machw.h	Wed Jul 24 14:03:37 2002
@@ -68,11 +68,11 @@
 
 /* hardware stuff */
 
-#define MACHW_DECLARE(name)    unsigned name : 1
-#define MACHW_SET(name)                (mac_hw_present.name = 1)
-#define MACHW_PRESENT(name)    (mac_hw_present.name)
+#define MACHW_DECLARE(name)	unsigned name : 1
+#define MACHW_SET(name)		(mac_hw_present.name = 1)
+#define MACHW_PRESENT(name)	(mac_hw_present.name)
 
-struct {
+struct mac_hw_present {
   /* video hardware */
   /* sound hardware */
   /* disk storage interfaces */
@@ -92,9 +92,9 @@
   MACHW_DECLARE(RBV);             /* Versatile Interface Ad. 2+ */
   /* NUBUS */
   MACHW_DECLARE(NUBUS);           /* NUBUS */
-} mac_hw_present;
+};
 
-/* extern struct mac_hw_present mac_hw_present; */
+extern struct mac_hw_present mac_hw_present;
 
 #endif /* __ASSEMBLY__ */
 
diff -Nru a/include/asm-m68k/macintosh.h b/include/asm-m68k/macintosh.h
--- a/include/asm-m68k/macintosh.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-m68k/macintosh.h	Wed Jul 24 14:03:35 2002
@@ -39,9 +39,6 @@
  *	Macintosh Table
  */
  
-struct mac_model *macintosh_config;
-
-
 struct mac_model
 {
 	short ident;
diff -Nru a/include/asm-m68k/mman.h b/include/asm-m68k/mman.h
--- a/include/asm-m68k/mman.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-m68k/mman.h	Wed Jul 24 14:03:36 2002
@@ -4,6 +4,7 @@
 #define PROT_READ	0x1		/* page can be read */
 #define PROT_WRITE	0x2		/* page can be written */
 #define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_SEM	0x8		/* page may be used for atomic ops */
 #define PROT_NONE	0x0		/* page can not be accessed */
 
 #define MAP_SHARED	0x01		/* Share changes */
diff -Nru a/include/asm-m68k/motorola_pgalloc.h b/include/asm-m68k/motorola_pgalloc.h
--- a/include/asm-m68k/motorola_pgalloc.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-m68k/motorola_pgalloc.h	Wed Jul 24 14:03:39 2002
@@ -14,9 +14,9 @@
 	pte = (pte_t *) __get_free_page(GFP_KERNEL);
 	if (pte) {
 		clear_page(pte);
-		__flush_page_to_ram((unsigned long)pte);
-		flush_tlb_kernel_page((unsigned long)pte);
-		nocache_page((unsigned long)pte);
+		__flush_page_to_ram(pte);
+		flush_tlb_kernel_page(pte);
+		nocache_page(pte);
 	}
 
 	return pte;
@@ -24,7 +24,7 @@
 
 static inline void pte_free_kernel(pte_t *pte)
 {
-	cache_page((unsigned long)pte);
+	cache_page(pte);
 	free_page((unsigned long) pte);
 }
 
@@ -39,9 +39,9 @@
 	pte = kmap(page);
 	if (pte) {
 		clear_page(pte);
-		__flush_page_to_ram((unsigned long)pte);
-		flush_tlb_kernel_page((unsigned long)pte);
-		nocache_page((unsigned long)pte);
+		__flush_page_to_ram(pte);
+		flush_tlb_kernel_page(pte);
+		nocache_page(pte);
 	}
 	kunmap(pte);
 
@@ -50,14 +50,14 @@
 
 static inline void pte_free(struct page *page)
 {
-	cache_page((unsigned long)kmap(page));
+	cache_page(kmap(page));
 	kunmap(page);
 	__free_page(page);
 }
 
 static inline void pte_free_tlb(mmu_gather_t *tlb, struct page *page)
 {
-	cache_page((unsigned long)kmap(page));
+	cache_page(kmap(page));
 	kunmap(page);
 	__free_page(page);
 }
@@ -104,8 +104,5 @@
 {
 	pgd_set(pgd, pmd);
 }
-
-
-#define check_pgt_cache()	do { } while (0)
 
 #endif /* _MOTOROLA_PGALLOC_H */
diff -Nru a/include/asm-m68k/motorola_pgtable.h b/include/asm-m68k/motorola_pgtable.h
--- a/include/asm-m68k/motorola_pgtable.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-m68k/motorola_pgtable.h	Wed Jul 24 14:03:35 2002
@@ -93,21 +93,7 @@
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-#define __mk_pte(page, pgprot) \
-({									\
-	pte_t __pte;							\
-									\
-	pte_val(__pte) = __pa(page) + pgprot_val(pgprot);	        \
-	__pte;								\
-})
-#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot))
-#define mk_pte_phys(physpage, pgprot) \
-({									\
-	pte_t __pte;							\
-									\
-	pte_val(__pte) = (physpage) + pgprot_val(pgprot);		\
-	__pte;								\
-})
+#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
 
 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
@@ -134,7 +120,10 @@
 #define pte_none(pte)		(!pte_val(pte))
 #define pte_present(pte)	(pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER))
 #define pte_clear(ptep)		({ pte_val(*(ptep)) = 0; })
-#define pte_pagenr(pte)		((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
+
+#define pte_page(pte)		(mem_map + ((unsigned long)(__va(pte_val(pte)) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
+#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 
 #define pmd_none(pmd)		(!pmd_val(pmd))
 #define pmd_bad(pmd)		((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE)
@@ -145,16 +134,13 @@
 	while (--__i >= 0)			\
 		*__ptr++ = 0;			\
 })
+#define pmd_page(pmd)		(mem_map + ((unsigned long)(__va(pmd_val(pmd)) - PAGE_OFFSET) >> PAGE_SHIFT))
 
 
 #define pgd_none(pgd)		(!pgd_val(pgd))
 #define pgd_bad(pgd)		((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE)
 #define pgd_present(pgd)	(pgd_val(pgd) & _PAGE_TABLE)
 #define pgd_clear(pgdp)		({ pgd_val(*pgdp) = 0; })
-/* Permanent address of a page. */
-#define page_address(page)	({ if (!(page)->virtual) BUG(); (page)->virtual; })
-#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define pte_page(pte)		(mem_map+pte_pagenr(pte))
 
 #define pte_ERROR(e) \
 	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
@@ -217,11 +203,15 @@
 }
 
 /* Find an entry in the third-level page table.. */ 
-extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address)
+extern inline pte_t * pte_offset_kernel(pmd_t * pmdp, unsigned long address)
 {
 	return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 }
 
+#define pte_offset_map(pmdp,address) ((pte_t *)kmap(pmd_page(*pmdp)) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+#define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address)
+#define pte_unmap(pte) kunmap(pte)
+#define pte_unmap_nested(pte) kunmap(pte)
 
 /*
  * Allocate and free page tables. The xxx_kernel() versions are
@@ -233,30 +223,34 @@
  * from both the cache and ATC, or the CPU might not notice that the
  * cache setting for the page has been changed. -jskov
  */
-static inline void nocache_page (unsigned long vaddr)
+static inline void nocache_page(void *vaddr)
 {
+	unsigned long addr = (unsigned long)vaddr;
+
 	if (CPU_IS_040_OR_060) {
 		pgd_t *dir;
 		pmd_t *pmdp;
 		pte_t *ptep;
 
-		dir = pgd_offset_k(vaddr);
-		pmdp = pmd_offset(dir,vaddr);
-		ptep = pte_offset(pmdp,vaddr);
+		dir = pgd_offset_k(addr);
+		pmdp = pmd_offset(dir, addr);
+		ptep = pte_offset_kernel(pmdp, addr);
 		*ptep = pte_mknocache(*ptep);
 	}
 }
 
-static inline void cache_page (unsigned long vaddr)
+static inline void cache_page(void *vaddr)
 {
+	unsigned long addr = (unsigned long)vaddr;
+
 	if (CPU_IS_040_OR_060) {
 		pgd_t *dir;
 		pmd_t *pmdp;
 		pte_t *ptep;
 
-		dir = pgd_offset_k(vaddr);
-		pmdp = pmd_offset(dir,vaddr);
-		ptep = pte_offset(pmdp,vaddr);
+		dir = pgd_offset_k(addr);
+		pmdp = pmd_offset(dir, addr);
+		ptep = pte_offset_kernel(pmdp, addr);
 		*ptep = pte_mkcache(*ptep);
 	}
 }
diff -Nru a/include/asm-m68k/nubus.h b/include/asm-m68k/nubus.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68k/nubus.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,46 @@
+#ifndef _ASM_M68K_NUBUS_H
+#define _ASM_M68K_NUBUS_H
+
+#include <asm/io.h>
+
+#define nubus_readb raw_inb
+#define nubus_readw raw_inw
+#define nubus_readl raw_inl
+
+#define nubus_writeb raw_outb
+#define nubus_writew raw_outw
+#define nubus_writel raw_outl
+
+#define nubus_memset_io(a,b,c)		memset((void *)(a),(b),(c))
+#define nubus_memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define nubus_memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+extern inline void *nubus_remap_nocache_ser(unsigned long physaddr,
+					    unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+
+extern inline void *nubus_remap_nocache_nonser(unsigned long physaddr,
+					       unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_NONSER);
+}
+
+extern inline void *nbus_remap_writethrough(unsigned long physaddr,
+					    unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+
+extern inline void *nubus_remap_fullcache(unsigned long physaddr,
+					  unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+#define nubus_unmap iounmap
+#define nubus_iounmap iounmap
+#define nubus_ioremap nubus_remap_nocache_ser
+
+#endif /* _ASM_NUBUS_H */
diff -Nru a/include/asm-m68k/page.h b/include/asm-m68k/page.h
--- a/include/asm-m68k/page.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/page.h	Wed Jul 24 14:03:38 2002
@@ -76,8 +76,8 @@
 #define copy_page(to,from)	memcpy((to), (from), PAGE_SIZE)
 #endif
 
-#define clear_user_page(page, vaddr)	clear_page(page)
-#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+#define clear_user_page(page, vaddr, pg)	clear_page(page)
+#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
 /*
  * These are used to make use of C type-checking..
@@ -159,10 +159,25 @@
 }
 #endif	/* CONFIG_SUN3 */
 
-#define MAP_NR(addr)		(((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
+/*
+ * NOTE: virtual isn't really correct, actually it should be the offset into the
+ * memory node, but we have no highmem, so that works for now.
+ * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots
+ * of the shifts unneccessary.
+ */
+#define virt_to_pfn(kaddr)	(__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_to_virt(pfn)	__va((pfn) << PAGE_SHIFT)
+
 #define virt_to_page(kaddr)	(mem_map + (((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT))
-#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+#define page_to_virt(page)	((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
+
+#define pfn_to_page(pfn)	virt_to_page(pfn_to_virt(pfn))
+#define page_to_pfn(page)	virt_to_pfn(page_to_virt(page))
+
+#define virt_addr_valid(kaddr)	((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
+#define pfn_valid(pfn)		virt_addr_valid(pfn_to_virt(pfn))
 
+#ifdef CONFIG_DEBUG_BUGVERBOSE
 #ifndef CONFIG_SUN3
 #define BUG() do { \
 	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
@@ -172,6 +187,11 @@
 #define BUG() do { \
 	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
 	panic("BUG!"); \
+} while (0)
+#endif
+#else
+#define BUG() do { \
+	asm volatile("illegal"); \
 } while (0)
 #endif
 
diff -Nru a/include/asm-m68k/param.h b/include/asm-m68k/param.h
--- a/include/asm-m68k/param.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/param.h	Wed Jul 24 14:03:38 2002
@@ -1,6 +1,12 @@
 #ifndef _M68K_PARAM_H
 #define _M68K_PARAM_H
 
+#ifdef __KERNEL__
+# define HZ		100		/* Internal kernel timer frequency */
+# define USER_HZ	100		/* .. some user interfaces are in "ticks" */
+# define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
+#endif
+
 #ifndef HZ
 #define HZ 100
 #endif
@@ -16,9 +22,5 @@
 #endif
 
 #define MAXHOSTNAMELEN	64	/* max length of hostname */
-
-#ifdef __KERNEL__
-# define CLOCKS_PER_SEC	HZ	/* frequency at which times() counts */
-#endif
 
 #endif /* _M68K_PARAM_H */
diff -Nru a/include/asm-m68k/pci.h b/include/asm-m68k/pci.h
--- a/include/asm-m68k/pci.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/pci.h	Wed Jul 24 14:03:38 2002
@@ -48,4 +48,10 @@
 /* Return the index of the PCI controller for device PDEV. */
 #define pci_controller_num(PDEV)	(0)
 
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
 #endif /* _ASM_M68K_PCI_H */
diff -Nru a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
--- a/include/asm-m68k/pgtable.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-m68k/pgtable.h	Wed Jul 24 14:03:39 2002
@@ -6,6 +6,7 @@
 
 #ifndef __ASSEMBLY__
 #include <asm/processor.h>
+#include <linux/sched.h>
 #include <linux/threads.h>
 
 /*
@@ -88,20 +89,12 @@
 #endif /* CONFIG_SUN3 */
 
 /* zero page used for uninitialized stuff */
-extern unsigned long empty_zero_page;
+extern void *empty_zero_page;
 
 /*
- * BAD_PAGETABLE is used when we need a bogus page-table, while
- * BAD_PAGE is used for a bogus page.
- *
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
  */
-extern pte_t __bad_page(void);
-extern pte_t * __bad_pagetable(void);
-
-#define BAD_PAGETABLE __bad_pagetable()
-#define BAD_PAGE __bad_page()
 #define ZERO_PAGE(vaddr)	(virt_to_page(empty_zero_page))
 
 /* number of bits that fit into a memory pointer */
@@ -184,5 +177,7 @@
  * No page table caches to initialise
  */
 #define pgtable_cache_init()	do { } while (0)
+
+#define check_pgt_cache()	do { } while (0)
 
 #endif /* _M68K_PGTABLE_H */
diff -Nru a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h
--- a/include/asm-m68k/processor.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-m68k/processor.h	Wed Jul 24 14:03:39 2002
@@ -59,11 +59,16 @@
 #define EISA_bus 0
 #define MCA_bus 0
 
-/* 
- * if you change this structure, you must change the code and offsets
- * in m68k/machasm.S
- */
-   
+struct task_work {
+	unsigned char sigpending;
+	unsigned char notify_resume;	/* request for notification on
+					   userspace execution resumption */
+	char          need_resched;
+	unsigned char delayed_trace;	/* single step a syscall */
+	unsigned char syscall_trace;	/* count of syscall interceptors */
+	unsigned char pad[3];
+};
+
 struct thread_struct {
 	unsigned long  ksp;		/* kernel stack pointer */
 	unsigned long  usp;		/* user stack pointer */
@@ -76,11 +81,13 @@
 	unsigned long  fp[8*3];
 	unsigned long  fpcntl[3];	/* fp control regs */
 	unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
+	struct task_work work;
 };
 
-#define INIT_THREAD  { \
-	sizeof(init_stack) + (unsigned long) init_stack, 0, \
-	PS_S, __KERNEL_DS, \
+#define INIT_THREAD  {						\
+	ksp: sizeof(init_stack) + (unsigned long) init_stack,	\
+	sr: PS_S, 						\
+	fs: __KERNEL_DS,					\
 }
 
 /*
@@ -117,21 +124,7 @@
 {
 }
 
-/*
- * Return saved PC of a blocked thread.
- */
-extern inline unsigned long thread_saved_pc(struct thread_struct *t)
-{
-	extern void scheduling_functions_start_here(void);
-	extern void scheduling_functions_end_here(void);
-	struct switch_stack *sw = (struct switch_stack *)t->ksp;
-	/* Check whether the thread is blocked in resume() */
-	if (sw->retpc > (unsigned long)scheduling_functions_start_here &&
-	    sw->retpc < (unsigned long)scheduling_functions_end_here)
-		return ((unsigned long *)sw->a6)[1];
-	else
-		return sw->retpc;
-}
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
 
 unsigned long get_wchan(struct task_struct *p);
 
@@ -143,17 +136,6 @@
 	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
 	eip; })
 #define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
-
-#define THREAD_SIZE (2*PAGE_SIZE)
-
-/* Allocation and freeing of basic task resources. */
-#define alloc_task_struct() \
-	((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
-#define free_task_struct(p)	free_pages((unsigned long)(p),1)
-#define get_task_struct(tsk)      atomic_inc(&virt_to_page(tsk)->count)
-
-#define init_task	(init_task_union.task)
-#define init_stack	(init_task_union.stack)
 
 #define cpu_relax()	do { } while (0)
 
diff -Nru a/include/asm-m68k/q40_keyboard.h b/include/asm-m68k/q40_keyboard.h
--- a/include/asm-m68k/q40_keyboard.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-m68k/q40_keyboard.h	Wed Jul 24 14:03:39 2002
@@ -20,7 +20,7 @@
 extern char q40kbd_unexpected_up(unsigned char keycode);
 extern void q40kbd_leds(unsigned char leds);
 extern int q40kbd_is_sysrq(unsigned char keycode);
-extern void q40kbd_init_hw(void);
+extern int q40kbd_init_hw(void);
 extern unsigned char q40kbd_sysrq_xlate[128];
 
 
diff -Nru a/include/asm-m68k/raw_io.h b/include/asm-m68k/raw_io.h
--- a/include/asm-m68k/raw_io.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/raw_io.h	Wed Jul 24 14:03:38 2002
@@ -20,10 +20,16 @@
     ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
 #define in_be32(addr) \
     ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+#define in_le16(addr) \
+    ({ unsigned short __v = le16_to_cpu(*(volatile unsigned short *) (addr)); __v; })
+#define in_le32(addr) \
+    ({ unsigned int __v = le32_to_cpu(*(volatile unsigned int *) (addr)); __v; })
 
 #define out_8(addr,b) (void)((*(volatile unsigned char *) (addr)) = (b))
-#define out_be16(addr,b) (void)((*(volatile unsigned short *) (addr)) = (b))
-#define out_be32(addr,b) (void)((*(volatile unsigned int *) (addr)) = (b))
+#define out_be16(addr,w) (void)((*(volatile unsigned short *) (addr)) = (w))
+#define out_be32(addr,l) (void)((*(volatile unsigned int *) (addr)) = (l))
+#define out_le16(addr,w) (void)((*(volatile unsigned short *) (addr)) = cpu_to_le16(w))
+#define out_le32(addr,l) (void)((*(volatile unsigned int *) (addr)) = cpu_to_le32(l))
 
 #define raw_inb in_8
 #define raw_inw in_be16
diff -Nru a/include/asm-m68k/scatterlist.h b/include/asm-m68k/scatterlist.h
--- a/include/asm-m68k/scatterlist.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/scatterlist.h	Wed Jul 24 14:03:38 2002
@@ -2,17 +2,15 @@
 #define _M68K_SCATTERLIST_H
 
 struct scatterlist {
-    struct page *page;
-    unsigned int offset;
-    unsigned int length;
-    unsigned long dvma_address;
-};
+	/* These two are only valid if ADDRESS member of this
+	 * struct is NULL.
+	 */
+	struct page *page;
+	unsigned int offset;
 
-struct mmu_sglist {
-        char *addr;
-        char *__dont_touch;
-        unsigned int len;
-        unsigned long dvma_addr;
+	unsigned int length;
+
+	__u32 dvma_address; /* A place to hang host-specific addresses at. */
 };
 
 /* This is bogus and should go away. */
diff -Nru a/include/asm-m68k/semaphore-helper.h b/include/asm-m68k/semaphore-helper.h
--- a/include/asm-m68k/semaphore-helper.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/semaphore-helper.h	Wed Jul 24 14:03:38 2002
@@ -10,6 +10,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/errno.h>
 
 /*
  * These two _must_ execute atomically wrt each other.
diff -Nru a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h
--- a/include/asm-m68k/serial.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-m68k/serial.h	Wed Jul 24 14:03:37 2002
@@ -2,7 +2,7 @@
  * include/asm-m68k/serial.h
  *
  * currently this seems useful only for a Q40,
- * its an almost exact copy of ../asm-alpha/serial.h 
+ * it's an almost exact copy of ../asm-alpha/serial.h 
  *
  */
 
diff -Nru a/include/asm-m68k/smplock.h b/include/asm-m68k/smplock.h
--- a/include/asm-m68k/smplock.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-m68k/smplock.h	Wed Jul 24 14:03:37 2002
@@ -18,7 +18,7 @@
 	if (task->lock_depth >= 0) \
 		spin_unlock(&kernel_flag); \
 	release_irqlock(cpu); \
-	__sti(); \
+	local_irq_enable(); \
 } while (0)
 
 /*
diff -Nru a/include/asm-m68k/sun3_pgtable.h b/include/asm-m68k/sun3_pgtable.h
--- a/include/asm-m68k/sun3_pgtable.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-m68k/sun3_pgtable.h	Wed Jul 24 14:03:39 2002
@@ -99,11 +99,8 @@
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-#define __mk_pte(page, pgprot) \
-({ pte_t __pte; pte_val(__pte) = (__pa(page) >> PAGE_SHIFT) | pgprot_val(pgprot); __pte; })
-#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot))
-#define mk_pte_phys(physpage, pgprot) \
-({ pte_t __pte; pte_val(__pte) = ((physpage) >> PAGE_SHIFT) | pgprot_val(pgprot); __pte; })
+#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+
 extern inline pte_t pte_modify (pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & SUN3_PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
 
@@ -121,12 +118,12 @@
 extern inline int pte_present (pte_t pte) { return pte_val (pte) & SUN3_PAGE_VALID; }
 extern inline void pte_clear (pte_t *ptep) { pte_val (*ptep) = 0; }
 
-/* FIXME: this is only a guess */
-#define pte_pagenr(pte)		((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
-/* Permanent address of a page. */
-#define page_address(page)	({ if (!(page)->virtual) BUG(); (page)->virtual; })
-#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define pte_page(pte)		(mem_map+pte_pagenr(pte))
+#define pte_pfn(pte)            (pte_val(pte) & SUN3_PAGE_PGNUM_MASK)
+#define pfn_pte(pfn, pgprot) \
+({ pte_t __pte; pte_val(__pte) = pfn | pgprot_val(pgprot); __pte; })
+
+#define pte_page(pte)		(mem_map+((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pmd_page(pmd)		(mem_map+((__pmd_page(pmd) - PAGE_OFFSET) >> PAGE_SHIFT))
 
 
 extern inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); }
@@ -199,21 +196,13 @@
 }
 
 /* Find an entry in the third-level pagetable. */
-#define pte_offset(pmd, address) \
-((pte_t *) __pmd_page (*pmd) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1)))
-
-/* Disable caching for page at given kernel virtual address. */
-static inline void nocache_page (unsigned long vaddr)
-{
-	/* Don't think this is required on sun3. --m */
-}
-
-/* Enable caching for page at given kernel virtual address. */
-static inline void cache_page (unsigned long vaddr)
-{
-	/* Don't think this is required on sun3. --m */
-}
-
+#define __pte_offset(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
+#define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + __pte_offset(address))
+/* FIXME: should we bother with kmap() here? */
+#define pte_offset_map(pmd, address) ((pte_t *)kmap(pmd_page(*pmd)) + __pte_offset(address))
+#define pte_offset_map_nested(pmd, address) pte_offset_map(pmd, address)
+#define pte_unmap(pte) kunmap(pte)
+#define pte_unmap_nested(pte) kunmap(pte)
 
 
 #endif	/* !__ASSEMBLY__ */
diff -Nru a/include/asm-m68k/suspend.h b/include/asm-m68k/suspend.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68k/suspend.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,6 @@
+#ifndef _M68K_SUSPEND_H
+#define _M68K_SUSPEND_H
+
+/* Dummy include. */
+
+#endif  /* _M68K_SUSPEND_H */
diff -Nru a/include/asm-m68k/system.h b/include/asm-m68k/system.h
--- a/include/asm-m68k/system.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-m68k/system.h	Wed Jul 24 14:03:36 2002
@@ -7,7 +7,10 @@
 #include <asm/segment.h>
 #include <asm/entry.h>
 
-#define prepare_to_switch()	do { } while(0)
+#define prepare_arch_schedule(prev)		do { } while(0)
+#define finish_arch_schedule(prev)		do { } while(0)
+#define prepare_arch_switch(rq)			do { } while(0)
+#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
 
 /*
  * switch_to(n) should switch tasks to task ptr, first checking that
@@ -32,45 +35,39 @@
  * 02/17/96 - Jes Sorensen (jds@kom.auc.dk)
  *
  * Changed 96/09/19 by Andreas Schwab
- * pass prev in a0, next in a1, offset of tss in d1, and whether
- * the mm structures are shared in d2 (to avoid atc flushing).
+ * pass prev in a0, next in a1
  */
 asmlinkage void resume(void);
-#define switch_to(prev,next,last) { \
+#define switch_to(prev,next,last) do { \
   register void *_prev __asm__ ("a0") = (prev); \
   register void *_next __asm__ ("a1") = (next); \
-  register void *_last __asm__ ("d1"); \
   __asm__ __volatile__("jbsr resume" \
-		       : "=d" (_last) : "a" (_prev), "a" (_next) \
-		       : "d0", /* "d1", */ "d2", "d3", "d4", "d5", "a0", "a1"); \
-  (last) = _last; \
-}
+		       : : "a" (_prev), "a" (_next) \
+		       : "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1"); \
+} while (0)
 
 
 /* interrupt control.. */
 #if 0
-#define __sti() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
+#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
 #else
 #include <asm/hardirq.h>
-#define __sti() ({							      \
+#define local_irq_enable() ({							      \
 	if (MACH_IS_Q40 || !local_irq_count(smp_processor_id()))              \
 		asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory");  \
 })
 #endif
-#define __cli() asm volatile ("oriw  #0x0700,%%sr": : : "memory")
-#define __save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
-#define __restore_flags(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
+#define local_irq_disable() asm volatile ("oriw  #0x0700,%%sr": : : "memory")
+#define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
+#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
 
 /* For spinlocks etc */
-#define local_irq_save(x)	({ __save_flags(x); __cli(); })
-#define local_irq_restore(x)	__restore_flags(x)
-#define local_irq_disable()	__cli()
-#define local_irq_enable()	__sti()
+#define local_irq_save(x)	({ local_save_flags(x); local_irq_disable(); })
 
-#define cli()			__cli()
-#define sti()			__sti()
-#define save_flags(x)		__save_flags(x)
-#define restore_flags(x)	__restore_flags(x)
+#define cli()			local_irq_disable()
+#define sti()			local_irq_enable()
+#define save_flags(x)		local_save_flags(x)
+#define restore_flags(x)	local_irq_restore(x)
 #define save_and_cli(flags)   do { save_flags(flags); cli(); } while(0)
 
 /*
diff -Nru a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68k/thread_info.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,101 @@
+#ifndef _ASM_M68K_THREAD_INFO_H
+#define _ASM_M68K_THREAD_INFO_H
+
+#include <asm/types.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+struct thread_info {
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain	*exec_domain;	/* execution domain */
+	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
+	__u32 cpu; /* should always be 0 on m68k */
+
+	__u8			supervisor_stack[0];
+};
+
+#define PREEMPT_ACTIVE		0x4000000
+
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	task:		&tsk,			\
+	exec_domain:	&default_exec_domain,	\
+}
+
+/* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */
+#if PAGE_SHIFT == 13 /* 8k machines */
+#define alloc_thread_info()   ((struct thread_info *)__get_free_pages(GFP_KERNEL,0))
+#define free_thread_info(ti)  free_pages((unsigned long)(ti),0)
+#else /* otherwise assume 4k pages */
+#define alloc_thread_info()   ((struct thread_info *)__get_free_pages(GFP_KERNEL,1))
+#define free_thread_info(ti)  free_pages((unsigned long)(ti),1)
+#endif /* PAGE_SHIFT == 13 */
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+#define current_thread_info()	(current->thread_info)
+
+
+#define __HAVE_THREAD_FUNCTIONS
+
+#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_DELAYED_TRACE	1	/* single step a syscall */
+#define TIF_NOTIFY_RESUME	2	/* resumption notification requested */
+#define TIF_SIGPENDING		3	/* signal pending */
+#define TIF_NEED_RESCHED	4	/* rescheduling necessary */
+
+extern int thread_flag_fixme(void);
+
+/*
+ * flag set/clear/test wrappers
+ * - pass TIF_xxxx constants to these functions
+ */
+
+#define __set_tsk_thread_flag(tsk, flag, val) ({ 	\
+	switch (flag) {					\
+	case TIF_SIGPENDING:				\
+		tsk->thread.work.sigpending = val;	\
+		break;					\
+	case TIF_NEED_RESCHED:				\
+		tsk->thread.work.need_resched = val;	\
+		break;					\
+	default:					\
+		thread_flag_fixme();			\
+	}						\
+})
+
+#define __get_tsk_thread_flag(tsk, flag) ({		\
+	int ___res;					\
+	switch (flag) {					\
+	case TIF_SIGPENDING:				\
+		___res = tsk->thread.work.sigpending;	\
+		break;					\
+	case TIF_NEED_RESCHED:				\
+		___res = tsk->thread.work.need_resched;	\
+		break;					\
+	default:					\
+		___res = thread_flag_fixme();		\
+	}						\
+	___res;						\
+})
+
+#define __get_set_tsk_thread_flag(tsk, flag, val) ({	\
+	int __res = __get_tsk_thread_flag(tsk, flag);	\
+	__set_tsk_thread_flag(tsk, flag, val);		\
+	__res;						\
+})
+
+#define set_tsk_thread_flag(tsk, flag) __set_tsk_thread_flag(tsk, flag, ~0)
+#define clear_tsk_thread_flag(tsk, flag) __set_tsk_thread_flag(tsk, flag, 0)
+#define test_and_set_tsk_thread_flag(tsk, flag) __get_set_tsk_thread_flag(tsk, flag, ~0)
+#define test_tsk_thread_flag(tsk, flag) __get_tsk_thread_flag(tsk, flag)
+
+#define set_thread_flag(flag) set_tsk_thread_flag(current, flag)
+#define clear_thread_flag(flag) clear_tsk_thread_flag(current, flag)
+#define test_thread_flag(flag) test_tsk_thread_flag(current, flag)
+
+#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED)
+#define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED)
+
+#endif	/* _ASM_M68K_THREAD_INFO_H */
diff -Nru a/include/asm-m68k/tlb.h b/include/asm-m68k/tlb.h
--- a/include/asm-m68k/tlb.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-m68k/tlb.h	Wed Jul 24 14:03:39 2002
@@ -7,7 +7,7 @@
  */
 #define tlb_start_vma(tlb, vma)	do { } while (0)
 #define tlb_end_vma(tlb, vma)	do { } while (0)
-#define tlb_remove_tlb_entry(tlb, pte, address)	do { } while (0)
+#define tlb_remove_tlb_entry(tlb, ptep, address)	do { } while (0)
 
 /*
  * .. because we flush the whole mm when it
diff -Nru a/include/asm-m68k/tlbflush.h b/include/asm-m68k/tlbflush.h
--- a/include/asm-m68k/tlbflush.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-m68k/tlbflush.h	Wed Jul 24 14:03:36 2002
@@ -3,7 +3,9 @@
 
 #ifndef CONFIG_SUN3
 
-extern inline void flush_tlb_kernel_page(unsigned long addr)
+#include <asm/current.h>
+
+static inline void flush_tlb_kernel_page(void *addr)
 {
 	if (CPU_IS_040_OR_060) {
 		mm_segment_t old_fs = get_fs();
@@ -91,6 +93,13 @@
 }
 
 #else
+
+
+/* Reserved PMEGs. */
+extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
+extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
 
 /* Flush all userspace mappings one by one...  (why no flush command,
    sun?) */
diff -Nru a/include/asm-m68k/types.h b/include/asm-m68k/types.h
--- a/include/asm-m68k/types.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-m68k/types.h	Wed Jul 24 14:03:35 2002
@@ -49,9 +49,10 @@
 
 #define BITS_PER_LONG 32
 
-/* DMA addresses are 32-bits wide */
+/* DMA addresses are always 32-bits wide */
 
 typedef u32 dma_addr_t;
+typedef u32 dma64_addr_t;
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
--- a/include/asm-m68k/unistd.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-m68k/unistd.h	Wed Jul 24 14:03:38 2002
@@ -221,9 +221,23 @@
 #define __NR_setgid32		214
 #define __NR_setfsuid32		215
 #define __NR_setfsgid32		216
+#define __NR_pivot_root		217
 #define __NR_getdents64		220
 #define __NR_gettid		221
 #define __NR_tkill		222
+#define __NR_setxattr		223
+#define __NR_lsetxattr		224
+#define __NR_fsetxattr		225
+#define __NR_getxattr		226
+#define __NR_lgetxattr		227
+#define __NR_fgetxattr		228
+#define __NR_listxattr		229
+#define __NR_llistxattr		230
+#define __NR_flistxattr		231
+#define __NR_removexattr	232
+#define __NR_lremovexattr	233
+#define __NR_fremovexattr	234
+#define __NR_futex		235
 
 /* user-visible error numbers are in the range -1 - -122: see
    <asm-m68k/errno.h> */
diff -Nru a/include/asm-m68k/virtconvert.h b/include/asm-m68k/virtconvert.h
--- a/include/asm-m68k/virtconvert.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-m68k/virtconvert.h	Wed Jul 24 14:03:39 2002
@@ -73,6 +73,10 @@
 }
 #endif
 
+/* Permanent address of a page. */
+#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+
 /*
  * IO bus memory addresses are 1:1 with the physical address,
  * except on the PCI bus of the Hades.
diff -Nru a/include/asm-m68k/zorro.h b/include/asm-m68k/zorro.h
--- a/include/asm-m68k/zorro.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-m68k/zorro.h	Wed Jul 24 14:03:36 2002
@@ -1,6 +1,7 @@
 #ifndef _ASM_M68K_ZORRO_H
 #define _ASM_M68K_ZORRO_H
-#include <asm/raw_io.h>
+
+#include <asm/io.h>
 
 #define z_readb raw_inb
 #define z_readw raw_inw
@@ -13,22 +14,6 @@
 #define z_memset_io(a,b,c)	memset((void *)(a),(b),(c))
 #define z_memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
 #define z_memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
-
-
-/* Values for nocacheflag and cmode */
-#ifndef IOMAP_FULL_CACHING		
-#define IOMAP_FULL_CACHING		0
-#define IOMAP_NOCACHE_SER		1
-#define IOMAP_NOCACHE_NONSER		2
-#define IOMAP_WRITETHROUGH		3
-#endif
-
-extern void iounmap(void *addr);
-
-extern void *__ioremap(unsigned long physaddr, unsigned long size,
-		       int cacheflag);
-extern void __iounmap(void *addr, unsigned long size);
-
 
 extern inline void *z_remap_nocache_ser(unsigned long physaddr, 
 					  unsigned long size)
diff -Nru a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
--- a/include/asm-mips/bitops.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-mips/bitops.h	Wed Jul 24 14:03:36 2002
@@ -29,10 +29,10 @@
  * that dares to use kernel include files alive.
  */
 #define __bi_flags unsigned long flags
-#define __bi_cli() __cli()
-#define __bi_save_flags(x) __save_flags(x)
-#define __bi_save_and_cli(x) __save_and_cli(x)
-#define __bi_restore_flags(x) __restore_flags(x)
+#define __bi_cli() local_irq_disable()
+#define __bi_save_flags(x) local_save_flags(x)
+#define __bi_save_and_cli(x) local_irq_save(x)
+#define __bi_restore_flags(x) local_irq_restore(x)
 #else
 #define __bi_flags
 #define __bi_cli()
diff -Nru a/include/asm-mips/smplock.h b/include/asm-mips/smplock.h
--- a/include/asm-mips/smplock.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-mips/smplock.h	Wed Jul 24 14:03:37 2002
@@ -21,7 +21,7 @@
 	if (task->lock_depth >= 0) \
 		spin_unlock(&kernel_flag); \
 	release_irqlock(cpu); \
-	__sti(); \
+	local_irq_enable(); \
 } while (0)
 
 /*
diff -Nru a/include/asm-mips/system.h b/include/asm-mips/system.h
--- a/include/asm-mips/system.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-mips/system.h	Wed Jul 24 14:03:38 2002
@@ -22,7 +22,7 @@
 #include <linux/kernel.h>
 
 extern __inline__ void
-__sti(void)
+local_irq_enable(void)
 {
 	__asm__ __volatile__(
 		".set\tpush\n\t"
@@ -46,7 +46,7 @@
  * no nops at all.
  */
 extern __inline__ void
-__cli(void)
+local_irq_disable(void)
 {
 	__asm__ __volatile__(
 		".set\tpush\n\t"
@@ -66,7 +66,7 @@
 		: "$1", "memory");
 }
 
-#define __save_flags(x)							\
+#define local_save_flags(x)							\
 __asm__ __volatile__(							\
 	".set\tpush\n\t"						\
 	".set\treorder\n\t"						\
@@ -74,7 +74,7 @@
 	".set\tpop\n\t"							\
 	: "=r" (x))
 
-#define __save_and_cli(x)						\
+#define local_irq_save(x)						\
 __asm__ __volatile__(							\
 	".set\tpush\n\t"						\
 	".set\treorder\n\t"						\
@@ -92,12 +92,12 @@
 	: /* no inputs */						\
 	: "$1", "memory")
 
-#define __restore_flags(flags)						\
+#define local_irq_restore(flags)						\
 do {									\
 	unsigned long __tmp1;						\
 									\
 	__asm__ __volatile__(						\
-		".set\tnoreorder\t\t\t# __restore_flags\n\t"		\
+		".set\tnoreorder\t\t\t# local_irq_restore\n\t"		\
 		".set\tnoat\n\t"					\
 		"mfc0\t$1, $12\n\t"					\
 		"andi\t%0, 1\n\t"					\
@@ -129,19 +129,13 @@
 
 #else /* Single processor */
 
-#  define sti() __sti()
-#  define cli() __cli()
-#  define save_flags(x) __save_flags(x)
-#  define save_and_cli(x) __save_and_cli(x)
-#  define restore_flags(x) __restore_flags(x)
+#  define sti() local_irq_enable()
+#  define cli() local_irq_disable()
+#  define save_flags(x) local_save_flags(x)
+#  define save_and_cli(x) local_irq_save(x)
+#  define restore_flags(x) local_irq_restore(x)
 
 #endif /* SMP */
-
-/* For spinlocks etc */
-#define local_irq_save(x)	__save_and_cli(x);
-#define local_irq_restore(x)	__restore_flags(x);
-#define local_irq_disable()	__cli();
-#define local_irq_enable()	__sti();
 
 /*
  * These are probably defined overly paranoid ...
diff -Nru a/include/asm-mips64/smplock.h b/include/asm-mips64/smplock.h
--- a/include/asm-mips64/smplock.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-mips64/smplock.h	Wed Jul 24 14:03:37 2002
@@ -22,7 +22,7 @@
 	if (task->lock_depth >= 0)
 		spin_unlock(&kernel_flag);
 	release_irqlock(cpu);
-	__sti();
+	local_irq_enable();
 }
 
 /*
diff -Nru a/include/asm-mips64/system.h b/include/asm-mips64/system.h
--- a/include/asm-mips64/system.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-mips64/system.h	Wed Jul 24 14:03:37 2002
@@ -16,7 +16,7 @@
 #include <linux/kernel.h>
 
 extern __inline__ void
-__sti(void)
+local_irq_enable(void)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -40,7 +40,7 @@
  * no nops at all.
  */
 extern __inline__ void
-__cli(void)
+local_irq_disable(void)
 {
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -59,14 +59,14 @@
 		: "$1", "memory");
 }
 
-#define __save_flags(x)							\
+#define local_save_flags(x)							\
 __asm__ __volatile__(							\
 	".set\tnoreorder\n\t"						\
 	"mfc0\t%0,$12\n\t"						\
 	".set\treorder"							\
 	: "=r" (x))
 
-#define __save_and_cli(x)						\
+#define local_irq_save(x)						\
 __asm__ __volatile__(							\
 	".set\tnoreorder\n\t"						\
 	".set\tnoat\n\t"						\
@@ -83,12 +83,12 @@
 	: /* no inputs */						\
 	: "$1", "memory")
 
-#define __restore_flags(flags)						\
+#define local_irq_restore(flags)						\
 do {									\
 	unsigned long __tmp1;						\
 									\
 	__asm__ __volatile__(						\
-		".set\tnoreorder\t\t\t# __restore_flags\n\t"		\
+		".set\tnoreorder\t\t\t# local_irq_restore\n\t"		\
 		".set\tnoat\n\t"					\
 		"mfc0\t$1, $12\n\t"					\
 		"andi\t%0, 1\n\t"					\
@@ -120,19 +120,13 @@
 
 #else
 
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
-#define save_and_cli(x) __save_and_cli(x)
+#define cli() local_irq_disable()
+#define sti() local_irq_enable()
+#define save_flags(x) local_save_flags(x)
+#define restore_flags(x) local_irq_restore(x)
+#define save_and_cli(x) local_irq_save(x)
 
 #endif /* CONFIG_SMP */
-
-/* For spinlocks etc */
-#define local_irq_save(x)	__save_and_cli(x);
-#define local_irq_restore(x)	__restore_flags(x);
-#define local_irq_disable()	__cli();
-#define local_irq_enable()	__sti();
 
 /*
  * These are probably defined overly paranoid ...
diff -Nru a/include/asm-parisc/smplock.h b/include/asm-parisc/smplock.h
--- a/include/asm-parisc/smplock.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-parisc/smplock.h	Wed Jul 24 14:03:35 2002
@@ -16,7 +16,7 @@
 	if (task->lock_depth >= 0) \
 		spin_unlock(&kernel_flag); \
 	release_irqlock(cpu); \
-	__sti(); \
+	local_irq_enable(); \
 } while (0)
 
 /*
diff -Nru a/include/asm-parisc/system.h b/include/asm-parisc/system.h
--- a/include/asm-parisc/system.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-parisc/system.h	Wed Jul 24 14:03:35 2002
@@ -62,24 +62,22 @@
 #endif
 
 /* interrupt control */
-#define __save_flags(x)	__asm__ __volatile__("ssm 0, %0" : "=r" (x) : : "memory")
-#define __restore_flags(x) __asm__ __volatile__("mtsm %0" : : "r" (x) : "memory")
-#define __cli()	__asm__ __volatile__("rsm %0,%%r0\n" : : "i" (PSW_I) : "memory" )
-#define __sti()	__asm__ __volatile__("ssm %0,%%r0\n" : : "i" (PSW_I) : "memory" )
+#define local_save_flags(x)	__asm__ __volatile__("ssm 0, %0" : "=r" (x) : : "memory")
+#define local_irq_restore(x)	__asm__ __volatile__("mtsm %0" : : "r" (x) : "memory")
+#define local_irq_disable()	__asm__ __volatile__("rsm %0,%%r0\n" : : "i" (PSW_I) : "memory" )
+#define local_irq_enable()	__asm__ __volatile__("ssm %0,%%r0\n" : : "i" (PSW_I) : "memory" )
 
 #define local_irq_save(x) \
 	__asm__ __volatile__("rsm %1,%0" : "=r" (x) :"i" (PSW_I) : "memory" )
 #define local_irq_restore(x) \
 	__asm__ __volatile__("mtsm %0" : : "r" (x) : "memory" )
-#define local_irq_disable() __cli()
-#define local_irq_enable()  __sti()
 
 #ifdef CONFIG_SMP
 #else
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
+#define cli() local_irq_disable()
+#define sti() local_irq_enable()
+#define save_flags(x) local_save_flags(x)
+#define restore_flags(x) local_irq_restore(x)
 #endif
 
 
diff -Nru a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h
--- a/include/asm-ppc/hw_irq.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-ppc/hw_irq.h	Wed Jul 24 14:03:38 2002
@@ -21,10 +21,10 @@
 			asm volatile("mfmsr %0" : "=r" (rval)); rval;})
 #define mtmsr(v)	asm volatile("mtmsr %0" : : "r" (v))
 
-#define __save_flags(flags)	((flags) = mfmsr())
-#define __restore_flags(flags)	mtmsr(flags)
+#define local_save_flags(flags)	((flags) = mfmsr())
+#define local_irq_restore(flags)	mtmsr(flags)
 
-static inline void __cli(void)
+static inline void local_irq_disable(void)
 {
 	unsigned long msr;
 	msr = mfmsr();
@@ -32,7 +32,7 @@
 	__asm__ __volatile__("": : :"memory");
 }
 
-static inline void __sti(void)
+static inline void local_irq_enable(void)
 {
 	unsigned long msr;
 	__asm__ __volatile__("": : :"memory");
@@ -49,18 +49,18 @@
 	__asm__ __volatile__("": : :"memory");
 }
 
-#define __save_and_cli(flags)          __do_save_and_cli(&flags)
+#define local_irq_save(flags)          __do_save_and_cli(&flags)
 
 #else
 
-extern void __sti(void);
-extern void __cli(void);
-extern void __restore_flags(unsigned long);
-extern void __save_flags_ptr(unsigned long *);
-extern unsigned long __sti_end, __cli_end, __restore_flags_end, __save_flags_ptr_end;
+extern void local_irq_enable(void);
+extern void local_irq_disable(void);
+extern void local_irq_restore(unsigned long);
+extern void local_save_flags_ptr(unsigned long *);
+extern unsigned long local_irq_enable_end, local_irq_disable_end, local_irq_restore_end, local_save_flags_ptr_end;
 
-#define __save_flags(flags) __save_flags_ptr((unsigned long *)&flags)
-#define __save_and_cli(flags) ({__save_flags(flags);__cli();})
+#define local_save_flags(flags) local_save_flags_ptr((unsigned long *)&flags)
+#define local_irq_save(flags) ({local_save_flags(flags);local_irq_disable();})
 
 #endif
 
diff -Nru a/include/asm-ppc/system.h b/include/asm-ppc/system.h
--- a/include/asm-ppc/system.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-ppc/system.h	Wed Jul 24 14:03:37 2002
@@ -83,11 +83,6 @@
 struct device_node;
 extern void note_scsi_host(struct device_node *, void *);
 
-#define prepare_arch_schedule(prev)		do { } while(0)
-#define finish_arch_schedule(prev)		do { } while(0)
-#define prepare_arch_switch(rq)			do { } while(0)
-#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
-
 struct task_struct;
 extern void __switch_to(struct task_struct *, struct task_struct *);
 #define switch_to(prev, next, last)	__switch_to((prev), (next))
@@ -103,11 +98,11 @@
 
 #ifndef CONFIG_SMP
 
-#define cli()	__cli()
-#define sti()	__sti()
-#define save_flags(flags)	__save_flags(flags)
-#define restore_flags(flags)	__restore_flags(flags)
-#define save_and_cli(flags)	__save_and_cli(flags)
+#define cli()	local_irq_disable()
+#define sti()	local_irq_enable()
+#define save_flags(flags)	local_save_flags(flags)
+#define restore_flags(flags)	local_irq_restore(flags)
+#define save_and_cli(flags)	local_irq_save(flags)
 
 #else /* CONFIG_SMP */
 
@@ -121,11 +116,6 @@
 #define restore_flags(x) __global_restore_flags(x)
 
 #endif /* !CONFIG_SMP */
-
-#define local_irq_disable()		__cli()
-#define local_irq_enable()		__sti()
-#define local_irq_save(flags)		__save_and_cli(flags)
-#define local_irq_restore(flags)	__restore_flags(flags)
 
 static __inline__ unsigned long
 xchg_u32(volatile void *p, unsigned long val)
diff -Nru a/include/asm-ppc/vc_ioctl.h b/include/asm-ppc/vc_ioctl.h
--- a/include/asm-ppc/vc_ioctl.h	Wed Jul 24 14:03:39 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,46 +0,0 @@
-/*
- * BK Id: SCCS/s.vc_ioctl.h 1.5 05/17/01 18:14:26 cort
- */
-#ifndef _LINUX_VC_IOCTL_H
-#define _LINUX_VC_IOCTL_H
-
-struct vc_mode {
-	int	height;
-	int	width;
-	int	depth;
-	int	pitch;
-	int	mode;
-	char	name[32];
-	unsigned long fb_address;
-	unsigned long cmap_adr_address;
-	unsigned long cmap_data_address;
-	unsigned long disp_reg_address;
-};
-
-#define VC_GETMODE	0x7667
-#define VC_SETMODE	0x7668
-#define VC_INQMODE	0x7669
-
-#define VC_SETCMAP      0x766a
-#define VC_GETCMAP      0x766b
-
-#define VC_POWERMODE	0x766c
-
-/* Values for the argument to the VC_POWERMODE ioctl */
-#define VC_POWERMODE_INQUIRY	(-1)
-#define VESA_NO_BLANKING	0
-#define VESA_VSYNC_SUSPEND	1
-#define VESA_HSYNC_SUSPEND	2
-#define VESA_POWERDOWN		3
-
-#ifdef __KERNEL__
-extern int console_getmode(struct vc_mode *);
-extern int console_setmode(struct vc_mode *, int);
-extern int console_setcmap(int, unsigned char *, unsigned char *,
-			   unsigned char *);
-extern int console_powermode(int);
-extern struct vc_mode display_info;
-extern struct fb_info *console_fb_info;
-#endif
-
-#endif /* _LINUX_VC_IOCTL_H */
diff -Nru a/include/asm-ppc64/bitops.h b/include/asm-ppc64/bitops.h
--- a/include/asm-ppc64/bitops.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-ppc64/bitops.h	Wed Jul 24 14:03:39 2002
@@ -43,7 +43,7 @@
 
 static __inline__ int test_bit(unsigned long nr, __const__ volatile unsigned long *addr)
 {
-	return (1UL & (((__const__ long *) addr)[nr >> 6] >> (nr & 63)));
+	return (1UL & (addr[nr >> 6] >> (nr & 63)));
 }
 
 static __inline__ void set_bit(unsigned long nr, volatile unsigned long *addr)
@@ -258,6 +258,12 @@
 	unsigned long i = (unsigned long)x;
 	return __ilog2(i & -i) + 1;
 }
+
+/*
+ * fls: find last (most-significant) bit set.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+#define fls(x) generic_fls(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
diff -Nru a/include/asm-ppc64/cache.h b/include/asm-ppc64/cache.h
--- a/include/asm-ppc64/cache.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-ppc64/cache.h	Wed Jul 24 14:03:36 2002
@@ -8,6 +8,9 @@
 #define __ARCH_PPC64_CACHE_H
 
 /* bytes per L1 cache line */
-#define L1_CACHE_BYTES	128
+#define L1_CACHE_SHIFT	7
+#define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
+
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
 
 #endif
diff -Nru a/include/asm-ppc64/current.h b/include/asm-ppc64/current.h
--- a/include/asm-ppc64/current.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-ppc64/current.h	Wed Jul 24 14:03:36 2002
@@ -1,6 +1,8 @@
 #ifndef _PPC64_CURRENT_H
 #define _PPC64_CURRENT_H
 
+#include <asm/paca.h>
+
 /*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -10,6 +12,9 @@
  * Use r13 for current since the ppc64 ABI reserves it - Anton
  */
 
-register struct task_struct *current asm ("r13");
+#include <asm/thread_info.h>
+
+#define get_current()   ((struct task_struct *)(get_paca()->xCurrent))
+#define current         get_current()
 
 #endif /* !(_PPC64_CURRENT_H) */
diff -Nru a/include/asm-ppc64/hardirq.h b/include/asm-ppc64/hardirq.h
--- a/include/asm-ppc64/hardirq.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-ppc64/hardirq.h	Wed Jul 24 14:03:36 2002
@@ -3,9 +3,6 @@
 #define __ASM_HARDIRQ_H
 
 /*
- * Use a brlock for the global irq lock, based on sparc64.
- * Anton Blanchard <anton@au1.ibm.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
@@ -13,88 +10,38 @@
  */
 
 #include <linux/config.h>
-#include <linux/brlock.h>
-#include <linux/spinlock.h>
-
+#include <linux/preempt.h>
 
 typedef struct {
 	unsigned long __softirq_pending;
-#ifndef CONFIG_SMP
-	unsigned int __local_irq_count;
-#else
-	unsigned int __unused_on_SMP;		/* We use brlocks on SMP */
-#endif
-	unsigned int __local_bh_count;
-	unsigned int __syscall_count;
-	unsigned long idle_timestamp;
+	unsigned long __syscall_count;
 	struct task_struct * __ksoftirqd_task;
+	unsigned long idle_timestamp;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
-/* Note that local_irq_count() is replaced by ppc64 specific version for SMP */
 
-#ifndef CONFIG_SMP
-#define irq_enter(cpu)		(local_irq_count(cpu)++)
-#define irq_exit(cpu)		(local_irq_count(cpu)--)
-#else
-#undef local_irq_count
-#define local_irq_count(cpu)	(__brlock_array[cpu][BR_GLOBALIRQ_LOCK])
-#define irq_enter(cpu)		br_read_lock(BR_GLOBALIRQ_LOCK)
-#define irq_exit(cpu)		br_read_unlock(BR_GLOBALIRQ_LOCK)
-#endif
+#define IRQ_OFFSET 64
 
 /*
  * Are we in an interrupt context? Either doing bottom half
  * or hardware interrupt processing?
  */
-#define in_interrupt() ({ int __cpu = smp_processor_id(); \
-	(local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
-
-/* This tests only the local processors hw IRQ context disposition.  */
-#define in_irq() (local_irq_count(smp_processor_id()) != 0)
-
-#ifndef CONFIG_SMP
+#define in_interrupt() \
+		((preempt_count() & ~PREEMPT_ACTIVE) >= IRQ_OFFSET)
 
-#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
-#define hardirq_endlock(cpu)	do { } while (0)
+#define in_irq in_interrupt
 
-#define synchronize_irq()	barrier()
-#define release_irqlock(cpu)	do { } while (0)
+#define hardirq_trylock()	(!in_interrupt())
+#define hardirq_endlock()	do { } while (0)
 
-#else /* CONFIG_SMP */
-
-static __inline__ int irqs_running(void)
-{
-	int i;
-
-	for (i = 0; i < smp_num_cpus; i++)
-		if (local_irq_count(cpu_logical_map(i)))
-			return 1;
-	return 0;
-}
-
-extern unsigned char global_irq_holder;
-
-static inline void release_irqlock(int cpu)
-{
-	/* if we didn't own the irq lock, just ignore... */
-	if(global_irq_holder == (unsigned char) cpu) {
-		global_irq_holder = NO_PROC_ID;
-		br_write_unlock(BR_GLOBALIRQ_LOCK);
-	}
-}
-
-static inline int hardirq_trylock(int cpu)
-{
-	spinlock_t *lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
-
-	return (!local_irq_count(cpu) && !spin_is_locked(lock));
-}
-
-#define hardirq_endlock(cpu)    do { (void)(cpu); } while (0)
-
-extern void synchronize_irq(void);
+#define irq_enter()		(preempt_count() += IRQ_OFFSET)
+#define irq_exit()		(preempt_count() -= IRQ_OFFSET)
 
+#ifndef CONFIG_SMP
+# define synchronize_irq(irq)	barrier()
+#else
+  extern void synchronize_irq(unsigned int irq);
 #endif /* CONFIG_SMP */
 
 #endif /* __KERNEL__ */
diff -Nru a/include/asm-ppc64/hw_irq.h b/include/asm-ppc64/hw_irq.h
--- a/include/asm-ppc64/hw_irq.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-ppc64/hw_irq.h	Wed Jul 24 14:03:38 2002
@@ -26,18 +26,18 @@
 extern void __no_use_set_lost(unsigned long);
 extern void __no_lpq_restore_flags(unsigned long);
 
-#define __cli()			__no_use_cli()
-#define __sti()			__no_use_sti()
-#define __save_flags(flags)	((flags) = __no_use_save_flags())
-#define __restore_flags(flags)	__no_use_restore_flags((unsigned long)flags)
-#define __save_and_cli(flags)	({__save_flags(flags);__cli();})
+#define local_irq_disable()			__no_use_cli()
+#define local_irq_enable()			__no_use_sti()
+#define local_save_flags(flags)	((flags) = __no_use_save_flags())
+#define local_irq_restore(flags)	__no_use_restore_flags((unsigned long)flags)
+#define local_irq_save(flags)	({local_save_flags(flags);local_irq_disable();})
 
 #else
 
-#define __save_flags(flags)	((flags) = mfmsr())
-#define __restore_flags(flags)	__mtmsrd((flags), 1)
+#define local_save_flags(flags)	((flags) = mfmsr())
+#define local_irq_restore(flags)	__mtmsrd((flags), 1)
 
-static inline void __cli(void)
+static inline void local_irq_disable(void)
 {
 	unsigned long msr;
 	msr = mfmsr();
@@ -45,7 +45,7 @@
 	__asm__ __volatile__("": : :"memory");
 }
 
-static inline void __sti(void)
+static inline void local_irq_enable(void)
 {
 	unsigned long msr;
 	__asm__ __volatile__("": : :"memory");
@@ -62,7 +62,7 @@
 	__asm__ __volatile__("": : :"memory");
 }
 
-#define __save_and_cli(flags)          __do_save_and_cli(&flags)
+#define local_irq_save(flags)          __do_save_and_cli(&flags)
 
 #endif /* CONFIG_PPC_ISERIES */
 
diff -Nru a/include/asm-ppc64/iSeries/HvCall.h b/include/asm-ppc64/iSeries/HvCall.h
--- a/include/asm-ppc64/iSeries/HvCall.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-ppc64/iSeries/HvCall.h	Wed Jul 24 14:03:36 2002
@@ -130,6 +130,9 @@
 #define HvCallBaseRouter28				HvCallBase + 28
 #define HvCallBaseRouter29				HvCallBase + 29
 #define HvCallBaseRouter30				HvCallBase + 30
+
+#define HvCallCcSetDABR  				HvCallCc + 7
+
 //=====================================================================================
 static inline void		HvCall_setVirtualDecr(void)
 {
@@ -197,6 +200,10 @@
 	HvCall0( HvCallBaseTerminateMachineSrc );
 }
 
+static inline void HvCall_setDABR(unsigned long val)
+{
+	HvCall1(HvCallCcSetDABR, val);
+}
 
 #endif // _HVCALL_H
 
diff -Nru a/include/asm-ppc64/iSeries/HvCallHpt.h b/include/asm-ppc64/iSeries/HvCallHpt.h
--- a/include/asm-ppc64/iSeries/HvCallHpt.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-ppc64/iSeries/HvCallHpt.h	Wed Jul 24 14:03:35 2002
@@ -106,21 +106,21 @@
 	return compressedStatus;
 }
 //=============================================================================
-static inline u64		HvCallHpt_findValid( struct HPTE *hpte, u64 vpn )
+static inline u64		HvCallHpt_findValid( HPTE *hpte, u64 vpn )
 {
 	u64 retIndex = HvCall3Ret16( HvCallHptFindValid, hpte, vpn, 0, 0 );
 	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 	return retIndex;
 }
 //=============================================================================
-static inline u64		HvCallHpt_findNextValid( struct HPTE *hpte, u32 hpteIndex, u8 bitson, u8 bitsoff )
+static inline u64		HvCallHpt_findNextValid( HPTE *hpte, u32 hpteIndex, u8 bitson, u8 bitsoff )
 {
 	u64 retIndex = HvCall3Ret16( HvCallHptFindNextValid, hpte, hpteIndex, bitson, bitsoff );
 	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 	return retIndex;
 }
 //=============================================================================
-static inline void		HvCallHpt_get( struct HPTE *hpte, u32 hpteIndex )
+static inline void		HvCallHpt_get( HPTE *hpte, u32 hpteIndex )
 {
 	HvCall2Ret16( HvCallHptGet, hpte, hpteIndex, 0 );
 	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
@@ -128,7 +128,7 @@
 //============================================================================
 static inline void		HvCallHpt_addValidate( u32 hpteIndex,
 						       u32 hBit,
-						       struct HPTE *hpte )
+						       HPTE *hpte )
 						
 {
 	HvCall4( HvCallHptAddValidate, hpteIndex,
diff -Nru a/include/asm-ppc64/iSeries/HvCallSc.h b/include/asm-ppc64/iSeries/HvCallSc.h
--- a/include/asm-ppc64/iSeries/HvCallSc.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-ppc64/iSeries/HvCallSc.h	Wed Jul 24 14:03:36 2002
@@ -25,6 +25,7 @@
 #define _HVCALLSC_H
 
 #define HvCallBase		0x8000000000000000
+#define HvCallCc		0x8001000000000000
 #define HvCallCfg		0x8002000000000000
 #define HvCallEvent		0x8003000000000000
 #define HvCallHpt		0x8004000000000000
diff -Nru a/include/asm-ppc64/iSeries/ItExtVpdPanel.h b/include/asm-ppc64/iSeries/ItExtVpdPanel.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc64/iSeries/ItExtVpdPanel.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,60 @@
+/*
+ * ItExtVpdPanel.h
+ * Copyright (C) 2002  Dave Boutcher IBM Corporation
+ * 
+ * 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
+ */
+
+/*
+ *
+ *	This struct maps the panel information 
+ *
+ * Warning:
+ *	This data must match the architecture for the panel information
+ *
+ */
+
+
+/*-------------------------------------------------------------------
+ * Standard Includes
+ *------------------------------------------------------------------- 
+*/
+#ifndef	_PPC_TYPES_H
+#include	<asm/types.h>
+#endif
+
+#ifndef _ITEXTVPDPANEL_H
+#define _ITEXTVPDPANEL_H
+struct ItExtVpdPanel
+{
+  // Definition of the Extended Vpd On Panel Data Area
+  char                      systemSerial[8];
+  char                      mfgID[4];
+  char                      reserved1[24];
+  char                      machineType[4];
+  char                      systemID[6];
+  char                      somUniqueCnt[4];
+  char                      serialNumberCount;
+  char                      reserved2[7];
+  u16                       bbu3;
+  u16                       bbu2;
+  u16                       bbu1;
+  char                      xLocationLabel[8];
+  u8                        xRsvd1[6];
+  u16                       xFrameId;
+  u8                        xRsvd2[48];
+};
+
+#endif /* _ITEXTVPDPANEL_H  */
diff -Nru a/include/asm-ppc64/iSeries/LparData.h b/include/asm-ppc64/iSeries/LparData.h
--- a/include/asm-ppc64/iSeries/LparData.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-ppc64/iSeries/LparData.h	Wed Jul 24 14:03:35 2002
@@ -37,6 +37,7 @@
 #include <asm/iSeries/LparMap.h>
 #include <asm/iSeries/ItVpdAreas.h>
 #include <asm/iSeries/ItIplParmsReal.h>
+#include <asm/iSeries/ItExtVpdPanel.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/IoHriProcessorVpd.h>
 #include <asm/page.h>
@@ -45,6 +46,7 @@
 extern struct HvReleaseData hvReleaseData;
 extern struct ItLpNaca	itLpNaca;
 extern struct ItIplParmsReal xItIplParmsReal;
+extern struct ItExtVpdPanel xItExtVpdPanel;
 extern struct IoHriProcessorVpd xIoHriProcessorVpd[];
 extern struct ItLpQueue xItLpQueue;
 extern struct ItVpdAreas itVpdAreas;
diff -Nru a/include/asm-ppc64/init.h b/include/asm-ppc64/init.h
--- a/include/asm-ppc64/init.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-ppc64/init.h	Wed Jul 24 14:03:36 2002
@@ -1,29 +1 @@
-#ifndef _PPC64_INIT_H
-#define _PPC64_INIT_H
-
-#include <linux/init.h>
-
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 90 /* egcs */
-/* DRENG add back in when we get section attribute support */
-#define __chrp __attribute__ ((__section__ (".text.chrp")))
-#define __chrpdata __attribute__ ((__section__ (".data.chrp")))
-#define __chrpfunc(__argchrp) \
-	__argchrp __chrp; \
-	__argchrp
-
-/* this is actually just common chrp/pmac code, not OF code -- Cort */
-#define __openfirmware __attribute__ ((__section__ (".text.openfirmware")))
-#define __openfirmwaredata __attribute__ ((__section__ (".data.openfirmware")))
-#define __openfirmwarefunc(__argopenfirmware) \
-	__argopenfirmware __openfirmware; \
-	__argopenfirmware
-	
-#else /* not egcs */
-
-#define __openfirmware
-#define __openfirmwaredata
-#define __openfirmwarefunc(x) x
-
-#endif /* egcs */
-
-#endif /* _PPC64_INIT_H */
+#error "<asm/init.h> should never be used - use <linux/init.h> instead"
diff -Nru a/include/asm-ppc64/lmb.h b/include/asm-ppc64/lmb.h
--- a/include/asm-ppc64/lmb.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-ppc64/lmb.h	Wed Jul 24 14:03:37 2002
@@ -13,6 +13,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/config.h>
 #include <asm/prom.h>
 
 extern unsigned long reloc_offset(void);
diff -Nru a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h
--- a/include/asm-ppc64/machdep.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-ppc64/machdep.h	Wed Jul 24 14:03:37 2002
@@ -62,7 +62,7 @@
 					    int msg, 
 					    unsigned long data,
 					    int wait);
-	int		(*smp_probe)(void);
+	void		(*smp_probe)(void);
 	void		(*smp_kick_cpu)(int nr);
 	void		(*smp_setup_cpu)(int nr);
 
diff -Nru a/include/asm-ppc64/md.h b/include/asm-ppc64/md.h
--- a/include/asm-ppc64/md.h	Wed Jul 24 14:03:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,17 +0,0 @@
-/* 
- * md.h: High speed xor_block operation for RAID4/5 
- *
- * 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 __ASM_MD_H
-#define __ASM_MD_H
-
-/* #define HAVE_ARCH_XORBLOCK */
-
-#define MD_XORBLOCK_ALIGNMENT	sizeof(long)
-
-#endif /* __ASM_MD_H */
diff -Nru a/include/asm-ppc64/mmzone.h b/include/asm-ppc64/mmzone.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc64/mmzone.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,93 @@
+/*
+ * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99
+ *
+ * PowerPC64 port:
+ * Copyright (C) 2002 Anton Blanchard, IBM Corp.
+ */
+#ifndef _ASM_MMZONE_H_
+#define _ASM_MMZONE_H_
+
+#include <linux/config.h>
+
+typedef struct plat_pglist_data {
+	pg_data_t	gendata;
+} plat_pg_data_t;
+
+/*
+ * Following are macros that are specific to this numa platform.
+ */
+
+extern plat_pg_data_t plat_node_data[];
+
+#define MAX_NUMNODES 4
+
+/* XXX grab this from the device tree - Anton */
+#define PHYSADDR_TO_NID(pa)		((pa) >> 36)
+#define PLAT_NODE_DATA(n)		(&plat_node_data[(n)])
+#define PLAT_NODE_DATA_STARTNR(n)	\
+	(PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
+#define PLAT_NODE_DATA_SIZE(n)		(PLAT_NODE_DATA(n)->gendata.node_size)
+#define PLAT_NODE_DATA_LOCALNR(p, n)	\
+	(((p) - PLAT_NODE_DATA(n)->gendata.node_start_paddr) >> PAGE_SHIFT)
+
+#ifdef CONFIG_DISCONTIGMEM
+
+/*
+ * Following are macros that each numa implmentation must define.
+ */
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define KVADDR_TO_NID(kaddr)	PHYSADDR_TO_NID(__pa(kaddr))
+
+/*
+ * Return a pointer to the node data for node n.
+ */
+#define NODE_DATA(n)	(&((PLAT_NODE_DATA(n))->gendata))
+
+/*
+ * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
+ */
+#define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
+
+/*
+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
+ * and returns the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr) \
+			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
+
+/*
+ * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
+ * and returns the kaddr corresponding to first physical page in the
+ * node's mem_map.
+ */
+#define LOCAL_BASE_ADDR(kaddr) \
+	((unsigned long)__va(NODE_DATA(KVADDR_TO_NID(kaddr))->node_start_paddr))
+
+#define LOCAL_MAP_NR(kvaddr) \
+	(((unsigned long)(kvaddr)-LOCAL_BASE_ADDR(kvaddr)) >> PAGE_SHIFT)
+
+#if 0
+/* XXX fix - Anton */
+#define kern_addr_valid(kaddr)	test_bit(LOCAL_MAP_NR(kaddr), \
+					 NODE_DATA(KVADDR_TO_NID(kaddr))->valid_addr_bitmap)
+#endif
+
+#define discontigmem_pfn_to_page(pfn) \
+({ \
+	unsigned long kaddr = (unsigned long)__va(pfn << PAGE_SHIFT); \
+	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)); \
+})
+
+#ifdef CONFIG_NUMA
+
+/* XXX grab this from the device tree - Anton */
+#define cputonode(cpu)	((cpu) >> 3)
+
+#define numa_node_id()	cputonode(smp_processor_id())
+
+#endif /* CONFIG_NUMA */
+#endif /* CONFIG_DISCONTIGMEM */
+#endif /* _ASM_MMZONE_H_ */
diff -Nru a/include/asm-ppc64/naca.h b/include/asm-ppc64/naca.h
--- a/include/asm-ppc64/naca.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-ppc64/naca.h	Wed Jul 24 14:03:38 2002
@@ -18,7 +18,6 @@
 	u64 xRamDiskSize;		/* In pages */
 	struct paca_struct *paca;	/* Ptr to an array of pacas */
 	u64 debug_switch;		/* Bits to control debug printing */
-	u16 processorCount;		/* # of physical processors */
 	u16 dCacheL1LineSize;		/* Line size of L1 DCache in bytes */
 	u16 dCacheL1LogLineSize;	/* Log-2 of DCache line size */
 	u16 dCacheL1LinesPerPage;	/* DCache lines per page */
diff -Nru a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h
--- a/include/asm-ppc64/paca.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-ppc64/paca.h	Wed Jul 24 14:03:37 2002
@@ -45,7 +45,8 @@
 #define MAX_PACAS MAX_PROCESSORS * 2
 
 extern struct paca_struct paca[];
-#define get_paca() ((struct paca_struct *)mfspr(SPRG3))
+register struct paca_struct *local_paca asm("r13");
+#define get_paca()	local_paca
 
 /*============================================================================
  * Name_______:	paca
@@ -71,7 +72,7 @@
 	struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC	0x08 */
 	u64 xCurrent;  		        /* Pointer to current			0x10 */
 	u16 xPacaIndex;			/* Logical processor number		0x18 */
-	u16 xHwProcNum;			/* Actual Hardware Processor Number	0x1a */
+	u16 active;			/* Is this cpu active?			0x1a */
 	u32 default_decr;		/* Default decrementer value		0x1c */	
 	u64 xHrdIntStack;		/* Stack for hardware interrupts	0x20 */
 	u64 xKsave;			/* Saved Kernel stack addr or zero	0x28 */
diff -Nru a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
--- a/include/asm-ppc64/page.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-ppc64/page.h	Wed Jul 24 14:03:35 2002
@@ -33,24 +33,13 @@
 #ifndef __ASSEMBLY__
 #include <asm/naca.h>
 
-#define STRICT_MM_TYPECHECKS
+#undef STRICT_MM_TYPECHECKS
 
 #define REGION_SIZE   4UL
-#define OFFSET_SIZE   60UL
 #define REGION_SHIFT  60UL
-#define OFFSET_SHIFT  0UL
 #define REGION_MASK   (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
 #define REGION_STRIDE (1UL << REGION_SHIFT)
 
-typedef union ppc64_va {
-        struct {
-                unsigned long off : OFFSET_SIZE;  /* intra-region offset */
-                unsigned long reg : REGION_SIZE;  /* region number */
-        } f;
-        unsigned long l;
-        void *p;
-} ppc64_va;
-       
 static __inline__ void clear_page(void *addr)
 {
 	unsigned long lines, line_size;
@@ -70,8 +59,8 @@
 
 extern void copy_page(void *to, void *from);
 struct page;
-extern void clear_user_page(void *page, unsigned long vaddr);
-extern void copy_user_page(void *to, void *from, unsigned long vaddr);
+extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
+extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *p);
 
 #ifdef STRICT_MM_TYPECHECKS
 /*
@@ -215,8 +204,15 @@
 #define __a2p(x) ((void *) absolute_to_phys(x))
 #define __a2v(x) ((void *) __va(absolute_to_phys(x)))
 
+#ifdef CONFIG_DISCONTIGMEM
+#define page_to_pfn(page) \
+		((page) - page_zone(page)->zone_mem_map + \
+		(page_zone(page)->zone_start_paddr >> PAGE_SHIFT))
+#define pfn_to_page(pfn)	discontigmem_pfn_to_page(pfn)
+#else
 #define pfn_to_page(pfn)	(mem_map + (pfn))
-#define page_to_pfn(pfn)	((unsigned long)((pfn) - mem_map))
+#define page_to_pfn(page)	((unsigned long)((page) - mem_map))
+#endif
 #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 
 #define pfn_valid(pfn)		((pfn) < max_mapnr)
diff -Nru a/include/asm-ppc64/param.h b/include/asm-ppc64/param.h
--- a/include/asm-ppc64/param.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-ppc64/param.h	Wed Jul 24 14:03:37 2002
@@ -8,18 +8,14 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#ifndef HZ
-#define HZ 1024
 #ifdef __KERNEL__
-#if HZ == 100
-/* ppc (like X86) is defined to provide userspace with a world where HZ=100
-   We have to do this, (x*const)/const2 isnt optimised out because its not
-   a null operation as it might overflow.. */
-#define hz_to_std(a) (a)
-#else
-#define hz_to_std(a) ((a)*(100/HZ)+((a)*(100%HZ))/HZ)
-#endif
+# define HZ		1000		/* Internal kernel timer frequency */
+# define USER_HZ	100		/* .. some user interfaces are in "ticks" */
+# define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
 #endif
+
+#ifndef HZ
+#define HZ 100
 #endif
 
 #define EXEC_PAGESIZE	4096
@@ -33,9 +29,5 @@
 #endif
 
 #define MAXHOSTNAMELEN	64	/* max length of hostname */
-
-#ifdef __KERNEL__
-# define CLOCKS_PER_SEC	HZ	/* frequency at which times() counts */
-#endif
 
 #endif /* _ASM_PPC64_PARAM_H */
diff -Nru a/include/asm-ppc64/pgalloc.h b/include/asm-ppc64/pgalloc.h
--- a/include/asm-ppc64/pgalloc.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-ppc64/pgalloc.h	Wed Jul 24 14:03:35 2002
@@ -53,6 +53,8 @@
 	free_page((unsigned long)pmd);
 }
 
+#define pmd_free_tlb(tlb, pmd)	pmd_free(pmd)
+
 #define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, pte)
 #define pmd_populate(mm, pmd, pte_page) \
 	pmd_populate_kernel(mm, pmd, page_address(pte_page))
@@ -86,6 +88,7 @@
 }
 
 #define pte_free(pte_page)	pte_free_kernel(page_address(pte_page))
+#define pte_free_tlb(tlb, pte)	pte_free(pte)
 
 #define check_pgt_cache()	do { } while (0)
 
diff -Nru a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
--- a/include/asm-ppc64/pgtable.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-ppc64/pgtable.h	Wed Jul 24 14:03:39 2002
@@ -12,11 +12,6 @@
 #include <asm/page.h>
 #endif /* __ASSEMBLY__ */
 
-/* Certain architectures need to do special things when pte's
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-
 /* PMD_SHIFT determines what a second-level page table entry can map */
 #define PMD_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - 3)
 #define PMD_SIZE	(1UL << PMD_SHIFT)
@@ -107,9 +102,9 @@
 /* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */
 #define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HPTEFLAGS)
 
-#define _PAGE_BASE	_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT
+#define _PAGE_BASE	(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
 
-#define _PAGE_WRENABLE	_PAGE_RW | _PAGE_DIRTY 
+#define _PAGE_WRENABLE	(_PAGE_RW | _PAGE_DIRTY)
 
 /* __pgprot defined in asm-ppc64/page.h */
 #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
@@ -330,8 +325,6 @@
 	pte_update(ptep, ~_PAGE_HPTEFLAGS, 0);
 }
 
-extern unsigned long va_to_phys(unsigned long address);
-extern pte_t *va_to_pte(unsigned long address);
 extern unsigned long ioremap_bot, ioremap_base;
 
 #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
@@ -356,6 +349,7 @@
  * ahead of time, instead of waiting for the inevitable extra
  * hash-table miss exception.
  */
+struct vm_area_struct;
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
 /* Encode and de-code a swap entry */
@@ -380,12 +374,8 @@
  */
 #define pgtable_cache_init()	do { } while (0)
 
-extern void updateBoltedHptePP(unsigned long newpp, unsigned long ea);
 extern void hpte_init_pSeries(void);
 extern void hpte_init_iSeries(void);
-
-extern void make_pte(HPTE * htab, unsigned long va, unsigned long pa,
-		int mode, unsigned long hash_mask, int large);
 
 #endif /* __ASSEMBLY__ */
 #endif /* _PPC64_PGTABLE_H */
diff -Nru a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
--- a/include/asm-ppc64/processor.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-ppc64/processor.h	Wed Jul 24 14:03:35 2002
@@ -483,10 +483,12 @@
 #define	PVR_REV(pvr)  (((pvr) >>   0) & 0xFFFF)	/* Revison field */
 
 /* Processor Version Numbers */
+#define PV_NORTHSTAR	0x0033
 #define	PV_PULSAR	0x0034
 #define	PV_POWER4	0x0035
 #define	PV_ICESTAR	0x0036
 #define	PV_SSTAR	0x0037
+#define	PV_POWER4p	0x0038
 #define	PV_630        	0x0040
 #define	PV_630p	        0x0041
 
@@ -710,6 +712,18 @@
 }
 
 #define spin_lock_prefetch(x)	prefetchw(x)
+
+#define cpu_has_largepage()	(__is_processor(PV_POWER4) || \
+				 __is_processor(PV_POWER4p))
+
+#define cpu_has_slb()		(__is_processor(PV_POWER4) || \
+				 __is_processor(PV_POWER4p))
+
+#define cpu_has_tlbiel()	(__is_processor(PV_POWER4) || \
+				 __is_processor(PV_POWER4p))
+
+#define cpu_has_noexecute()	(__is_processor(PV_POWER4) || \
+				 __is_processor(PV_POWER4p))
 
 #endif /* ASSEMBLY */
 
diff -Nru a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
--- a/include/asm-ppc64/prom.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-ppc64/prom.h	Wed Jul 24 14:03:38 2002
@@ -195,8 +195,5 @@
 extern int prom_n_addr_cells(struct device_node* np);
 extern int prom_n_size_cells(struct device_node* np);
 extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
-extern void prom_drawstring(const char *c);
-extern void prom_drawhex(unsigned long v);
-extern void prom_drawchar(char c);
 
 #endif /* _PPC64_PROM_H */
diff -Nru a/include/asm-ppc64/ptrace-common.h b/include/asm-ppc64/ptrace-common.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc64/ptrace-common.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,55 @@
+/*
+ *  linux/arch/ppc64/kernel/ptrace-common.h
+ *
+ *    Copyright (c) 2002 Stephen Rothwell, IBM Coproration
+ *    Extracted from ptrace.c and ptrace32.c
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file README.legal in the main directory of
+ * this archive for more details.
+ */
+
+/*
+ * Set of msr bits that gdb can change on behalf of a process.
+ */
+#define MSR_DEBUGCHANGE	(MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline unsigned long get_reg(struct task_struct *task, int regno)
+{
+	if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long)))
+		return ((unsigned long *)task->thread.regs)[regno];
+	return 0;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+			  unsigned long data)
+{
+	if (regno < PT_SOFTE) {
+		if (regno == PT_MSR)
+			data = (data & MSR_DEBUGCHANGE)
+				| (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
+		((unsigned long *)task->thread.regs)[regno] = data;
+		return 0;
+	}
+	return -EIO;
+}
+
+static inline void set_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+	if (regs != NULL)
+		regs->msr |= MSR_SE;
+}
+
+static inline void clear_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+	if (regs != NULL)
+		regs->msr &= ~MSR_SE;
+}
diff -Nru a/include/asm-ppc64/rmap.h b/include/asm-ppc64/rmap.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc64/rmap.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,9 @@
+#ifndef _PPC64_RMAP_H
+#define _PPC64_RMAP_H
+
+/* PPC64 calls pte_alloc() before mem_map[] is setup ... */
+#define BROKEN_PPC_PTE_ALLOC_ONE
+
+#include <asm-generic/rmap.h>
+
+#endif
diff -Nru a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h
--- a/include/asm-ppc64/rtas.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-ppc64/rtas.h	Wed Jul 24 14:03:39 2002
@@ -2,6 +2,7 @@
 #define _PPC64_RTAS_H
 
 #include <linux/spinlock.h>
+#include <asm/page.h>
 
 /*
  * Definitions for talking to the RTAS on CHRP machines.
@@ -128,6 +129,29 @@
 	unsigned char buffer[1];		/* allocated by klimit bump */
 };
 
+struct flash_block {
+	char *data;
+	unsigned long length;
+};
+
+/* This struct is very similar but not identical to
+ * that needed by the rtas flash update.
+ * All we need to do for rtas is rewrite num_blocks
+ * into a version/length and translate the pointers
+ * to absolute.
+ */
+#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block))
+struct flash_block_list {
+	unsigned long num_blocks;
+	struct flash_block_list *next;
+	struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
+};
+struct flash_block_list_header { /* just the header of flash_block_list */
+	unsigned long num_blocks;
+	struct flash_block_list *next;
+};
+extern struct flash_block_list_header rtas_firmware_flash_list;
+
 extern struct rtas_t rtas;
 
 extern void enter_rtas(struct rtas_args *);
@@ -139,5 +163,8 @@
 extern void rtas_restart(char *cmd);
 extern void rtas_power_off(void);
 extern void rtas_halt(void);
+
+extern struct proc_dir_entry *rtas_proc_dir;
+
 
 #endif /* _PPC64_RTAS_H */
diff -Nru a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h
--- a/include/asm-ppc64/smp.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-ppc64/smp.h	Wed Jul 24 14:03:35 2002
@@ -39,16 +39,27 @@
 
 #define NO_PROC_ID		0xFF            /* No processor magic marker */
 
-/* 1 to 1 mapping on PPC -- Cort */
-#define cpu_logical_map(cpu) (cpu)
-#define cpu_number_map(x) (x)
+#define cpu_online(cpu)	test_bit((cpu), &cpu_online_map)
+
+#define cpu_possible(cpu)	paca[cpu].active
+
+static inline int num_online_cpus(void)
+{
+	int i, nr = 0;
+
+	for (i = 0; i < NR_CPUS; i++)
+		nr += test_bit(i, &cpu_online_map);
+
+	return nr;
+}
+
 extern volatile unsigned long cpu_callin_map[NR_CPUS];
 
 #define smp_processor_id() (get_paca()->xPacaIndex)
-#define hard_smp_processor_id() (get_paca()->xHwProcNum)
-#define get_hard_smp_processor_id(CPU) (paca[(CPU)].xHwProcNum)
-
 
+/* remove when the boot sequence gets rewritten to use hotplug interface */
+extern int boot_cpuid;
+extern int ppc64_is_smp;
 
 /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
  *
diff -Nru a/include/asm-ppc64/smplock.h b/include/asm-ppc64/smplock.h
--- a/include/asm-ppc64/smplock.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-ppc64/smplock.h	Wed Jul 24 14:03:36 2002
@@ -18,13 +18,10 @@
 /*
  * Release global kernel lock and global interrupt lock
  */
-#define release_kernel_lock(task, cpu)		\
+#define release_kernel_lock(task)		\
 do {						\
-	if (unlikely(task->lock_depth >= 0)) {	\
+	if (unlikely(task->lock_depth >= 0))	\
 		spin_unlock(&kernel_flag);	\
-		if (global_irq_holder == (cpu))	\
-			BUG();			\
-	}					\
 } while (0)
 
 /*
diff -Nru a/include/asm-ppc64/softirq.h b/include/asm-ppc64/softirq.h
--- a/include/asm-ppc64/softirq.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-ppc64/softirq.h	Wed Jul 24 14:03:35 2002
@@ -8,22 +8,28 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <asm/atomic.h>
+#include <linux/preempt.h>
 #include <asm/hardirq.h>
 
+#define local_bh_disable() \
+		do { preempt_count() += IRQ_OFFSET; barrier(); } while (0)
 
-#define local_bh_disable()	do { local_bh_count(smp_processor_id())++; barrier(); } while (0)
-#define __local_bh_enable()	do { barrier(); local_bh_count(smp_processor_id())--; } while (0)
+#define __local_bh_enable() \
+		do { barrier(); preempt_count() -= IRQ_OFFSET; } while (0)
 
-#define local_bh_enable()  \
-do {                                                    \
-        if (!--local_bh_count(smp_processor_id())       \
-            && softirq_pending(smp_processor_id())) {   \
-                do_softirq();                           \
-        }                                               \
+#define local_bh_enable() \
+do { \
+	if (unlikely((preempt_count() == IRQ_OFFSET) && \
+		     softirq_pending(smp_processor_id()))) { \
+		__local_bh_enable(); \
+		do_softirq(); \
+		preempt_check_resched(); \
+	} else { \
+		__local_bh_enable(); \
+		preempt_check_resched(); \
+	} \
 } while (0)
 
-
-#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+#define in_softirq() in_interrupt()
 
 #endif	/* __ASM_SOFTIRQ_H */
diff -Nru a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
--- a/include/asm-ppc64/system.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-ppc64/system.h	Wed Jul 24 14:03:38 2002
@@ -9,20 +9,12 @@
  */
 
 #include <linux/config.h>
-#include <linux/kdev_t.h>
 #include <asm/page.h>
 #include <asm/processor.h>
 #include <asm/hw_irq.h>
 #include <asm/memory.h>
 
 /*
- * System defines.
- */
-#define KERNEL_START_PHYS	0x800000 
-#define KERNEL_START	        (PAGE_OFFSET+KERNEL_START_PHYS)
-#define START_ADDR	        (PAGE_OFFSET+KERNEL_START_PHYS+0x00000)
-
-/*
  * Memory barrier.
  * The sync instruction guarantees that all memory accesses initiated
  * by this processor have been performed (with respect to all other
@@ -85,28 +77,21 @@
 extern void print_backtrace(unsigned long *);
 extern void show_regs(struct pt_regs * regs);
 extern void flush_instruction_cache(void);
-extern void hard_reset_now(void);
-extern void poweroff_now(void);
 extern int _get_PVR(void);
-extern long _get_L2CR(void);
-extern void _set_L2CR(unsigned long);
-extern void via_cuda_init(void);
-extern void pmac_nvram_init(void);
-extern void pmac_find_display(void);
 extern void giveup_fpu(struct task_struct *);
 extern void enable_kernel_fp(void);
-extern void giveup_altivec(struct task_struct *);
-extern void load_up_altivec(struct task_struct *);
 extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
 extern void cvt_df(double *from, float *to, unsigned long *fpscr);
 extern int abs(int);
 
-struct device_node;
-
 struct task_struct;
-#define prepare_to_switch()	do { } while(0)
-#define switch_to(prev,next) _switch_to((prev),(next))
-extern void _switch_to(struct task_struct *, struct task_struct *);
+extern void __switch_to(struct task_struct *, struct task_struct *);
+#define switch_to(prev, next, last) __switch_to((prev), (next))
+
+#define prepare_arch_schedule(prev)		do { } while(0)
+#define finish_arch_schedule(prev)		do { } while(0)
+#define prepare_arch_switch(rq)			do { } while(0)
+#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
 
 struct thread_struct;
 extern void _switch(struct thread_struct *prev, struct thread_struct *next);
@@ -116,29 +101,13 @@
 
 #ifndef CONFIG_SMP
 
-#define cli()	__cli()
-#define sti()	__sti()
-#define save_flags(flags)	__save_flags(flags)
-#define restore_flags(flags)	__restore_flags(flags)
-#define save_and_cli(flags)	__save_and_cli(flags)
-
-#else /* CONFIG_SMP */
-
-extern void __global_cli(void);
-extern void __global_sti(void);
-extern unsigned long __global_save_flags(void);
-extern void __global_restore_flags(unsigned long);
-#define cli() __global_cli()
-#define sti() __global_sti()
-#define save_flags(x) ((x)=__global_save_flags())
-#define restore_flags(x) __global_restore_flags(x)
+#define cli()	local_irq_disable()
+#define sti()	local_irq_enable()
+#define save_flags(flags)	local_save_flags(flags)
+#define restore_flags(flags)	local_irq_restore(flags)
+#define save_and_cli(flags)	local_irq_save(flags)
 
 #endif /* !CONFIG_SMP */
-
-#define local_irq_disable()		__cli()
-#define local_irq_enable()		__sti()
-#define local_irq_save(flags)		__save_and_cli(flags)
-#define local_irq_restore(flags)	__restore_flags(flags)
 
 static __inline__ int __is_processor(unsigned long pv)
 {
diff -Nru a/include/asm-ppc64/time.h b/include/asm-ppc64/time.h
--- a/include/asm-ppc64/time.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-ppc64/time.h	Wed Jul 24 14:03:38 2002
@@ -14,6 +14,7 @@
 #define __PPC64_TIME_H
 
 #ifdef __KERNEL__
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/mc146818rtc.h>
 
diff -Nru a/include/asm-ppc64/tlb.h b/include/asm-ppc64/tlb.h
--- a/include/asm-ppc64/tlb.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-ppc64/tlb.h	Wed Jul 24 14:03:37 2002
@@ -1 +1,86 @@
+/*
+ *	TLB shootdown specifics for PPC64
+ *
+ * Copyright (C) 2002 Anton Blanchard, IBM Corp.
+ * Copyright (C) 2002 Paul Mackerras, IBM Corp.
+ *
+ * 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 _PPC64_TLB_H
+#define _PPC64_TLB_H
+
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+
+struct free_pte_ctx;
+static inline void tlb_flush(struct free_pte_ctx *tlb);
+
+/* Get the generic bits... */
 #include <asm-generic/tlb.h>
+
+/* Nothing needed here in fact... */
+#define tlb_start_vma(tlb, vma)	do { } while (0)
+#define tlb_end_vma(tlb, vma)	do { } while (0)
+
+/* Should make this at least as large as the generic batch size, but it
+ * takes up too much space */
+#define PPC64_TLB_BATCH_NR 192
+
+struct ppc64_tlb_batch {
+	unsigned long index;
+	pte_t pte[PPC64_TLB_BATCH_NR];
+	unsigned long addr[PPC64_TLB_BATCH_NR];
+	unsigned long vaddr[PPC64_TLB_BATCH_NR];
+};
+
+extern struct ppc64_tlb_batch ppc64_tlb_batch[NR_CPUS];
+
+static inline void tlb_remove_tlb_entry(mmu_gather_t *tlb, pte_t *ptep,
+					unsigned long address)
+{
+	int cpu = smp_processor_id();
+	struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[cpu];
+	unsigned long i = batch->index;
+	pte_t pte;
+
+	if (pte_val(*ptep) & _PAGE_HASHPTE) {
+		pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
+		if (pte_val(pte) & _PAGE_HASHPTE) {
+			int local = 0;
+
+			if (tlb->mm->cpu_vm_mask == (1 << cpu))
+				local = 1;
+
+			batch->pte[i] = pte;
+			batch->addr[i] = address;
+			i++;
+
+			if (i == PPC64_TLB_BATCH_NR) {
+				flush_hash_range(tlb->mm->context, i, local);
+				i = 0;
+			}
+		}
+	}
+
+	batch->index = i;
+}
+
+static inline void tlb_flush(struct free_pte_ctx *tlb)
+{
+	int cpu = smp_processor_id();
+	struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[cpu];
+	int local = 0;
+
+	if (tlb->mm->cpu_vm_mask == (1 << smp_processor_id()))
+		local = 1;
+
+	flush_hash_range(tlb->mm->context, batch->index, local);
+	batch->index = 0;
+}
+
+#endif /* _PPC64_TLB_H */
diff -Nru a/include/asm-ppc64/tlbflush.h b/include/asm-ppc64/tlbflush.h
--- a/include/asm-ppc64/tlbflush.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-ppc64/tlbflush.h	Wed Jul 24 14:03:35 2002
@@ -35,12 +35,4 @@
 			    int local);
 void flush_hash_range(unsigned long context, unsigned long number, int local);
 
-/* TLB flush batching */
-#define MAX_BATCH_FLUSH 128
-struct tlb_batch_data {
-	pte_t pte;
-	unsigned long addr;
-};
-extern struct tlb_batch_data tlb_batch_array[NR_CPUS][MAX_BATCH_FLUSH];
-
 #endif /* _PPC64_TLBFLUSH_H */
diff -Nru a/include/asm-ppc64/uaccess.h b/include/asm-ppc64/uaccess.h
--- a/include/asm-ppc64/uaccess.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-ppc64/uaccess.h	Wed Jul 24 14:03:38 2002
@@ -124,9 +124,6 @@
 	}							\
 } while (0)
 
-struct __large_struct { unsigned long buf[100]; };
-#define __m(x) (*(struct __large_struct *)(x))
-
 /*
  * We don't tell gcc that we are accessing memory, but this is OK
  * because we do not write to any memory gcc knows about, so there
diff -Nru a/include/asm-ppc64/vc_ioctl.h b/include/asm-ppc64/vc_ioctl.h
--- a/include/asm-ppc64/vc_ioctl.h	Wed Jul 24 14:03:39 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,50 +0,0 @@
-#ifndef _LINUX_VC_IOCTL_H
-#define _LINUX_VC_IOCTL_H
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-struct vc_mode {
-	int	height;
-	int	width;
-	int	depth;
-	int	pitch;
-	int	mode;
-	char	name[32];
-	unsigned long fb_address;
-	unsigned long cmap_adr_address;
-	unsigned long cmap_data_address;
-	unsigned long disp_reg_address;
-};
-
-#define VC_GETMODE	0x7667
-#define VC_SETMODE	0x7668
-#define VC_INQMODE	0x7669
-
-#define VC_SETCMAP      0x766a
-#define VC_GETCMAP      0x766b
-
-#define VC_POWERMODE	0x766c
-
-/* Values for the argument to the VC_POWERMODE ioctl */
-#define VC_POWERMODE_INQUIRY	(-1)
-#define VESA_NO_BLANKING	0
-#define VESA_VSYNC_SUSPEND	1
-#define VESA_HSYNC_SUSPEND	2
-#define VESA_POWERDOWN		3
-
-#ifdef __KERNEL__
-extern int console_getmode(struct vc_mode *);
-extern int console_setmode(struct vc_mode *, int);
-extern int console_setcmap(int, unsigned char *, unsigned char *,
-			   unsigned char *);
-extern int console_powermode(int);
-extern struct vc_mode display_info;
-extern struct fb_info *console_fb_info;
-#endif
-
-#endif /* _LINUX_VC_IOCTL_H */
diff -Nru a/include/asm-s390/smplock.h b/include/asm-s390/smplock.h
--- a/include/asm-s390/smplock.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-s390/smplock.h	Wed Jul 24 14:03:38 2002
@@ -21,7 +21,7 @@
 	if (task->lock_depth >= 0)         \
 		spin_unlock(&kernel_flag); \
 	release_irqlock(cpu);              \
-	__sti();                           \
+	local_irq_enable();                           \
 } while (0)
 
 /*
diff -Nru a/include/asm-s390/system.h b/include/asm-s390/system.h
--- a/include/asm-s390/system.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-s390/system.h	Wed Jul 24 14:03:39 2002
@@ -18,11 +18,6 @@
 #endif
 #include <linux/kernel.h>
 
-#define prepare_arch_schedule(prev)		do { } while (0)
-#define finish_arch_schedule(prev)		do { } while (0)
-#define prepare_arch_switch(rq)			do { } while (0)
-#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
-
 #define switch_to(prev,next,last) do {					     \
 	if (prev == next)						     \
 		break;							     \
@@ -132,23 +127,23 @@
 #define set_wmb(var, value)     do { var = value; wmb(); } while (0)
 
 /* interrupt control.. */
-#define __sti() ({ \
+#define local_irq_enable() ({ \
         __u8 __dummy; \
         __asm__ __volatile__ ( \
                 "stosm 0(%0),0x03" : : "a" (&__dummy) : "memory"); \
         })
 
-#define __cli() ({ \
+#define local_irq_disable() ({ \
         __u32 __flags; \
         __asm__ __volatile__ ( \
                 "stnsm 0(%0),0xFC" : : "a" (&__flags) : "memory"); \
         __flags; \
         })
 
-#define __save_flags(x) \
+#define local_save_flags(x) \
         __asm__ __volatile__("stosm 0(%0),0" : : "a" (&x) : "memory")
 
-#define __restore_flags(x) \
+#define local_irq_restore(x) \
         __asm__ __volatile__("ssm   0(%0)" : : "a" (&x) : "memory")
 
 #define __load_psw(psw) \
@@ -211,10 +206,7 @@
         })
 
 /* For spinlocks etc */
-#define local_irq_save(x)	((x) = __cli())
-#define local_irq_restore(x)	__restore_flags(x)
-#define local_irq_disable()	__cli()
-#define local_irq_enable()	__sti()
+#define local_irq_save(x)	((x) = local_irq_disable())
 
 #ifdef CONFIG_SMP
 
@@ -235,10 +227,10 @@
 
 #else
 
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
+#define cli() local_irq_disable()
+#define sti() local_irq_enable()
+#define save_flags(x) local_save_flags(x)
+#define restore_flags(x) local_irq_restore(x)
 
 #define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit)
 #define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit)
diff -Nru a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h
--- a/include/asm-s390/tlb.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-s390/tlb.h	Wed Jul 24 14:03:39 2002
@@ -7,7 +7,7 @@
  */
 #define tlb_start_vma(tlb, vma) do { } while (0)
 #define tlb_end_vma(tlb, vma) do { } while (0)
-#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+#define tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
 
 /*
  * .. because we flush the whole mm when it
diff -Nru a/include/asm-s390x/smplock.h b/include/asm-s390x/smplock.h
--- a/include/asm-s390x/smplock.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-s390x/smplock.h	Wed Jul 24 14:03:37 2002
@@ -21,7 +21,7 @@
 	if (task->lock_depth >= 0)         \
 		spin_unlock(&kernel_flag); \
 	release_irqlock(cpu);              \
-	__sti();                           \
+	local_irq_enable();                           \
 } while (0)
 
 /*
diff -Nru a/include/asm-s390x/system.h b/include/asm-s390x/system.h
--- a/include/asm-s390x/system.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-s390x/system.h	Wed Jul 24 14:03:39 2002
@@ -18,11 +18,6 @@
 #endif
 #include <linux/kernel.h>
 
-#define prepare_arch_schedule(prev)		do { } while (0)
-#define finish_arch_schedule(prev)		do { } while (0)
-#define prepare_arch_switch(rq)			do { } while (0)
-#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
-
 #define switch_to(prev,next),last do {					     \
 	if (prev == next)						     \
 		break;							     \
@@ -144,23 +139,23 @@
 #define set_wmb(var, value)     do { var = value; wmb(); } while (0)
 
 /* interrupt control.. */
-#define __sti() ({ \
+#define local_irq_enable() ({ \
         unsigned long __dummy; \
         __asm__ __volatile__ ( \
                 "stosm 0(%0),0x03" : : "a" (&__dummy) : "memory"); \
         })
 
-#define __cli() ({ \
+#define local_irq_disable() ({ \
         unsigned long __flags; \
         __asm__ __volatile__ ( \
                 "stnsm 0(%0),0xFC" : : "a" (&__flags) : "memory"); \
         __flags; \
         })
 
-#define __save_flags(x) \
+#define local_save_flags(x) \
         __asm__ __volatile__("stosm 0(%0),0" : : "a" (&x) : "memory")
 
-#define __restore_flags(x) \
+#define local_irq_restore(x) \
         __asm__ __volatile__("ssm   0(%0)" : : "a" (&x) : "memory")
 
 #define __load_psw(psw) \
@@ -221,10 +216,7 @@
         })
 
 /* For spinlocks etc */
-#define local_irq_save(x)	((x) = __cli())
-#define local_irq_restore(x)	__restore_flags(x)
-#define local_irq_disable()	__cli()
-#define local_irq_enable()	__sti()
+#define local_irq_save(x)	((x) = local_irq_disable())
 
 #ifdef CONFIG_SMP
 
@@ -245,10 +237,10 @@
 
 #else
 
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
+#define cli() local_irq_disable()
+#define sti() local_irq_enable()
+#define save_flags(x) local_save_flags(x)
+#define restore_flags(x) local_irq_restore(x)
 
 #define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit)
 #define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit)
diff -Nru a/include/asm-s390x/tlb.h b/include/asm-s390x/tlb.h
--- a/include/asm-s390x/tlb.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-s390x/tlb.h	Wed Jul 24 14:03:35 2002
@@ -7,7 +7,7 @@
  */
 #define tlb_start_vma(tlb, vma) do { } while (0)
 #define tlb_end_vma(tlb, vma) do { } while (0)
-#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+#define tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
 
 /*
  * .. because we flush the whole mm when it
diff -Nru a/include/asm-sh/system.h b/include/asm-sh/system.h
--- a/include/asm-sh/system.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-sh/system.h	Wed Jul 24 14:03:39 2002
@@ -104,7 +104,7 @@
 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 /* Interrupt Control */
-static __inline__ void __sti(void)
+static __inline__ void local_irq_enable(void)
 {
 	unsigned long __dummy0, __dummy1;
 
@@ -118,7 +118,7 @@
 			     : "memory");
 }
 
-static __inline__ void __cli(void)
+static __inline__ void local_irq_disable(void)
 {
 	unsigned long __dummy;
 	__asm__ __volatile__("stc	sr, %0\n\t"
@@ -129,10 +129,10 @@
 			     : "memory");
 }
 
-#define __save_flags(x) \
+#define local_save_flags(x) \
 	__asm__("stc sr, %0; and #0xf0, %0" : "=&z" (x) :/**/: "memory" )
 
-static __inline__ unsigned long __save_and_cli(void)
+static __inline__ unsigned long local_irq_save(void)
 {
 	unsigned long flags, __dummy;
 
@@ -149,34 +149,34 @@
 }
 
 #ifdef DEBUG_CLI_STI
-static __inline__ void  __restore_flags(unsigned long x)
+static __inline__ void  local_irq_restore(unsigned long x)
 {
 	if ((x & 0x000000f0) != 0x000000f0)
-		__sti();
+		local_irq_enable();
 	else {
 		unsigned long flags;
-		__save_flags(flags);
+		local_save_flags(flags);
 
 		if (flags == 0) {
 			extern void dump_stack(void);
 			printk(KERN_ERR "BUG!\n");
 			dump_stack();
-			__cli();
+			local_irq_disable();
 		}
 	}
 }
 #else
-#define __restore_flags(x) do { 			\
+#define local_irq_restore(x) do { 			\
 	if ((x & 0x000000f0) != 0x000000f0)		\
-		__sti();				\
+		local_irq_enable();				\
 } while (0)
 #endif
 
 #define really_restore_flags(x) do { 			\
 	if ((x & 0x000000f0) != 0x000000f0)		\
-		__sti();				\
+		local_irq_enable();				\
 	else						\
-		__cli();				\
+		local_irq_disable();				\
 } while (0)
 
 /*
@@ -216,10 +216,7 @@
 } while (0)
 
 /* For spinlocks etc */
-#define local_irq_save(x)	x = __save_and_cli()
-#define local_irq_restore(x)	__restore_flags(x)
-#define local_irq_disable()	__cli()
-#define local_irq_enable()	__sti()
+#define local_irq_save(x)	x = local_irq_save()
 
 #ifdef CONFIG_SMP
 
@@ -234,11 +231,11 @@
 
 #else
 
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define save_and_cli(x) x = __save_and_cli()
-#define restore_flags(x) __restore_flags(x)
+#define cli() local_irq_disable()
+#define sti() local_irq_enable()
+#define save_flags(x) local_save_flags(x)
+#define save_and_cli(x) x = local_irq_save()
+#define restore_flags(x) local_irq_restore(x)
 
 #endif
 
diff -Nru a/include/asm-sparc/smplock.h b/include/asm-sparc/smplock.h
--- a/include/asm-sparc/smplock.h	Wed Jul 24 14:03:38 2002
+++ b/include/asm-sparc/smplock.h	Wed Jul 24 14:03:38 2002
@@ -21,7 +21,7 @@
 	if (unlikely(task->lock_depth >= 0)) {	\
 		spin_unlock(&kernel_flag);	\
 		release_irqlock(cpu);		\
-		__sti();			\
+		local_irq_enable();			\
 	}					\
 } while (0)
 
diff -Nru a/include/asm-sparc/softirq.h b/include/asm-sparc/softirq.h
--- a/include/asm-sparc/softirq.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-sparc/softirq.h	Wed Jul 24 14:03:35 2002
@@ -19,7 +19,7 @@
 do { if (!--local_bh_count(smp_processor_id()) && \
 	 softirq_pending(smp_processor_id())) {   \
 		do_softirq();			  \
-		__sti();			  \
+		local_irq_enable();			  \
      }						  \
 } while (0)
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
diff -Nru a/include/asm-sparc/spinlock.h b/include/asm-sparc/spinlock.h
--- a/include/asm-sparc/spinlock.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-sparc/spinlock.h	Wed Jul 24 14:03:39 2002
@@ -58,30 +58,30 @@
 
 #define read_lock(lock)	\
 do {	unsigned long flags; \
-	__save_and_cli(flags); \
+	local_irq_save(flags); \
 	_do_read_lock(lock, "read_lock"); \
-	__restore_flags(flags); \
+	local_irq_restore(flags); \
 } while(0)
 
 #define read_unlock(lock) \
 do {	unsigned long flags; \
-	__save_and_cli(flags); \
+	local_irq_save(flags); \
 	_do_read_unlock(lock, "read_unlock"); \
-	__restore_flags(flags); \
+	local_irq_restore(flags); \
 } while(0)
 
 #define write_lock(lock) \
 do {	unsigned long flags; \
-	__save_and_cli(flags); \
+	local_irq_save(flags); \
 	_do_write_lock(lock, "write_lock"); \
-	__restore_flags(flags); \
+	local_irq_restore(flags); \
 } while(0)
 
 #define write_unlock(lock) \
 do {	unsigned long flags; \
-	__save_and_cli(flags); \
+	local_irq_save(flags); \
 	_do_write_unlock(lock); \
-	__restore_flags(flags); \
+	local_irq_restore(flags); \
 } while(0)
 
 #else /* !SPIN_LOCK_DEBUG */
@@ -180,9 +180,9 @@
 
 #define read_lock(lock) \
 do {	unsigned long flags; \
-	__save_and_cli(flags); \
+	local_irq_save(flags); \
 	_read_lock(lock); \
-	__restore_flags(flags); \
+	local_irq_restore(flags); \
 } while(0)
 
 extern __inline__ void _read_unlock(rwlock_t *rw)
@@ -200,9 +200,9 @@
 
 #define read_unlock(lock) \
 do {	unsigned long flags; \
-	__save_and_cli(flags); \
+	local_irq_save(flags); \
 	_read_unlock(lock); \
-	__restore_flags(flags); \
+	local_irq_restore(flags); \
 } while(0)
 
 extern __inline__ void write_lock(rwlock_t *rw)
diff -Nru a/include/asm-sparc/system.h b/include/asm-sparc/system.h
--- a/include/asm-sparc/system.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-sparc/system.h	Wed Jul 24 14:03:39 2002
@@ -164,7 +164,7 @@
 		: "memory", "cc");
 }
 
-extern __inline__ void __cli(void)
+extern __inline__ void local_irq_disable(void)
 {
 	unsigned long tmp;
 
@@ -179,7 +179,7 @@
 		: "memory");
 }
 
-extern __inline__ void __sti(void)
+extern __inline__ void local_irq_enable(void)
 {
 	unsigned long tmp;
 
@@ -241,13 +241,9 @@
 	return retval;
 }
 
-#define __save_flags(flags)	((flags) = getipl())
-#define __save_and_cli(flags)	((flags) = read_psr_and_cli())
-#define __restore_flags(flags)	setipl((flags))
-#define local_irq_disable()		__cli()
-#define local_irq_enable()		__sti()
-#define local_irq_save(flags)		__save_and_cli(flags)
-#define local_irq_restore(flags)	__restore_flags(flags)
+#define local_save_flags(flags)	((flags) = getipl())
+#define local_irq_save(flags)	((flags) = read_psr_and_cli())
+#define local_irq_restore(flags)	setipl((flags))
 
 #ifdef CONFIG_SMP
 
@@ -266,11 +262,11 @@
 
 #else
 
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
-#define save_and_cli(x) __save_and_cli(x)
+#define cli() local_irq_disable()
+#define sti() local_irq_enable()
+#define save_flags(x) local_save_flags(x)
+#define restore_flags(x) local_irq_restore(x)
+#define save_and_cli(x) local_irq_save(x)
 
 #endif
 
diff -Nru a/include/asm-sparc64/smplock.h b/include/asm-sparc64/smplock.h
--- a/include/asm-sparc64/smplock.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-sparc64/smplock.h	Wed Jul 24 14:03:39 2002
@@ -29,7 +29,7 @@
 	if (unlikely(task->lock_depth >= 0)) {	\
 		spin_unlock(&kernel_flag);	\
 		release_irqlock(cpu);		\
-		__sti();			\
+		local_irq_enable();			\
 	}					\
 } while (0)
 
diff -Nru a/include/asm-sparc64/softirq.h b/include/asm-sparc64/softirq.h
--- a/include/asm-sparc64/softirq.h	Wed Jul 24 14:03:39 2002
+++ b/include/asm-sparc64/softirq.h	Wed Jul 24 14:03:39 2002
@@ -16,7 +16,7 @@
 do { if (!--local_bh_count(smp_processor_id()) && \
 	 softirq_pending(smp_processor_id())) {   \
 		do_softirq();			  \
-		__sti();			  \
+		local_irq_enable();			  \
      }						  \
      preempt_enable();				  \
 } while (0)
diff -Nru a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
--- a/include/asm-sparc64/spinlock.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-sparc64/spinlock.h	Wed Jul 24 14:03:36 2002
@@ -140,30 +140,30 @@
 
 #define _raw_read_lock(lock) \
 do {	unsigned long flags; \
-	__save_and_cli(flags); \
+	local_irq_save(flags); \
 	_do_read_lock(lock, "read_lock"); \
-	__restore_flags(flags); \
+	local_irq_restore(flags); \
 } while(0)
 
 #define _raw_read_unlock(lock) \
 do {	unsigned long flags; \
-	__save_and_cli(flags); \
+	local_irq_save(flags); \
 	_do_read_unlock(lock, "read_unlock"); \
-	__restore_flags(flags); \
+	local_irq_restore(flags); \
 } while(0)
 
 #define _raw_write_lock(lock) \
 do {	unsigned long flags; \
-	__save_and_cli(flags); \
+	local_irq_save(flags); \
 	_do_write_lock(lock, "write_lock"); \
-	__restore_flags(flags); \
+	local_irq_restore(flags); \
 } while(0)
 
 #define _raw_write_unlock(lock) \
 do {	unsigned long flags; \
-	__save_and_cli(flags); \
+	local_irq_save(flags); \
 	_do_write_unlock(lock); \
-	__restore_flags(flags); \
+	local_irq_restore(flags); \
 } while(0)
 
 #endif /* CONFIG_DEBUG_SPINLOCK */
diff -Nru a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
--- a/include/asm-sparc64/system.h	Wed Jul 24 14:03:35 2002
+++ b/include/asm-sparc64/system.h	Wed Jul 24 14:03:35 2002
@@ -34,10 +34,10 @@
 #define setipl(__new_ipl) \
 	__asm__ __volatile__("wrpr	%0, %%pil"  : : "r" (__new_ipl) : "memory")
 
-#define __cli() \
+#define local_irq_disable() \
 	__asm__ __volatile__("wrpr	15, %%pil" : : : "memory")
 
-#define __sti() \
+#define local_irq_enable() \
 	__asm__ __volatile__("wrpr	0, %%pil" : : : "memory")
 
 #define getipl() \
@@ -62,20 +62,16 @@
 	retval; \
 })
 
-#define __save_flags(flags)		((flags) = getipl())
-#define __save_and_cli(flags)		((flags) = read_pil_and_cli())
-#define __restore_flags(flags)		setipl((flags))
-#define local_irq_disable()		__cli()
-#define local_irq_enable()		__sti()
-#define local_irq_save(flags)		__save_and_cli(flags)
-#define local_irq_restore(flags)	__restore_flags(flags)
+#define local_save_flags(flags)		((flags) = getipl())
+#define local_irq_save(flags)		((flags) = read_pil_and_cli())
+#define local_irq_restore(flags)		setipl((flags))
 
 #ifndef CONFIG_SMP
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
-#define save_and_cli(x) __save_and_cli(x)
+#define cli() local_irq_disable()
+#define sti() local_irq_enable()
+#define save_flags(x) local_save_flags(x)
+#define restore_flags(x) local_irq_restore(x)
+#define save_and_cli(x) local_irq_save(x)
 #else
 
 #ifndef __ASSEMBLY__
@@ -144,13 +140,17 @@
 #define flush_user_windows flushw_user
 #define flush_register_windows flushw_all
 
-#define prepare_arch_schedule(prev)	task_lock(prev)
-#define finish_arch_schedule(prev)	task_unlock(prev)
-#define prepare_arch_switch(rq)		\
-do {	spin_unlock(&(rq)->lock);	\
-	flushw_all();			\
+#define prepare_arch_switch(rq, next)		\
+do {	spin_lock(&(next)->switch_lock);	\
+	spin_unlock(&(rq)->lock);		\
+	flushw_all();				\
 } while (0)
-#define finish_arch_switch(rq)		__sti()
+
+#define finish_arch_switch(rq, prev)		\
+do {	spin_unlock_irq(&(prev)->switch_lock);	\
+} while (0)
+
+
 
 #ifndef CONFIG_DEBUG_SPINLOCK
 #define CHECK_LOCKS(PREV)	do { } while(0)
diff -Nru a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h
--- a/include/asm-sparc64/tlb.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-sparc64/tlb.h	Wed Jul 24 14:03:36 2002
@@ -16,7 +16,7 @@
 		flush_tlb_range(vma, vma->vm_start, vma->vm_end); \
 } while (0)
 
-#define tlb_remove_tlb_entry(tlb, pte, address) \
+#define tlb_remove_tlb_entry(tlb, ptep, address) \
 	do { } while (0)
 
 #include <asm-generic/tlb.h>
diff -Nru a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
--- a/include/asm-x86_64/system.h	Wed Jul 24 14:03:37 2002
+++ b/include/asm-x86_64/system.h	Wed Jul 24 14:03:37 2002
@@ -13,11 +13,6 @@
 #define LOCK_PREFIX ""
 #endif
 
-#define prepare_arch_schedule(prev)            do { } while(0)
-#define finish_arch_schedule(prev)             do { } while(0)
-#define prepare_arch_switch(rq)                        do { } while(0)
-#define finish_arch_switch(rq)                 spin_unlock_irq(&(rq)->lock)
-
 #define __STR(x) #x
 #define STR(x) __STR(x)
 
@@ -240,18 +235,16 @@
 #define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
 
 /* interrupt control.. */
-#define __save_flags(x)		do { warn_if_not_ulong(x); __asm__ __volatile__("# save_flags \n\t pushfq ; popq %q0":"=g" (x): /* no input */ :"memory"); } while (0)
-#define __restore_flags(x) 	__asm__ __volatile__("# restore_flags \n\t pushq %0 ; popfq": /* no output */ :"g" (x):"memory", "cc")
-#define __cli() 		__asm__ __volatile__("cli": : :"memory")
-#define __sti()			__asm__ __volatile__("sti": : :"memory")
+#define local_save_flags(x)	do { warn_if_not_ulong(x); __asm__ __volatile__("# save_flags \n\t pushfq ; popq %q0":"=g" (x): /* no input */ :"memory"); } while (0)
+#define local_irq_restore(x) 	__asm__ __volatile__("# restore_flags \n\t pushq %0 ; popfq": /* no output */ :"g" (x):"memory", "cc")
+#define local_irq_disable() 	__asm__ __volatile__("cli": : :"memory")
+#define local_irq_enable()	__asm__ __volatile__("sti": : :"memory")
 /* used in the idle loop; sti takes one instruction cycle to complete */
 #define safe_halt()		__asm__ __volatile__("sti; hlt": : :"memory")
 
 /* For spinlocks etc */
 #define local_irq_save(x) 	do { warn_if_not_ulong(x); __asm__ __volatile__("# local_irq_save \n\t pushfq ; popq %0 ; cli":"=g" (x): /* no input */ :"memory"); } while (0)
 #define local_irq_restore(x)	__asm__ __volatile__("# local_irq_restore \n\t pushq %0 ; popfq": /* no output */ :"g" (x):"memory")
-#define local_irq_disable()	__cli()
-#define local_irq_enable()	__sti()
 
 #ifdef CONFIG_SMP
 
@@ -266,10 +259,10 @@
 
 #else
 
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
+#define cli() local_irq_disable()
+#define sti() local_irq_enable()
+#define save_flags(x) local_save_flags(x)
+#define restore_flags(x) local_irq_restore(x)
 
 #endif
 
diff -Nru a/include/asm-x86_64/tlb.h b/include/asm-x86_64/tlb.h
--- a/include/asm-x86_64/tlb.h	Wed Jul 24 14:03:36 2002
+++ b/include/asm-x86_64/tlb.h	Wed Jul 24 14:03:36 2002
@@ -4,7 +4,7 @@
 
 #define tlb_start_vma(tlb, vma) do { } while (0)
 #define tlb_end_vma(tlb, vma) do { } while (0)
-#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+#define tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
 
 #define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
 
diff -Nru a/include/linux/adfs_fs.h b/include/linux/adfs_fs.h
--- a/include/linux/adfs_fs.h	Wed Jul 24 14:03:39 2002
+++ b/include/linux/adfs_fs.h	Wed Jul 24 14:03:39 2002
@@ -68,7 +68,7 @@
 
 static inline struct adfs_inode_info *ADFS_I(struct inode *inode)
 {
-	return list_entry(inode, struct adfs_inode_info, vfs_inode);
+	return container_of(inode, struct adfs_inode_info, vfs_inode);
 }
 
 #endif
diff -Nru a/include/linux/bio.h b/include/linux/bio.h
--- a/include/linux/bio.h	Wed Jul 24 14:03:39 2002
+++ b/include/linux/bio.h	Wed Jul 24 14:03:39 2002
@@ -215,7 +215,7 @@
 {
 	unsigned long addr;
 
-	__save_flags(*flags);
+	local_save_flags(*flags);
 
 	/*
 	 * could be low
@@ -226,7 +226,7 @@
 	/*
 	 * it's a highmem page
 	 */
-	__cli();
+	local_irq_disable();
 	addr = (unsigned long) kmap_atomic(bio_page(bio), KM_BIO_SRC_IRQ);
 
 	if (addr & ~PAGE_MASK)
@@ -240,7 +240,7 @@
 	unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
 
 	kunmap_atomic((void *) ptr, KM_BIO_SRC_IRQ);
-	__restore_flags(*flags);
+	local_irq_restore(*flags);
 }
 
 #else
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	Wed Jul 24 14:03:36 2002
+++ b/include/linux/blkdev.h	Wed Jul 24 14:03:36 2002
@@ -295,6 +295,7 @@
 extern int block_ioctl(struct block_device *, unsigned int, unsigned long);
 extern void blk_start_queue(request_queue_t *q);
 extern void blk_stop_queue(request_queue_t *q);
+extern void __blk_stop_queue(request_queue_t *q);
 
 /*
  * get ready for proper ref counting
@@ -387,20 +388,6 @@
 extern inline unsigned int block_size(struct block_device *bdev)
 {
 	return bdev->bd_block_size;
-}
-
-static inline loff_t blkdev_size_in_bytes(kdev_t dev)
-{
-#if 0
-	if (blk_size_in_bytes[major(dev)])
-		return blk_size_in_bytes[major(dev)][minor(dev)];
-	else
-#endif
-	if (blk_size[major(dev)])
-		return (loff_t) blk_size[major(dev)][minor(dev)]
-			<< BLOCK_SIZE_BITS;
-	else
-		return 0;
 }
 
 typedef struct {struct page *v;} Sector;
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	Wed Jul 24 14:03:37 2002
+++ b/include/linux/device.h	Wed Jul 24 14:03:37 2002
@@ -160,6 +160,8 @@
 	void	(*release)(struct device * dev);
 };
 
+#define to_device(d) container_of(d, struct device, dir)
+
 static inline struct device *
 list_to_dev(struct list_head *node)
 {
diff -Nru a/include/linux/dio.h b/include/linux/dio.h
--- a/include/linux/dio.h	Wed Jul 24 14:03:39 2002
+++ b/include/linux/dio.h	Wed Jul 24 14:03:39 2002
@@ -72,16 +72,16 @@
 #define DIO_SCINHOLE(scode) (((scode) >= 32) && ((scode) < DIOII_SCBASE))
 
 /* macros to read device IDs, given base address */
-#define DIO_ID(baseaddr) readb((baseaddr) + DIO_IDOFF)
-#define DIO_SECID(baseaddr) readb((baseaddr) + DIO_SECIDOFF)
+#define DIO_ID(baseaddr) in_8((baseaddr) + DIO_IDOFF)
+#define DIO_SECID(baseaddr) in_8((baseaddr) + DIO_SECIDOFF)
 
 /* extract the interrupt level */
-#define DIO_IPL(baseaddr) (((readb((baseaddr) + DIO_IPLOFF) >> 4) & 0x03) + 3)
+#define DIO_IPL(baseaddr) (((in_8((baseaddr) + DIO_IPLOFF) >> 4) & 0x03) + 3)
 
 /* find the size of a DIO-II board's address space.
  * DIO boards are all fixed length.
  */
-#define DIOII_SIZE(baseaddr) ((readb((baseaddr) + DIOII_SIZEOFF) + 1) * 0x100000)
+#define DIOII_SIZE(baseaddr) ((in_8((baseaddr) + DIOII_SIZEOFF) + 1) * 0x100000)
 
 /* general purpose macro for both DIO and DIO-II */
 #define DIO_SIZE(scode, base) (DIO_ISDIOII((scode)) ? DIOII_SIZE((base)) : DIO_DEVSIZE)
@@ -109,7 +109,7 @@
 #define DIO_ID_DCMREM   0x85 /* 98642A serial MUX */
 #define DIO_DESC_DCMREM "98642A DCMREM serial MUX"
 #define DIO_ID_LAN      0x15 /* 98643A LAN */
-#define DIO_DESC_LAN "98643A LAN"
+#define DIO_DESC_LAN "98643A LANCE ethernet"
 #define DIO_ID_FHPIB    0x08 /* 98625A/98625B fast HP-IB */
 #define DIO_DESC_FHPIB "98625A/98625B fast HPIB"
 #define DIO_ID_NHPIB    0x80 /* 98624A HP-IB (normal ie slow) */
@@ -192,10 +192,10 @@
  * identify them...
  */
 
-extern void dio_init(void);
 extern int dio_find(int deviceid);
 extern void *dio_scodetoviraddr(int scode);
 extern int dio_scodetoipl(int scode);
+extern const char *dio_scodetoname(int scode);
 extern void dio_config_board(int scode);
 extern void dio_unconfig_board(int scode);
 
diff -Nru a/include/linux/efs_fs.h b/include/linux/efs_fs.h
--- a/include/linux/efs_fs.h	Wed Jul 24 14:03:37 2002
+++ b/include/linux/efs_fs.h	Wed Jul 24 14:03:37 2002
@@ -41,7 +41,7 @@
 
 static inline struct efs_inode_info *INODE_INFO(struct inode *inode)
 {
-	return list_entry(inode, struct efs_inode_info, vfs_inode);
+	return container_of(inode, struct efs_inode_info, vfs_inode);
 }
 
 static inline struct efs_sb_info *SUPER_INFO(struct super_block *sb)
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
--- a/include/linux/ext3_fs.h	Wed Jul 24 14:03:35 2002
+++ b/include/linux/ext3_fs.h	Wed Jul 24 14:03:35 2002
@@ -447,7 +447,7 @@
 #define EXT3_SB(sb)	(&((sb)->u.ext3_sb))
 static inline struct ext3_inode_info *EXT3_I(struct inode *inode)
 {
-	return list_entry(inode, struct ext3_inode_info, vfs_inode);
+	return container_of(inode, struct ext3_inode_info, vfs_inode);
 }
 #else
 /* Assume that user mode programs are passing in an ext3fs superblock, not
diff -Nru a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h	Wed Jul 24 14:03:37 2002
+++ b/include/linux/fb.h	Wed Jul 24 14:03:37 2002
@@ -304,7 +304,6 @@
 #include <linux/devfs_fs_kernel.h>
 
 struct fb_info;
-struct fb_info_gen;
 struct vm_area_struct;
 struct file;
 
@@ -397,66 +396,20 @@
 #endif
 
     /*
-     *  This structure abstracts from the underlying hardware. It is not
-     *  mandatory but used by the `generic' frame buffer operations.
-     *  Read drivers/video/skeletonfb.c for more information.
-     */
-
-struct fbgen_hwswitch {
-    void (*detect)(void);
-    int (*encode_fix)(struct fb_fix_screeninfo *fix, const void *par,
-		      struct fb_info_gen *info);
-    int (*decode_var)(const struct fb_var_screeninfo *var, void *par,
-		      struct fb_info_gen *info);
-    int (*encode_var)(struct fb_var_screeninfo *var, const void *par,
-		      struct fb_info_gen *info);
-    void (*get_par)(void *par, struct fb_info_gen *info);
-    void (*set_par)(const void *par, struct fb_info_gen *info);
-    int (*getcolreg)(unsigned regno, unsigned *red, unsigned *green,
-		     unsigned *blue, unsigned *transp, struct fb_info *info);
-    int (*pan_display)(const struct fb_var_screeninfo *var,
-		       struct fb_info_gen *info);
-    int (*blank)(int blank_mode, struct fb_info_gen *info);
-    void (*set_disp)(const void *par, struct display *disp,
-		     struct fb_info_gen *info);
-};
-
-struct fb_info_gen {
-    struct fb_info info;
-
-    /* Entries for a generic frame buffer device */
-    /* Yes, this starts looking like C++ */
-    u_int parsize;
-    struct fbgen_hwswitch *fbhw;
-
-   /* From here on everything is device dependent */
-};
-
-    /*
      *  `Generic' versions of the frame buffer device operations
      */
 
-extern int fbgen_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info);
 extern int gen_get_fix(struct fb_fix_screeninfo *fix, int con,
 		       struct fb_info *info);
-extern int fbgen_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info);
 extern int gen_get_var(struct fb_var_screeninfo *var, int con,
 		       struct fb_info *info);
-extern int fbgen_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info);
 extern int gen_set_var(struct fb_var_screeninfo *var, int con,
 		       struct fb_info *info);
-extern int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info);
 extern int gen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
 			struct fb_info *info);
-extern int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info);
 extern int gen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
 			struct fb_info *info);
-extern int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
+extern int fb_pan_display(struct fb_var_screeninfo *var, int con,
 			     struct fb_info *info);
 extern void cfb_fillrect(struct fb_info *info, struct fb_fillrect *rect); 
 extern void cfb_copyarea(struct fb_info *info, struct fb_copyarea *region); 
@@ -466,16 +419,9 @@
      *  Helper functions
      */
 
-extern int fbgen_do_set_var(struct fb_var_screeninfo *var, int isactive,
-			    struct fb_info_gen *info);
-extern void fbgen_set_disp(int con, struct fb_info_gen *info);
-extern void do_install_cmap(int con, struct fb_info *info);
-extern int fbgen_update_var(int con, struct fb_info *info);
 extern int gen_update_var(int con, struct fb_info *info);
-extern int fbgen_switch(int con, struct fb_info *info);
-extern int fbgen_blank(int blank, struct fb_info *info);
+extern int fb_blank(int blank, struct fb_info *info);
 extern int gen_switch(int con, struct fb_info *info);
-
 extern void gen_set_disp(int con, struct fb_info *info);
 
 /* drivers/video/fbmem.c */
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Wed Jul 24 14:03:36 2002
+++ b/include/linux/fs.h	Wed Jul 24 14:03:36 2002
@@ -342,7 +342,7 @@
 	struct inode *		bd_inode;
 	dev_t			bd_dev;  /* not a kdev_t - it's a search key */
 	int			bd_openers;
-	const struct block_device_operations *bd_op;
+	struct block_device_operations *bd_op;
 	struct request_queue	*bd_queue;
 	struct semaphore	bd_sem;	/* open/close mutex */
 	struct list_head	bd_inodes;
@@ -350,6 +350,9 @@
 	int			bd_holders;
 	struct block_device *	bd_contains;
 	unsigned		bd_block_size;
+	unsigned long		bd_offset;
+	struct semaphore	bd_part_sem;
+	unsigned		bd_part_count;
 };
 
 struct inode {
@@ -409,12 +412,12 @@
 
 static inline struct socket *SOCKET_I(struct inode *inode)
 {
-	return &list_entry(inode, struct socket_alloc, vfs_inode)->socket;
+	return &container_of(inode, struct socket_alloc, vfs_inode)->socket;
 }
 
 static inline struct inode *SOCK_INODE(struct socket *socket)
 {
-	return &list_entry(socket, struct socket_alloc, socket)->vfs_inode;
+	return &container_of(socket, struct socket_alloc, socket)->vfs_inode;
 }
 
 /* will die */
@@ -1082,7 +1085,7 @@
 extern void blk_run_queues(void);
 
 /* fs/devices.c */
-extern const struct block_device_operations *get_blkfops(unsigned int);
+extern struct block_device_operations *get_blkfops(unsigned int);
 extern int register_chrdev(unsigned int, const char *, struct file_operations *);
 extern int unregister_chrdev(unsigned int, const char *);
 extern int chrdev_open(struct inode *, struct file *);
@@ -1290,6 +1293,32 @@
 	res = dentry->d_parent->d_inode->i_ino;
 	read_unlock(&dparent_lock);
 	return res;
+}
+
+/* NOTE NOTE NOTE: this interface _will_ change in a couple of patches */
+
+static inline int dev_lock_part(kdev_t dev)
+{
+	struct block_device *bdev = bdget(kdev_t_to_nr(dev));
+	if (!bdev)
+		return -ENOMEM;
+	if (!down_trylock(&bdev->bd_part_sem)) {
+		if (!bdev->bd_part_count)
+			return 0;
+		up(&bdev->bd_part_sem);
+	}
+	bdput(bdev);
+	return -EBUSY;
+}
+
+static inline void dev_unlock_part(kdev_t dev)
+{
+	struct block_device *bdev = bdget(kdev_t_to_nr(dev));
+	if (!bdev)
+		BUG();
+	up(&bdev->bd_part_sem);
+	bdput(bdev);
+	bdput(bdev);
 }
 
 #endif /* __KERNEL__ */
diff -Nru a/include/linux/generic_serial.h b/include/linux/generic_serial.h
--- a/include/linux/generic_serial.h	Wed Jul 24 14:03:39 2002
+++ b/include/linux/generic_serial.h	Wed Jul 24 14:03:39 2002
@@ -45,7 +45,7 @@
   int                     count;
   int                     blocked_open;
   struct tty_struct       *tty;
-  int                     event;
+  unsigned long           event;
   unsigned short          closing_wait;
   int                     close_delay;
   struct real_driver      *rd;
diff -Nru a/include/linux/genhd.h b/include/linux/genhd.h
--- a/include/linux/genhd.h	Wed Jul 24 14:03:36 2002
+++ b/include/linux/genhd.h	Wed Jul 24 14:03:36 2002
@@ -90,8 +90,10 @@
 extern void add_gendisk(struct gendisk *gp);
 extern void del_gendisk(struct gendisk *gp);
 extern struct gendisk *get_gendisk(kdev_t dev);
-extern unsigned long get_start_sect(kdev_t dev);
-extern unsigned long get_nr_sects(kdev_t dev);
+static inline unsigned long get_start_sect(struct block_device *bdev)
+{
+	return bdev->bd_offset;
+}
 
 #endif  /*  __KERNEL__  */
 
diff -Nru a/include/linux/hfs_fs.h b/include/linux/hfs_fs.h
--- a/include/linux/hfs_fs.h	Wed Jul 24 14:03:39 2002
+++ b/include/linux/hfs_fs.h	Wed Jul 24 14:03:39 2002
@@ -322,7 +322,7 @@
 
 static inline struct hfs_inode_info *HFS_I(struct inode *inode)
 {
-	return list_entry(inode, struct hfs_inode_info, vfs_inode);
+	return container_of(inode, struct hfs_inode_info, vfs_inode);
 }
 
 static inline struct hfs_sb_info *HFS_SB(struct super_block *sb)
diff -Nru a/include/linux/init_task.h b/include/linux/init_task.h
--- a/include/linux/init_task.h	Wed Jul 24 14:03:36 2002
+++ b/include/linux/init_task.h	Wed Jul 24 14:03:36 2002
@@ -47,7 +47,7 @@
     lock_depth:		-1,						\
     prio:		MAX_PRIO-20,					\
     static_prio:	MAX_PRIO-20,					\
-    policy:		SCHED_OTHER,					\
+    policy:		SCHED_NORMAL,					\
     cpus_allowed:	-1,						\
     mm:			NULL,						\
     active_mm:		&init_mm,					\
@@ -78,6 +78,7 @@
     pending:		{ NULL, &tsk.pending.head, {{0}}},		\
     blocked:		{{0}},						\
     alloc_lock:		SPIN_LOCK_UNLOCKED,				\
+    switch_lock:	SPIN_LOCK_UNLOCKED,				\
     journal_info:	NULL,						\
 }
 
diff -Nru a/include/linux/intermezzo_fs.h b/include/linux/intermezzo_fs.h
--- a/include/linux/intermezzo_fs.h	Wed Jul 24 14:03:38 2002
+++ b/include/linux/intermezzo_fs.h	Wed Jul 24 14:03:38 2002
@@ -19,6 +19,7 @@
 #ifdef __KERNEL__
 #include <linux/smp.h>
 #include <linux/fsfilter.h>
+#include <linux/namei.h>
 
 /* fixups for fs.h */
 #ifndef fs_down
diff -Nru a/include/linux/interrupt.h b/include/linux/interrupt.h
--- a/include/linux/interrupt.h	Wed Jul 24 14:03:35 2002
+++ b/include/linux/interrupt.h	Wed Jul 24 14:03:35 2002
@@ -44,6 +44,16 @@
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
 
+/*
+ * Temporary defines for UP kernels, until all code gets fixed.
+ */
+#if !CONFIG_SMP
+# define cli()			local_irq_disable()
+# define sti()			local_irq_enable()
+# define save_flags(x)		local_irq_save(x)
+# define restore_flags(x)	local_irq_restore(x)
+# define save_and_cli(x)	local_irq_save_off(x)
+#endif
 
 
 /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
diff -Nru a/include/linux/irq_cpustat.h b/include/linux/irq_cpustat.h
--- a/include/linux/irq_cpustat.h	Wed Jul 24 14:03:37 2002
+++ b/include/linux/irq_cpustat.h	Wed Jul 24 14:03:37 2002
@@ -29,8 +29,6 @@
 
   /* arch independent irq_stat fields */
 #define softirq_pending(cpu)	__IRQ_STAT((cpu), __softirq_pending)
-#define local_irq_count(cpu)	__IRQ_STAT((cpu), __local_irq_count)
-#define local_bh_count(cpu)	__IRQ_STAT((cpu), __local_bh_count)
 #define syscall_count(cpu)	__IRQ_STAT((cpu), __syscall_count)
 #define ksoftirqd_task(cpu)	__IRQ_STAT((cpu), __ksoftirqd_task)
   /* arch dependent irq_stat fields */
diff -Nru a/include/linux/iso_fs.h b/include/linux/iso_fs.h
--- a/include/linux/iso_fs.h	Wed Jul 24 14:03:38 2002
+++ b/include/linux/iso_fs.h	Wed Jul 24 14:03:38 2002
@@ -179,7 +179,7 @@
 
 static inline struct iso_inode_info *ISOFS_I(struct inode *inode)
 {
-	return list_entry(inode, struct iso_inode_info, vfs_inode);
+	return container_of(inode, struct iso_inode_info, vfs_inode);
 }
 
 static inline int isonum_711(char *p)
diff -Nru a/include/linux/kernel.h b/include/linux/kernel.h
--- a/include/linux/kernel.h	Wed Jul 24 14:03:35 2002
+++ b/include/linux/kernel.h	Wed Jul 24 14:03:35 2002
@@ -150,6 +150,19 @@
 #define max_t(type,x,y) \
 	({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
 
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr:	the pointer to the member.
+ * @type:	the type of the container struct this is embedded in.
+ * @member:	the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({			\
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+
 #endif /* __KERNEL__ */
 
 #define SI_LOAD_SHIFT	16
diff -Nru a/include/linux/list.h b/include/linux/list.h
--- a/include/linux/list.h	Wed Jul 24 14:03:35 2002
+++ b/include/linux/list.h	Wed Jul 24 14:03:35 2002
@@ -184,7 +184,7 @@
  * @member:	the name of the list_struct within the struct.
  */
 #define list_entry(ptr, type, member) \
-	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+	container_of(ptr, type, member)
 
 /**
  * list_for_each	-	iterate over a list
diff -Nru a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
--- a/include/linux/msdos_fs.h	Wed Jul 24 14:03:39 2002
+++ b/include/linux/msdos_fs.h	Wed Jul 24 14:03:39 2002
@@ -198,7 +198,7 @@
 
 static inline struct msdos_inode_info *MSDOS_I(struct inode *inode)
 {
-	return list_entry(inode, struct msdos_inode_info, vfs_inode);
+	return container_of(inode, struct msdos_inode_info, vfs_inode);
 }
 
 struct fat_cache {
diff -Nru a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h
--- a/include/linux/ncp_fs.h	Wed Jul 24 14:03:36 2002
+++ b/include/linux/ncp_fs.h	Wed Jul 24 14:03:36 2002
@@ -199,7 +199,7 @@
 #define NCP_SERVER(inode)	NCP_SBP((inode)->i_sb)
 static inline struct ncp_inode_info *NCP_FINFO(struct inode *inode)
 {
-	return list_entry(inode, struct ncp_inode_info, vfs_inode);
+	return container_of(inode, struct ncp_inode_info, vfs_inode);
 }
 
 #ifdef DEBUG_NCP_MALLOC
diff -Nru a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
--- a/include/linux/nfs_fs.h	Wed Jul 24 14:03:37 2002
+++ b/include/linux/nfs_fs.h	Wed Jul 24 14:03:37 2002
@@ -176,7 +176,7 @@
 
 static inline struct nfs_inode *NFS_I(struct inode *inode)
 {
-	return list_entry(inode, struct nfs_inode, vfs_inode);
+	return container_of(inode, struct nfs_inode, vfs_inode);
 }
 #define NFS_SB(s)		((struct nfs_server *)(s->u.generic_sbp))
 
diff -Nru a/include/linux/nubus.h b/include/linux/nubus.h
--- a/include/linux/nubus.h	Wed Jul 24 14:03:39 2002
+++ b/include/linux/nubus.h	Wed Jul 24 14:03:39 2002
@@ -12,6 +12,10 @@
 #ifndef LINUX_NUBUS_H
 #define LINUX_NUBUS_H
 
+#ifdef __KERNEL__
+#include <asm/nubus.h>
+#endif
+
 enum nubus_category {
 	NUBUS_CAT_BOARD          = 0x0001,
 	NUBUS_CAT_DISPLAY        = 0x0003,
@@ -262,7 +266,6 @@
 extern struct nubus_board* nubus_boards;
 
 /* Generic NuBus interface functions, modelled after the PCI interface */
-extern void nubus_init(void);
 void nubus_scan_bus(void);
 extern void nubus_proc_init(void);
 int get_nubus_list(char *buf);
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h	Wed Jul 24 14:03:38 2002
+++ b/include/linux/pci.h	Wed Jul 24 14:03:38 2002
@@ -392,6 +392,7 @@
 
 #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)
 #define pci_dev_b(n) list_entry(n, struct pci_dev, bus_list)
+#define	to_pci_dev(n) container_of(n, struct pci_dev, dev)
 
 /*
  *  For PCI devices, the region numbers are assigned this way:
@@ -490,6 +491,8 @@
 
 	struct device_driver	driver;
 };
+
+#define	to_pci_driver(drv) container_of(drv,struct pci_driver, driver)
 
 
 /* these external functions are only available when PCI support is enabled */
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Wed Jul 24 14:03:37 2002
+++ b/include/linux/pci_ids.h	Wed Jul 24 14:03:37 2002
@@ -1259,6 +1259,7 @@
 #define PCI_DEVICE_ID_3DFX_VOODOO2	0x0002
 #define PCI_DEVICE_ID_3DFX_BANSHEE	0x0003
 #define PCI_DEVICE_ID_3DFX_VOODOO3	0x0005
+#define PCI_DEVICE_ID_3DFX_VOODOO5	0x0009
 
 #define PCI_VENDOR_ID_SIGMADES		0x1236
 #define PCI_DEVICE_ID_SIGMADES_6425	0x6401
diff -Nru a/include/linux/pmu.h b/include/linux/pmu.h
--- a/include/linux/pmu.h	Wed Jul 24 14:03:35 2002
+++ b/include/linux/pmu.h	Wed Jul 24 14:03:35 2002
@@ -75,6 +75,8 @@
 	PMU_HEATHROW_BASED,	/* PowerBook G3 series */
 	PMU_PADDINGTON_BASED,	/* 1999 PowerBook G3 */
 	PMU_KEYLARGO_BASED,	/* Core99 motherboard (PMU99) */
+	PMU_68K_V1,		/* 68K PMU, version 1 */
+	PMU_68K_V2, 		/* 68K PMU, version 2 */
 };
 
 /* PMU PMU_POWER_EVENTS commands */
diff -Nru a/include/linux/preempt.h b/include/linux/preempt.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/preempt.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,46 @@
+#ifndef __LINUX_PREEMPT_H
+#define __LINUX_PREEMPT_H
+
+#include <linux/config.h>
+
+#define preempt_count() (current_thread_info()->preempt_count)
+
+#ifdef CONFIG_PREEMPT
+
+extern void preempt_schedule(void);
+
+#define preempt_disable() \
+do { \
+	preempt_count()++; \
+	barrier(); \
+} while (0)
+
+#define preempt_enable_no_resched() \
+do { \
+	preempt_count()--; \
+	barrier(); \
+} while (0)
+
+#define preempt_enable() \
+do { \
+	preempt_enable_no_resched(); \
+	if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
+		preempt_schedule(); \
+} while (0)
+
+#define preempt_check_resched() \
+do { \
+	if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
+		preempt_schedule(); \
+} while (0)
+
+#else
+
+#define preempt_disable()		do { } while (0)
+#define preempt_enable_no_resched()	do {} while(0)
+#define preempt_enable()		do { } while (0)
+#define preempt_check_resched()		do { } while (0)
+
+#endif
+
+#endif /* __LINUX_PREEMPT_H */
diff -Nru a/include/linux/proc_fs.h b/include/linux/proc_fs.h
--- a/include/linux/proc_fs.h	Wed Jul 24 14:03:35 2002
+++ b/include/linux/proc_fs.h	Wed Jul 24 14:03:35 2002
@@ -219,7 +219,7 @@
 
 static inline struct proc_inode *PROC_I(const struct inode *inode)
 {
-	return list_entry(inode, struct proc_inode, vfs_inode);
+	return container_of(inode, struct proc_inode, vfs_inode);
 }
 
 static inline struct proc_dir_entry *PDE(const struct inode *inode)
diff -Nru a/include/linux/qnx4_fs.h b/include/linux/qnx4_fs.h
--- a/include/linux/qnx4_fs.h	Wed Jul 24 14:03:38 2002
+++ b/include/linux/qnx4_fs.h	Wed Jul 24 14:03:38 2002
@@ -140,7 +140,7 @@
 
 static inline struct qnx4_inode_info *qnx4_i(struct inode *inode)
 {
-	return list_entry(inode, struct qnx4_inode_info, vfs_inode);
+	return container_of(inode, struct qnx4_inode_info, vfs_inode);
 }
 
 static inline struct qnx4_inode_entry *qnx4_raw_inode(struct inode *inode)
diff -Nru a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
--- a/include/linux/raid/md_k.h	Wed Jul 24 14:03:35 2002
+++ b/include/linux/raid/md_k.h	Wed Jul 24 14:03:35 2002
@@ -249,7 +249,6 @@
 }
 
 extern mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr);
-extern mdk_rdev_t *get_spare(mddev_t *mddev);
 
 /*
  * iterates through some rdev ringlist. It's safe to remove the
diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
--- a/include/linux/reiserfs_fs.h	Wed Jul 24 14:03:39 2002
+++ b/include/linux/reiserfs_fs.h	Wed Jul 24 14:03:39 2002
@@ -288,7 +288,7 @@
 
 static inline struct reiserfs_inode_info *REISERFS_I(struct inode *inode)
 {
-	return list_entry(inode, struct reiserfs_inode_info, vfs_inode);
+	return container_of(inode, struct reiserfs_inode_info, vfs_inode);
 }
 
 static inline struct reiserfs_sb_info *REISERFS_SB(const struct super_block *sb)
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	Wed Jul 24 14:03:36 2002
+++ b/include/linux/sched.h	Wed Jul 24 14:03:36 2002
@@ -116,7 +116,7 @@
 /*
  * Scheduling policies
  */
-#define SCHED_OTHER		0
+#define SCHED_NORMAL		0
 #define SCHED_FIFO		1
 #define SCHED_RR		2
 
@@ -207,7 +207,7 @@
 
 /*
  * Priority of a process goes from 0..MAX_PRIO-1, valid RT
- * priority is 0..MAX_RT_PRIO-1, and SCHED_OTHER tasks are
+ * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL tasks are
  * in the range MAX_RT_PRIO..MAX_PRIO-1. Priority values
  * are inverted: lower p->prio value means higher priority.
  *
@@ -264,7 +264,7 @@
 
 	unsigned long policy;
 	unsigned long cpus_allowed;
-	unsigned int time_slice;
+	unsigned int time_slice, first_time_slice;
 
 	struct list_head tasks;
 
@@ -361,6 +361,8 @@
    	u32 self_exec_id;
 /* Protection of (de-)allocation: mm, files, fs, tty */
 	spinlock_t alloc_lock;
+/* context-switch lock */
+	spinlock_t switch_lock;
 
 /* journalling filesystem info */
 	void *journal_info;
@@ -810,6 +812,27 @@
 	return res;
 }
 
+ 
+/**
+ * get_task_mm - acquire a reference to the task's mm
+ *
+ * Returns %NULL if the task has no mm. User must release
+ * the mm via mmput() after use.
+ */
+static inline struct mm_struct * get_task_mm(struct task_struct * task)
+{
+	struct mm_struct * mm;
+ 
+	task_lock(task);
+	mm = task->mm;
+	if (mm)
+		atomic_inc(&mm->mm_users);
+	task_unlock(task);
+
+	return mm;
+}
+ 
+ 
 /* set thread flags in other task's structures
  * - see asm/thread_info.h for TIF_xxxx flags available
  */
diff -Nru a/include/linux/serial167.h b/include/linux/serial167.h
--- a/include/linux/serial167.h	Wed Jul 24 14:03:37 2002
+++ b/include/linux/serial167.h	Wed Jul 24 14:03:37 2002
@@ -37,7 +37,7 @@
 	int			ignore_status_mask;
 	int			close_delay;
 	int			IER; 	/* Interrupt Enable Register */
-	int			event;
+	unsigned long		event;
 	unsigned long		last_active;
 	int			count;	/* # of fd on device */
 	int                     x_char; /* to be pushed out ASAP */
diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/serial_core.h	Wed Jul 24 14:03:39 2002
@@ -0,0 +1,395 @@
+/*
+ *  linux/drivers/char/serial_core.h
+ *
+ *  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
+ *
+ *  $Id: serial_core.h,v 1.49 2002/07/20 18:06:32 rmk Exp $
+ */
+
+/*
+ * The type definitions.  These are from Ted Ts'o's serial.h
+ */
+#define PORT_UNKNOWN	0
+#define PORT_8250	1
+#define PORT_16450	2
+#define PORT_16550	3
+#define PORT_16550A	4
+#define PORT_CIRRUS	5
+#define PORT_16650	6
+#define PORT_16650V2	7
+#define PORT_16750	8
+#define PORT_STARTECH	9
+#define PORT_16C950	10
+#define PORT_16654	11
+#define PORT_16850	12
+#define PORT_RSA	13
+#define PORT_MAX_8250	13	/* max port ID */
+
+/*
+ * ARM specific type numbers.  These are not currently guaranteed
+ * to be implemented, and will change in the future.  These are
+ * separate so any additions to the old serial.c that occur before
+ * we are merged can be easily merged here.
+ */
+#define PORT_AMBA	32
+#define PORT_CLPS711X	33
+#define PORT_SA1100	34
+#define PORT_UART00	35
+#define PORT_21285	37
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/circ_buf.h>
+#include <linux/spinlock.h>
+
+struct uart_port;
+struct uart_info;
+struct serial_struct;
+
+/*
+ * This structure describes all the operations that can be
+ * done on the physical hardware.
+ */
+struct uart_ops {
+	unsigned int	(*tx_empty)(struct uart_port *);
+	void		(*set_mctrl)(struct uart_port *, unsigned int mctrl);
+	unsigned int	(*get_mctrl)(struct uart_port *);
+	void		(*stop_tx)(struct uart_port *, unsigned int tty_stop);
+	void		(*start_tx)(struct uart_port *, unsigned int tty_start);
+	void		(*send_xchar)(struct uart_port *, char ch);
+	void		(*stop_rx)(struct uart_port *);
+	void		(*enable_ms)(struct uart_port *);
+	void		(*break_ctl)(struct uart_port *, int ctl);
+	int		(*startup)(struct uart_port *);
+	void		(*shutdown)(struct uart_port *);
+	void		(*change_speed)(struct uart_port *, unsigned int cflag,
+				        unsigned int iflag, unsigned int quot);
+	void		(*pm)(struct uart_port *, unsigned int state,
+			      unsigned int oldstate);
+	int		(*set_wake)(struct uart_port *, unsigned int state);
+
+	/*
+	 * Return a string describing the type of the port
+	 */
+	const char *(*type)(struct uart_port *);
+
+	/*
+	 * Release IO and memory resources used by the port.
+	 * This includes iounmap if necessary.
+	 */
+	void		(*release_port)(struct uart_port *);
+
+	/*
+	 * Request IO and memory resources used by the port.
+	 * This includes iomapping the port if necessary.
+	 */
+	int		(*request_port)(struct uart_port *);
+	void		(*config_port)(struct uart_port *, int);
+	int		(*verify_port)(struct uart_port *, struct serial_struct *);
+	int		(*ioctl)(struct uart_port *, unsigned int, unsigned long);
+};
+
+#define UART_CONFIG_TYPE	(1 << 0)
+#define UART_CONFIG_IRQ		(1 << 1)
+
+struct uart_icount {
+	__u32	cts;
+	__u32	dsr;
+	__u32	rng;
+	__u32	dcd;
+	__u32	rx;
+	__u32	tx;
+	__u32	frame;
+	__u32	overrun;
+	__u32	parity;
+	__u32	brk;
+	__u32	buf_overrun;
+};
+
+struct uart_port {
+	spinlock_t		lock;			/* port lock */
+	unsigned int		iobase;			/* in/out[bwl] */
+	char			*membase;		/* read/write[bwl] */
+	unsigned int		irq;			/* irq number */
+	unsigned int		uartclk;		/* base uart clock */
+	unsigned char		fifosize;		/* tx fifo size */
+	unsigned char		x_char;			/* xon/xoff char */
+	unsigned char		regshift;		/* reg offset shift */
+	unsigned char		iotype;			/* io access style */
+
+#define UPIO_PORT		(0)
+#define UPIO_HUB6		(1)
+#define UPIO_MEM		(2)
+
+	unsigned int		read_status_mask;	/* driver specific */
+	unsigned int		ignore_status_mask;	/* driver specific */
+	struct uart_info	*info;			/* pointer to parent info */
+	struct uart_icount	icount;			/* statistics */
+
+	struct console		*cons;			/* struct console, if any */
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+	unsigned long		sysrq;			/* sysrq timeout */
+#endif
+
+	unsigned int		flags;
+
+#define UPF_HUP_NOTIFY		(1 << 0)
+#define UPF_SAK			(1 << 2)
+#define UPF_SPD_MASK		(0x1030)
+#define UPF_SPD_HI		(0x0010)
+#define UPF_SPD_VHI		(0x0020)
+#define UPF_SPD_CUST		(0x0030)
+#define UPF_SPD_SHI		(0x1000)
+#define UPF_SPD_WARP		(0x1010)
+#define UPF_SKIP_TEST		(1 << 6)
+#define UPF_AUTO_IRQ		(1 << 7)
+#define UPF_HARDPPS_CD		(1 << 11)
+#define UPF_LOW_LATENCY		(1 << 13)
+#define UPF_BUGGY_UART		(1 << 14)
+#define UPF_AUTOPROBE		(1 << 15)
+#define UPF_BOOT_AUTOCONF	(1 << 28)
+
+#define UPF_FLAGS		(0x7fff)
+#define UPF_USR_MASK		(UPF_SPD_MASK|UPF_LOW_LATENCY)
+
+	unsigned int		mctrl;			/* current modem ctrl settings */
+	unsigned int		timeout;		/* character-based timeout */
+	unsigned int		type;			/* port type */
+	struct uart_ops		*ops;
+	unsigned int		line;			/* port index */
+	unsigned long		mapbase;		/* for ioremap */
+	unsigned char		hub6;			/* this should be in the 8250 driver */
+	unsigned char		unused[3];
+};
+
+/*
+ * This is the state information which is persistent across opens.
+ * The low level driver must not to touch any elements contained
+ * within.
+ */
+struct uart_state {
+	unsigned int		close_delay;
+	unsigned int		closing_wait;
+
+#define USF_CLOSING_WAIT_INF	(0)
+#define USF_CLOSING_WAIT_NONE	(65535)
+
+	unsigned int		custom_divisor;
+
+	int			count;
+	struct uart_info	*info;
+	struct uart_port	*port;
+
+#ifdef CONFIG_PM
+	struct pm_dev		*pm;
+#endif
+};
+
+#define UART_XMIT_SIZE 1024
+/*
+ * This is the state information which is only valid when the port
+ * is open; it may be freed by the core driver once the device has
+ * been closed.  Either the low level driver or the core can modify
+ * stuff here.
+ */
+struct uart_info {
+	struct uart_port	*port;
+	struct uart_state	*state;
+	struct tty_struct	*tty;
+	struct circ_buf		xmit;
+	unsigned int		flags;
+
+/*
+ * These are the flags that specific to info->flags, and reflect our
+ * internal state.  They can not be accessed via port->flags.  Low
+ * level drivers must not change these, but may query them instead.
+ */
+#define UIF_CHECK_CD		(1 << 25)
+#define UIF_CTS_FLOW		(1 << 26)
+#define UIF_CLOSING		(1 << 27)
+#define UIF_NORMAL_ACTIVE	(1 << 29)
+#define UIF_INITIALIZED		(1 << 31)
+
+	unsigned char		*tmpbuf;
+	struct semaphore	tmpbuf_sem;
+
+	unsigned long		event;
+	int			blocked_open;
+
+	struct tasklet_struct	tlet;
+
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	delta_msr_wait;
+};
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS		256
+
+#define EVT_WRITE_WAKEUP	0
+
+struct module;
+struct tty_driver;
+
+struct uart_driver {
+	struct module		*owner;
+	const char		*driver_name;
+	const char		*dev_name;
+	int			 major;
+	int			 minor;
+	int			 nr;
+	struct console		*cons;
+
+	/*
+	 * these are private; the low level driver should not
+	 * touch these; they should be initialised to NULL
+	 */
+	struct uart_state	*state;
+	struct tty_driver	*tty_driver;
+};
+
+void uart_event(struct uart_port *port, int event);
+struct uart_port *uart_get_console(struct uart_port *ports, int nr,
+				   struct console *c);
+void uart_parse_options(char *options, int *baud, int *parity, int *bits,
+			int *flow);
+int uart_set_options(struct uart_port *port, struct console *co, int baud,
+		     int parity, int bits, int flow);
+int uart_register_driver(struct uart_driver *uart);
+void uart_unregister_driver(struct uart_driver *uart);
+void uart_unregister_port(struct uart_driver *reg, int line);
+int uart_register_port(struct uart_driver *reg, struct uart_port *port);
+int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
+int uart_remove_one_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)
+
+#define uart_circ_chars_pending(circ)	\
+	(CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
+
+#define uart_circ_chars_free(circ)	\
+	(CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
+
+#define uart_tx_stopped(port)		\
+	((port)->info->tty->stopped || (port)->info->tty->hw_stopped)
+
+/*
+ * The following are helper functions for the low level drivers.
+ */
+#ifdef SUPPORT_SYSRQ
+static inline int
+uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
+		       struct pt_regs *regs)
+{
+	if (port->sysrq) {
+		if (ch && time_before(jiffies, port->sysrq)) {
+			handle_sysrq(ch, regs, NULL);
+			port->sysrq = 0;
+			return 1;
+		}
+		port->sysrq = 0;
+	}
+	return 0;
+}
+#else
+#define uart_handle_sysrq_char(port,ch,regs)	(0)
+#endif
+
+/*
+ * We do the SysRQ and SAK checking like this...
+ */
+static inline int uart_handle_break(struct uart_port *port)
+{
+	struct uart_info *info = port->info;
+#ifdef SUPPORT_SYSRQ
+	if (port->cons && port->cons->index == port->line) {
+		if (!port->sysrq) {
+			port->sysrq = jiffies + HZ*5;
+			return 1;
+		}
+		port->sysrq = 0;
+	}
+#endif
+	if (info->flags & UPF_SAK)
+		do_SAK(info->tty);
+	return 0;
+}
+
+/**
+ *	uart_handle_dcd_change - handle a change of carrier detect state
+ *	@port: uart_port structure for the open port
+ *	@status: new carrier detect status, nonzero if active
+ */
+static inline void
+uart_handle_dcd_change(struct uart_port *port, unsigned int status)
+{
+	struct uart_info *info = port->info;
+
+	port->icount.dcd++;
+
+#ifdef CONFIG_HARD_PPS
+	if ((port->flags & UPF_HARDPPS_CD) && status)
+		hardpps();
+#endif
+
+	if (info->flags & UIF_CHECK_CD) {
+		if (status)
+			wake_up_interruptible(&info->open_wait);
+		else if (info->tty)
+			tty_hangup(info->tty);
+	}
+}
+
+/**
+ *	uart_handle_cts_change - handle a change of clear-to-send state
+ *	@port: uart_port structure for the open port
+ *	@status: new clear to send status, nonzero if active
+ */
+static inline void
+uart_handle_cts_change(struct uart_port *port, unsigned int status)
+{
+	struct uart_info *info = port->info;
+	struct tty_struct *tty = info->tty;
+
+	port->icount.cts++;
+
+	if (info->flags & UIF_CTS_FLOW) {
+		if (tty->hw_stopped) {
+			if (status) {
+				tty->hw_stopped = 0;
+				port->ops->start_tx(port, 0);
+				uart_event(port, EVT_WRITE_WAKEUP);
+			}
+		} else {
+			if (!status) {
+				tty->hw_stopped = 1;
+				port->ops->stop_tx(port, 0);
+			}
+		}
+	}
+}
+
+/*
+ *	UART_ENABLE_MS - determine if port should enable modem status irqs
+ */
+#define UART_ENABLE_MS(port,cflag)	((port)->flags & UPF_HARDPPS_CD || \
+					 (cflag) & CRTSCTS || \
+					 !(cflag) & CLOCAL)
+
+#endif
diff -Nru a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
--- a/include/linux/shmem_fs.h	Wed Jul 24 14:03:39 2002
+++ b/include/linux/shmem_fs.h	Wed Jul 24 14:03:39 2002
@@ -31,7 +31,7 @@
 
 static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
 {
-	return list_entry(inode, struct shmem_inode_info, vfs_inode);
+	return container_of(inode, struct shmem_inode_info, vfs_inode);
 }
 
 #endif
diff -Nru a/include/linux/smb_fs.h b/include/linux/smb_fs.h
--- a/include/linux/smb_fs.h	Wed Jul 24 14:03:38 2002
+++ b/include/linux/smb_fs.h	Wed Jul 24 14:03:38 2002
@@ -38,7 +38,7 @@
 
 static inline struct smb_inode_info *SMB_I(struct inode *inode)
 {
-	return list_entry(inode, struct smb_inode_info, vfs_inode);
+	return container_of(inode, struct smb_inode_info, vfs_inode);
 }
 
 /* macro names are short for word, double-word, long value (?) */
diff -Nru a/include/linux/smp.h b/include/linux/smp.h
--- a/include/linux/smp.h	Wed Jul 24 14:03:38 2002
+++ b/include/linux/smp.h	Wed Jul 24 14:03:38 2002
@@ -95,7 +95,8 @@
 
 #endif /* !SMP */
 
-#define get_cpu()	({ preempt_disable(); smp_processor_id(); })
-#define put_cpu()	preempt_enable()
+#define get_cpu()		({ preempt_disable(); smp_processor_id(); })
+#define put_cpu()		preempt_enable()
+#define put_cpu_no_resched()	preempt_enable_no_resched()
 
 #endif /* __LINUX_SMP_H */
diff -Nru a/include/linux/smp_lock.h b/include/linux/smp_lock.h
--- a/include/linux/smp_lock.h	Wed Jul 24 14:03:36 2002
+++ b/include/linux/smp_lock.h	Wed Jul 24 14:03:36 2002
@@ -7,7 +7,7 @@
 
 #define lock_kernel()				do { } while(0)
 #define unlock_kernel()				do { } while(0)
-#define release_kernel_lock(task, cpu)		do { } while(0)
+#define release_kernel_lock(task)		do { } while(0)
 #define reacquire_kernel_lock(task)		do { } while(0)
 #define kernel_locked() 1
 
diff -Nru a/include/linux/spinlock.h b/include/linux/spinlock.h
--- a/include/linux/spinlock.h	Wed Jul 24 14:03:38 2002
+++ b/include/linux/spinlock.h	Wed Jul 24 14:03:38 2002
@@ -2,6 +2,7 @@
 #define __LINUX_SPINLOCK_H
 
 #include <linux/config.h>
+#include <linux/preempt.h>
 #include <linux/linkage.h>
 #include <linux/compiler.h>
 #include <linux/thread_info.h>
@@ -25,17 +26,17 @@
 #define write_lock_irq(lock)			do { local_irq_disable();        write_lock(lock); } while (0)
 #define write_lock_bh(lock)			do { local_bh_disable();         write_lock(lock); } while (0)
 
-#define spin_unlock_irqrestore(lock, flags)	do { spin_unlock(lock);  local_irq_restore(flags); } while (0)
+#define spin_unlock_irqrestore(lock, flags)	do { _raw_spin_unlock(lock);  local_irq_restore(flags); preempt_enable(); } while (0)
 #define _raw_spin_unlock_irqrestore(lock, flags) do { _raw_spin_unlock(lock);  local_irq_restore(flags); } while (0)
-#define spin_unlock_irq(lock)			do { spin_unlock(lock);  local_irq_enable();       } while (0)
-#define spin_unlock_bh(lock)			do { spin_unlock(lock);  local_bh_enable();        } while (0)
+#define spin_unlock_irq(lock)			do { _raw_spin_unlock(lock);  local_irq_enable(); preempt_enable();       } while (0)
+#define spin_unlock_bh(lock)			do { spin_unlock(lock); local_bh_enable(); } while (0)
 
-#define read_unlock_irqrestore(lock, flags)	do { read_unlock(lock);  local_irq_restore(flags); } while (0)
-#define read_unlock_irq(lock)			do { read_unlock(lock);  local_irq_enable();       } while (0)
+#define read_unlock_irqrestore(lock, flags)	do { _raw_read_unlock(lock);  local_irq_restore(flags); preempt_enable(); } while (0)
+#define read_unlock_irq(lock)			do { _raw_read_unlock(lock);  local_irq_enable(); preempt_enable(); } while (0)
 #define read_unlock_bh(lock)			do { read_unlock(lock);  local_bh_enable();        } while (0)
 
-#define write_unlock_irqrestore(lock, flags)	do { write_unlock(lock); local_irq_restore(flags); } while (0)
-#define write_unlock_irq(lock)			do { write_unlock(lock); local_irq_enable();       } while (0)
+#define write_unlock_irqrestore(lock, flags)	do { _raw_write_unlock(lock); local_irq_restore(flags); preempt_enable(); } while (0)
+#define write_unlock_irq(lock)			do { _raw_write_unlock(lock); local_irq_enable(); preempt_enable();       } while (0)
 #define write_unlock_bh(lock)			do { write_unlock(lock); local_bh_enable();        } while (0)
 #define spin_trylock_bh(lock)			({ int __r; local_bh_disable();\
 						__r = spin_trylock(lock);      \
@@ -120,36 +121,6 @@
 
 #ifdef CONFIG_PREEMPT
 
-asmlinkage void preempt_schedule(void);
-
-#define preempt_get_count() (current_thread_info()->preempt_count)
-
-#define preempt_disable() \
-do { \
-	++current_thread_info()->preempt_count; \
-	barrier(); \
-} while (0)
-
-#define preempt_enable_no_resched() \
-do { \
-	--current_thread_info()->preempt_count; \
-	barrier(); \
-} while (0)
-
-#define preempt_enable() \
-do { \
-	--current_thread_info()->preempt_count; \
-	barrier(); \
-	if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
-		preempt_schedule(); \
-} while (0)
-
-#define preempt_check_resched() \
-do { \
-	if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
-		preempt_schedule(); \
-} while (0)
-
 #define spin_lock(lock)	\
 do { \
 	preempt_disable(); \
@@ -164,12 +135,6 @@
 	preempt_enable(); \
 } while (0)
 
-#define spin_unlock_no_resched(lock) \
-do { \
-	_raw_spin_unlock(lock); \
-	preempt_enable_no_resched(); \
-} while (0)
-
 #define read_lock(lock)		({preempt_disable(); _raw_read_lock(lock);})
 #define read_unlock(lock)	({_raw_read_unlock(lock); preempt_enable();})
 #define write_lock(lock)	({preempt_disable(); _raw_write_lock(lock);})
@@ -179,16 +144,9 @@
 
 #else
 
-#define preempt_get_count()		(0)
-#define preempt_disable()		do { } while (0)
-#define preempt_enable_no_resched()	do {} while(0)
-#define preempt_enable()		do { } while (0)
-#define preempt_check_resched()		do { } while (0)
-
 #define spin_lock(lock)			_raw_spin_lock(lock)
 #define spin_trylock(lock)		_raw_spin_trylock(lock)
 #define spin_unlock(lock)		_raw_spin_unlock(lock)
-#define spin_unlock_no_resched(lock)	_raw_spin_unlock(lock)
 
 #define read_lock(lock)			_raw_read_lock(lock)
 #define read_unlock(lock)		_raw_read_unlock(lock)
diff -Nru a/include/linux/trdevice.h b/include/linux/trdevice.h
--- a/include/linux/trdevice.h	Wed Jul 24 14:03:37 2002
+++ b/include/linux/trdevice.h	Wed Jul 24 14:03:37 2002
@@ -33,6 +33,7 @@
 				   void *saddr, unsigned len);
 extern int		tr_rebuild_header(struct sk_buff *skb);
 extern unsigned short	tr_type_trans(struct sk_buff *skb, struct net_device *dev);
+extern void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct net_device *dev);
 extern struct net_device *init_trdev(struct net_device *dev, int sizeof_priv);
 extern struct net_device *alloc_trdev(int sizeof_priv);
 extern int register_trdev(struct net_device *dev);
diff -Nru a/include/linux/tty.h b/include/linux/tty.h
--- a/include/linux/tty.h	Wed Jul 24 14:03:38 2002
+++ b/include/linux/tty.h	Wed Jul 24 14:03:38 2002
@@ -89,7 +89,8 @@
 	unsigned short vesapm_seg;		/* 0x2e */
 	unsigned short vesapm_off;		/* 0x30 */
 	unsigned short pages;			/* 0x32 */
-						/* 0x34 -- 0x3f reserved for future expansion */
+	unsigned short vesa_attributes;		/* 0x34 */
+						/* 0x36 -- 0x3f reserved for future expansion */
 };
 
 extern struct screen_info screen_info;
diff -Nru a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h
--- a/include/linux/ufs_fs.h	Wed Jul 24 14:03:39 2002
+++ b/include/linux/ufs_fs.h	Wed Jul 24 14:03:39 2002
@@ -784,7 +784,7 @@
 
 static inline struct ufs_inode_info *UFS_I(struct inode *inode)
 {
-	return list_entry(inode, struct ufs_inode_info, vfs_inode);
+	return container_of(inode, struct ufs_inode_info, vfs_inode);
 }
 
 #endif	/* __KERNEL__ */
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Wed Jul 24 14:03:38 2002
+++ b/include/linux/usb.h	Wed Jul 24 14:03:38 2002
@@ -257,6 +257,7 @@
 	struct device dev;		/* interface specific device info */
 	void *private_data;
 };
+#define	to_usb_interface(d) container_of(d, struct usb_interface, dev)
 
 /* USB_DT_CONFIG: Configuration descriptor information.
  *
@@ -422,6 +423,7 @@
 	int maxchild;			/* Number of ports if hub */
 	struct usb_device *children[USB_MAXCHILDREN];
 };
+#define	to_usb_device(d) container_of(d, struct usb_device, dev)
 
 extern struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *);
 extern struct usb_device *usb_get_dev(struct usb_device *dev);
diff -Nru a/include/linux/writeback.h b/include/linux/writeback.h
--- a/include/linux/writeback.h	Wed Jul 24 14:03:36 2002
+++ b/include/linux/writeback.h	Wed Jul 24 14:03:36 2002
@@ -8,6 +8,8 @@
 #ifndef WRITEBACK_H
 #define WRITEBACK_H
 
+struct backing_dev_info;
+
 extern spinlock_t inode_lock;
 extern struct list_head inode_in_use;
 extern struct list_head inode_unused;
@@ -38,6 +40,9 @@
 void __wait_on_inode(struct inode * inode);
 void sync_inodes_sb(struct super_block *, int wait);
 void sync_inodes(int wait);
+void writeback_backing_dev(struct backing_dev_info *bdi, int *nr_to_write,
+			enum writeback_sync_modes sync_mode,
+			unsigned long *older_than_this);
 
 /* writeback.h requires fs.h; it, too, is not included from here. */
 static inline void wait_on_inode(struct inode *inode)
diff -Nru a/include/linux/zorro.h b/include/linux/zorro.h
--- a/include/linux/zorro.h	Wed Jul 24 14:03:35 2002
+++ b/include/linux/zorro.h	Wed Jul 24 14:03:35 2002
@@ -199,7 +199,7 @@
      *  the corresponding bits.
      */
 
-extern __u32 zorro_unused_z2ram[4];
+extern bitmap_member(zorro_unused_z2ram, 128);
 
 #define Z2RAM_START		(0x00200000)
 #define Z2RAM_END		(0x00a00000)
diff -Nru a/include/scsi/scsicam.h b/include/scsi/scsicam.h
--- a/include/scsi/scsicam.h	Wed Jul 24 14:03:37 2002
+++ b/include/scsi/scsicam.h	Wed Jul 24 14:03:37 2002
@@ -12,9 +12,8 @@
 
 #ifndef SCSICAM_H
 #define SCSICAM_H
-#include <linux/kdev_t.h>
-extern int scsicam_bios_param (Disk *disk, kdev_t dev, int *ip);
+extern int scsicam_bios_param (Disk *disk, struct block_device *bdev, int *ip);
 extern int scsi_partsize(unsigned char *buf, unsigned long capacity,
            unsigned int  *cyls, unsigned int *hds, unsigned int *secs);
-extern unsigned char *scsi_bios_ptable(kdev_t dev);
+extern unsigned char *scsi_bios_ptable(struct block_device *bdev);
 #endif /* def SCSICAM_H */
diff -Nru a/include/video/aty128.h b/include/video/aty128.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/aty128.h	Wed Jul 24 14:03:38 2002
@@ -0,0 +1,419 @@
+/*  $Id: aty128.h,v 1.1 1999/10/12 11:00:40 geert Exp $
+ *  linux/drivers/video/aty128.h
+ *  Register definitions for ATI Rage128 boards
+ *
+ *  Anthony Tong <atong@uiuc.edu>, 1999
+ *  Brad Douglas <brad@neruo.com>, 2000
+ */
+
+#ifndef REG_RAGE128_H
+#define REG_RAGE128_H
+
+#define CLOCK_CNTL_INDEX			0x0008
+#define CLOCK_CNTL_DATA				0x000c
+#define BIOS_0_SCRATCH				0x0010
+#define BUS_CNTL				0x0030
+#define BUS_CNTL1				0x0034
+#define GEN_INT_CNTL				0x0040
+#define CRTC_GEN_CNTL				0x0050
+#define CRTC_EXT_CNTL				0x0054
+#define DAC_CNTL				0x0058
+#define I2C_CNTL_1				0x0094
+#define PALETTE_INDEX				0x00b0
+#define PALETTE_DATA				0x00b4
+#define CONFIG_CNTL				0x00e0
+#define GEN_RESET_CNTL				0x00f0
+#define CONFIG_MEMSIZE				0x00f8
+#define MEM_CNTL				0x0140
+#define MEM_POWER_MISC				0x015c
+#define AGP_BASE				0x0170
+#define AGP_CNTL				0x0174
+#define AGP_APER_OFFSET				0x0178
+#define PCI_GART_PAGE				0x017c
+#define PC_NGUI_MODE				0x0180
+#define PC_NGUI_CTLSTAT				0x0184
+#define MPP_TB_CONFIG				0x01C0
+#define MPP_GP_CONFIG				0x01C8
+#define VIPH_CONTROL				0x01D0
+#define CRTC_H_TOTAL_DISP			0x0200
+#define CRTC_H_SYNC_STRT_WID			0x0204
+#define CRTC_V_TOTAL_DISP			0x0208
+#define CRTC_V_SYNC_STRT_WID			0x020c
+#define CRTC_VLINE_CRNT_VLINE			0x0210
+#define CRTC_CRNT_FRAME				0x0214
+#define CRTC_GUI_TRIG_VLINE			0x0218
+#define CRTC_OFFSET				0x0224
+#define CRTC_OFFSET_CNTL			0x0228
+#define CRTC_PITCH				0x022c
+#define OVR_CLR					0x0230
+#define OVR_WID_LEFT_RIGHT			0x0234
+#define OVR_WID_TOP_BOTTOM			0x0238
+#define LVDS_GEN_CNTL				0x02d0
+#define DDA_CONFIG				0x02e0
+#define DDA_ON_OFF				0x02e4
+#define VGA_DDA_CONFIG				0x02e8
+#define VGA_DDA_ON_OFF				0x02ec
+#define CRTC2_H_TOTAL_DISP			0x0300
+#define CRTC2_H_SYNC_STRT_WID			0x0304
+#define CRTC2_V_TOTAL_DISP			0x0308
+#define CRTC2_V_SYNC_STRT_WID			0x030c
+#define CRTC2_VLINE_CRNT_VLINE			0x0310
+#define CRTC2_CRNT_FRAME			0x0314
+#define CRTC2_GUI_TRIG_VLINE			0x0318
+#define CRTC2_OFFSET				0x0324
+#define CRTC2_OFFSET_CNTL			0x0328
+#define CRTC2_PITCH				0x032c
+#define DDA2_CONFIG				0x03e0
+#define DDA2_ON_OFF				0x03e4
+#define CRTC2_GEN_CNTL				0x03f8
+#define CRTC2_STATUS				0x03fc
+#define OV0_SCALE_CNTL				0x0420
+#define SUBPIC_CNTL				0x0540
+#define PM4_BUFFER_OFFSET			0x0700
+#define PM4_BUFFER_CNTL				0x0704
+#define PM4_BUFFER_WM_CNTL			0x0708
+#define PM4_BUFFER_DL_RPTR_ADDR			0x070c
+#define PM4_BUFFER_DL_RPTR			0x0710
+#define PM4_BUFFER_DL_WPTR			0x0714
+#define PM4_VC_FPU_SETUP			0x071c
+#define PM4_FPU_CNTL				0x0720
+#define PM4_VC_FORMAT				0x0724
+#define PM4_VC_CNTL				0x0728
+#define PM4_VC_I01				0x072c
+#define PM4_VC_VLOFF				0x0730
+#define PM4_VC_VLSIZE				0x0734
+#define PM4_IW_INDOFF				0x0738
+#define PM4_IW_INDSIZE				0x073c
+#define PM4_FPU_FPX0				0x0740
+#define PM4_FPU_FPY0				0x0744
+#define PM4_FPU_FPX1				0x0748
+#define PM4_FPU_FPY1				0x074c
+#define PM4_FPU_FPX2				0x0750
+#define PM4_FPU_FPY2				0x0754
+#define PM4_FPU_FPY3				0x0758
+#define PM4_FPU_FPY4				0x075c
+#define PM4_FPU_FPY5				0x0760
+#define PM4_FPU_FPY6				0x0764
+#define PM4_FPU_FPR				0x0768
+#define PM4_FPU_FPG				0x076c
+#define PM4_FPU_FPB				0x0770
+#define PM4_FPU_FPA				0x0774
+#define PM4_FPU_INTXY0				0x0780
+#define PM4_FPU_INTXY1				0x0784
+#define PM4_FPU_INTXY2				0x0788
+#define PM4_FPU_INTARGB				0x078c
+#define PM4_FPU_FPTWICEAREA			0x0790
+#define PM4_FPU_DMAJOR01			0x0794
+#define PM4_FPU_DMAJOR12			0x0798
+#define PM4_FPU_DMAJOR02			0x079c
+#define PM4_FPU_STAT				0x07a0
+#define PM4_STAT				0x07b8
+#define PM4_TEST_CNTL				0x07d0
+#define PM4_MICROCODE_ADDR			0x07d4
+#define PM4_MICROCODE_RADDR			0x07d8
+#define PM4_MICROCODE_DATAH			0x07dc
+#define PM4_MICROCODE_DATAL			0x07e0
+#define PM4_CMDFIFO_ADDR			0x07e4
+#define PM4_CMDFIFO_DATAH			0x07e8
+#define PM4_CMDFIFO_DATAL			0x07ec
+#define PM4_BUFFER_ADDR				0x07f0
+#define PM4_BUFFER_DATAH			0x07f4
+#define PM4_BUFFER_DATAL			0x07f8
+#define PM4_MICRO_CNTL				0x07fc
+#define CAP0_TRIG_CNTL				0x0950
+#define CAP1_TRIG_CNTL				0x09c0
+
+/******************************************************************************
+ *                  GUI Block Memory Mapped Registers                         *
+ *                     These registers are FIFOed.                            *
+ *****************************************************************************/
+#define PM4_FIFO_DATA_EVEN			0x1000
+#define PM4_FIFO_DATA_ODD			0x1004
+
+#define DST_OFFSET				0x1404
+#define DST_PITCH				0x1408
+#define DST_WIDTH				0x140c
+#define DST_HEIGHT				0x1410
+#define SRC_X					0x1414
+#define SRC_Y					0x1418
+#define DST_X					0x141c
+#define DST_Y					0x1420
+#define SRC_PITCH_OFFSET			0x1428
+#define DST_PITCH_OFFSET			0x142c
+#define SRC_Y_X					0x1434
+#define DST_Y_X					0x1438
+#define DST_HEIGHT_WIDTH			0x143c
+#define DP_GUI_MASTER_CNTL			0x146c
+#define BRUSH_SCALE				0x1470
+#define BRUSH_Y_X				0x1474
+#define DP_BRUSH_BKGD_CLR			0x1478
+#define DP_BRUSH_FRGD_CLR			0x147c
+#define DST_WIDTH_X				0x1588
+#define DST_HEIGHT_WIDTH_8			0x158c
+#define SRC_X_Y					0x1590
+#define DST_X_Y					0x1594
+#define DST_WIDTH_HEIGHT			0x1598
+#define DST_WIDTH_X_INCY			0x159c
+#define DST_HEIGHT_Y				0x15a0
+#define DST_X_SUB				0x15a4
+#define DST_Y_SUB				0x15a8
+#define SRC_OFFSET				0x15ac
+#define SRC_PITCH				0x15b0
+#define DST_HEIGHT_WIDTH_BW			0x15b4
+#define CLR_CMP_CNTL				0x15c0
+#define CLR_CMP_CLR_SRC				0x15c4
+#define CLR_CMP_CLR_DST				0x15c8
+#define CLR_CMP_MASK				0x15cc
+#define DP_SRC_FRGD_CLR				0x15d8
+#define DP_SRC_BKGD_CLR				0x15dc
+#define DST_BRES_ERR				0x1628
+#define DST_BRES_INC				0x162c
+#define DST_BRES_DEC				0x1630
+#define DST_BRES_LNTH				0x1634
+#define DST_BRES_LNTH_SUB			0x1638
+#define SC_LEFT					0x1640
+#define SC_RIGHT				0x1644
+#define SC_TOP					0x1648
+#define SC_BOTTOM				0x164c
+#define SRC_SC_RIGHT				0x1654
+#define SRC_SC_BOTTOM				0x165c
+#define GUI_DEBUG0				0x16a0
+#define GUI_DEBUG1				0x16a4
+#define GUI_TIMEOUT				0x16b0
+#define GUI_TIMEOUT0				0x16b4
+#define GUI_TIMEOUT1				0x16b8
+#define GUI_PROBE				0x16bc
+#define DP_CNTL					0x16c0
+#define DP_DATATYPE				0x16c4
+#define DP_MIX					0x16c8
+#define DP_WRITE_MASK				0x16cc
+#define DP_CNTL_XDIR_YDIR_YMAJOR		0x16d0
+#define DEFAULT_OFFSET				0x16e0
+#define DEFAULT_PITCH				0x16e4
+#define DEFAULT_SC_BOTTOM_RIGHT			0x16e8
+#define SC_TOP_LEFT				0x16ec
+#define SC_BOTTOM_RIGHT				0x16f0
+#define SRC_SC_BOTTOM_RIGHT			0x16f4
+#define WAIT_UNTIL				0x1720
+#define CACHE_CNTL				0x1724
+#define GUI_STAT				0x1740
+#define PC_GUI_MODE				0x1744
+#define PC_GUI_CTLSTAT				0x1748
+#define PC_DEBUG_MODE				0x1760
+#define BRES_DST_ERR_DEC			0x1780
+#define TRAIL_BRES_T12_ERR_DEC			0x1784
+#define TRAIL_BRES_T12_INC			0x1788
+#define DP_T12_CNTL				0x178c
+#define DST_BRES_T1_LNTH			0x1790
+#define DST_BRES_T2_LNTH			0x1794
+#define SCALE_SRC_HEIGHT_WIDTH			0x1994
+#define SCALE_OFFSET_0				0x1998
+#define SCALE_PITCH				0x199c
+#define SCALE_X_INC				0x19a0
+#define SCALE_Y_INC				0x19a4
+#define SCALE_HACC				0x19a8
+#define SCALE_VACC				0x19ac
+#define SCALE_DST_X_Y				0x19b0
+#define SCALE_DST_HEIGHT_WIDTH			0x19b4
+#define SCALE_3D_CNTL				0x1a00
+#define SCALE_3D_DATATYPE			0x1a20
+#define SETUP_CNTL				0x1bc4
+#define SOLID_COLOR				0x1bc8
+#define WINDOW_XY_OFFSET			0x1bcc
+#define DRAW_LINE_POINT				0x1bd0
+#define SETUP_CNTL_PM4				0x1bd4
+#define DST_PITCH_OFFSET_C			0x1c80
+#define DP_GUI_MASTER_CNTL_C			0x1c84
+#define SC_TOP_LEFT_C				0x1c88
+#define SC_BOTTOM_RIGHT_C			0x1c8c
+
+#define CLR_CMP_MASK_3D				0x1A28
+#define MISC_3D_STATE_CNTL_REG			0x1CA0
+#define MC_SRC1_CNTL				0x19D8
+#define TEX_CNTL				0x1800
+
+/* CONSTANTS */
+#define GUI_ACTIVE				0x80000000
+#define ENGINE_IDLE				0x0
+
+#define PLL_WR_EN				0x00000080
+
+#define CLK_PIN_CNTL				0x0001
+#define PPLL_CNTL				0x0002
+#define PPLL_REF_DIV				0x0003
+#define PPLL_DIV_0				0x0004
+#define PPLL_DIV_1				0x0005
+#define PPLL_DIV_2				0x0006
+#define PPLL_DIV_3				0x0007
+#define VCLK_ECP_CNTL				0x0008
+#define HTOTAL_CNTL				0x0009
+#define X_MPLL_REF_FB_DIV			0x000a
+#define XPLL_CNTL				0x000b
+#define XDLL_CNTL				0x000c
+#define XCLK_CNTL				0x000d
+#define MPLL_CNTL				0x000e
+#define MCLK_CNTL				0x000f
+#define AGP_PLL_CNTL				0x0010
+#define FCP_CNTL				0x0012
+#define PLL_TEST_CNTL				0x0013
+#define P2PLL_CNTL				0x002a
+#define P2PLL_REF_DIV				0x002b
+#define P2PLL_DIV_0				0x002b
+#define POWER_MANAGEMENT			0x002f
+
+#define PPLL_RESET				0x01
+#define PPLL_ATOMIC_UPDATE_EN			0x10000
+#define PPLL_VGA_ATOMIC_UPDATE_EN		0x20000
+#define PPLL_REF_DIV_MASK			0x3FF
+#define PPLL_FB3_DIV_MASK			0x7FF
+#define PPLL_POST3_DIV_MASK			0x70000
+#define PPLL_ATOMIC_UPDATE_R			0x8000
+#define PPLL_ATOMIC_UPDATE_W			0x8000
+#define MEM_CFG_TYPE_MASK			0x3
+#define XCLK_SRC_SEL_MASK			0x7
+#define XPLL_FB_DIV_MASK			0xFF00
+#define X_MPLL_REF_DIV_MASK			0xFF
+
+/* CRTC control values (CRTC_GEN_CNTL) */
+#define CRTC_CSYNC_EN				0x00000010
+
+#define CRTC2_DBL_SCAN_EN			0x00000001
+#define CRTC2_DISPLAY_DIS			0x00800000
+#define CRTC2_FIFO_EXTSENSE			0x00200000
+#define CRTC2_ICON_EN				0x00100000
+#define CRTC2_CUR_EN				0x00010000
+#define CRTC2_EN				0x02000000
+#define CRTC2_DISP_REQ_EN_B			0x04000000
+
+#define CRTC_PIX_WIDTH_MASK			0x00000700
+#define CRTC_PIX_WIDTH_4BPP			0x00000100
+#define CRTC_PIX_WIDTH_8BPP			0x00000200
+#define CRTC_PIX_WIDTH_15BPP			0x00000300
+#define CRTC_PIX_WIDTH_16BPP			0x00000400
+#define CRTC_PIX_WIDTH_24BPP			0x00000500
+#define CRTC_PIX_WIDTH_32BPP			0x00000600
+
+/* DAC_CNTL bit constants */
+#define DAC_8BIT_EN				0x00000100
+#define DAC_MASK				0xFF000000
+#define DAC_BLANKING				0x00000004
+#define DAC_RANGE_CNTL				0x00000003
+#define DAC_CLK_SEL				0x00000010
+#define DAC_PALETTE_ACCESS_CNTL			0x00000020
+#define DAC_PALETTE2_SNOOP_EN			0x00000040
+#define DAC_PDWN				0x00008000
+
+/* CRTC_EXT_CNTL */
+#define CRT_CRTC_ON				0x00008000
+
+/* GEN_RESET_CNTL bit constants */
+#define SOFT_RESET_GUI				0x00000001
+#define SOFT_RESET_VCLK				0x00000100
+#define SOFT_RESET_PCLK				0x00000200
+#define SOFT_RESET_ECP				0x00000400
+#define SOFT_RESET_DISPENG_XCLK			0x00000800
+
+/* PC_GUI_CTLSTAT bit constants */
+#define PC_BUSY_INIT				0x10000000
+#define PC_BUSY_GUI				0x20000000
+#define PC_BUSY_NGUI				0x40000000
+#define PC_BUSY					0x80000000
+
+#define BUS_MASTER_DIS				0x00000040
+#define PM4_BUFFER_CNTL_NONPM4			0x00000000
+
+/* DP_DATATYPE bit constants */
+#define DST_8BPP				0x00000002
+#define DST_15BPP				0x00000003
+#define DST_16BPP				0x00000004
+#define DST_24BPP				0x00000005
+#define DST_32BPP				0x00000006
+
+#define BRUSH_SOLIDCOLOR			0x00000d00
+
+/* DP_GUI_MASTER_CNTL bit constants */
+#define	GMC_SRC_PITCH_OFFSET_DEFAULT		0x00000000
+#define GMC_DST_PITCH_OFFSET_DEFAULT		0x00000000
+#define GMC_SRC_CLIP_DEFAULT			0x00000000
+#define GMC_DST_CLIP_DEFAULT			0x00000000
+#define GMC_BRUSH_SOLIDCOLOR			0x000000d0
+#define GMC_SRC_DSTCOLOR			0x00003000
+#define GMC_BYTE_ORDER_MSB_TO_LSB		0x00000000
+#define GMC_DP_SRC_RECT				0x02000000
+#define GMC_3D_FCN_EN_CLR			0x00000000
+#define GMC_AUX_CLIP_CLEAR			0x20000000
+#define GMC_DST_CLR_CMP_FCN_CLEAR		0x10000000
+#define GMC_WRITE_MASK_SET			0x40000000
+#define GMC_DP_CONVERSION_TEMP_6500		0x00000000
+
+/* DP_GUI_MASTER_CNTL ROP3 named constants */
+#define	ROP3_PATCOPY				0x00f00000
+#define ROP3_SRCCOPY				0x00cc0000
+
+#define SRC_DSTCOLOR				0x00030000
+
+/* DP_CNTL bit constants */
+#define DST_X_RIGHT_TO_LEFT			0x00000000
+#define DST_X_LEFT_TO_RIGHT			0x00000001
+#define DST_Y_BOTTOM_TO_TOP			0x00000000
+#define DST_Y_TOP_TO_BOTTOM			0x00000002
+#define DST_X_MAJOR				0x00000000
+#define DST_Y_MAJOR				0x00000004
+#define DST_X_TILE				0x00000008
+#define DST_Y_TILE				0x00000010
+#define DST_LAST_PEL				0x00000020
+#define DST_TRAIL_X_RIGHT_TO_LEFT		0x00000000
+#define DST_TRAIL_X_LEFT_TO_RIGHT		0x00000040
+#define DST_TRAP_FILL_RIGHT_TO_LEFT		0x00000000
+#define DST_TRAP_FILL_LEFT_TO_RIGHT		0x00000080
+#define DST_BRES_SIGN				0x00000100
+#define DST_HOST_BIG_ENDIAN_EN			0x00000200
+#define DST_POLYLINE_NONLAST			0x00008000
+#define DST_RASTER_STALL			0x00010000
+#define DST_POLY_EDGE				0x00040000
+
+/* DP_MIX bit constants */
+#define DP_SRC_RECT				0x00000200
+#define DP_SRC_HOST				0x00000300
+#define DP_SRC_HOST_BYTEALIGN			0x00000400
+
+/* LVDS_GEN_CNTL constants */
+#define LVDS_BL_MOD_LEVEL_MASK			0x0000ff00
+#define LVDS_BL_MOD_LEVEL_SHIFT			8
+#define LVDS_BL_MOD_EN				0x00010000
+#define LVDS_DIGION				0x00040000
+#define LVDS_BLON				0x00080000
+#define LVDS_ON					0x00000001
+#define LVDS_DISPLAY_DIS			0x00000002
+#define LVDS_PANEL_TYPE_2PIX_PER_CLK		0x00000004
+#define LVDS_PANEL_24BITS_TFT			0x00000008
+#define LVDS_FRAME_MOD_NO			0x00000000
+#define LVDS_FRAME_MOD_2_LEVELS			0x00000010
+#define LVDS_FRAME_MOD_4_LEVELS			0x00000020
+#define LVDS_RST_FM				0x00000040
+#define LVDS_EN					0x00000080
+
+/* CRTC2_GEN_CNTL constants */
+#define CRTC2_EN				0x02000000
+
+/* POWER_MANAGEMENT constants */
+#define PWR_MGT_ON				0x00000001
+#define PWR_MGT_MODE_MASK			0x00000006
+#define PWR_MGT_MODE_PIN			0x00000000
+#define PWR_MGT_MODE_REGISTER			0x00000002
+#define PWR_MGT_MODE_TIMER			0x00000004
+#define PWR_MGT_MODE_PCI			0x00000006
+#define PWR_MGT_AUTO_PWR_UP_EN			0x00000008
+#define PWR_MGT_ACTIVITY_PIN_ON			0x00000010
+#define PWR_MGT_STANDBY_POL			0x00000020
+#define PWR_MGT_SUSPEND_POL			0x00000040
+#define PWR_MGT_SELF_REFRESH			0x00000080
+#define PWR_MGT_ACTIVITY_PIN_EN			0x00000100
+#define PWR_MGT_KEYBD_SNOOP			0x00000200
+#define PWR_MGT_TRISTATE_MEM_EN			0x00000800
+#define PWR_MGT_SELW4MS				0x00001000
+#define PWR_MGT_SLOWDOWN_MCLK			0x00002000
+
+#define PMI_PMSCR_REG				0x60
+
+#endif				/* REG_RAGE128_H */
diff -Nru a/include/video/mach64.h b/include/video/mach64.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/mach64.h	Wed Jul 24 14:03:38 2002
@@ -0,0 +1,1158 @@
+/*
+ * ATI Mach64 Register Definitions
+ *
+ * Copyright (C) 1997 Michael AK Tesch
+ *  written with much help from Jon Howell
+ *
+ * Updated for 3D RAGE PRO and 3D RAGE Mobility by Geert Uytterhoeven
+ *	
+ * 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.
+ */
+
+/*
+ * most of the rest of this file comes from ATI sample code
+ */
+#ifndef REGMACH64_H
+#define REGMACH64_H
+
+/* NON-GUI MEMORY MAPPED Registers - expressed in BYTE offsets */
+
+/* Accelerator CRTC */
+#define CRTC_H_TOTAL_DISP	0x0000	/* Dword offset 0_00 */
+#define CRTC2_H_TOTAL_DISP	0x0000	/* Dword offset 0_00 */
+#define CRTC_H_SYNC_STRT_WID	0x0004	/* Dword offset 0_01 */
+#define CRTC2_H_SYNC_STRT_WID	0x0004	/* Dword offset 0_01 */
+#define CRTC_H_SYNC_STRT	0x0004
+#define CRTC2_H_SYNC_STRT	0x0004
+#define CRTC_H_SYNC_DLY		0x0005
+#define CRTC2_H_SYNC_DLY	0x0005
+#define CRTC_H_SYNC_WID		0x0006
+#define CRTC2_H_SYNC_WID	0x0006
+#define CRTC_V_TOTAL_DISP	0x0008	/* Dword offset 0_02 */
+#define CRTC2_V_TOTAL_DISP	0x0008	/* Dword offset 0_02 */
+#define CRTC_V_TOTAL		0x0008
+#define CRTC2_V_TOTAL		0x0008
+#define CRTC_V_DISP		0x000A
+#define CRTC2_V_DISP		0x000A
+#define CRTC_V_SYNC_STRT_WID	0x000C	/* Dword offset 0_03 */
+#define CRTC2_V_SYNC_STRT_WID	0x000C	/* Dword offset 0_03 */
+#define CRTC_V_SYNC_STRT	0x000C
+#define CRTC2_V_SYNC_STRT	0x000C
+#define CRTC_V_SYNC_WID		0x000E
+#define CRTC2_V_SYNC_WID	0x000E
+#define CRTC_VLINE_CRNT_VLINE	0x0010	/* Dword offset 0_04 */
+#define CRTC2_VLINE_CRNT_VLINE	0x0010	/* Dword offset 0_04 */
+#define CRTC_OFF_PITCH		0x0014	/* Dword offset 0_05 */
+#define CRTC_OFFSET		0x0014
+#define CRTC_PITCH		0x0016
+#define CRTC_INT_CNTL		0x0018	/* Dword offset 0_06 */
+#define CRTC_GEN_CNTL		0x001C	/* Dword offset 0_07 */
+#define CRTC_PIX_WIDTH		0x001D
+#define CRTC_FIFO		0x001E
+#define CRTC_EXT_DISP		0x001F
+
+/* Memory Buffer Control */
+#define DSP_CONFIG		0x0020	/* Dword offset 0_08 */
+#define PM_DSP_CONFIG		0x0020	/* Dword offset 0_08 (Mobility Only) */
+#define DSP_ON_OFF		0x0024	/* Dword offset 0_09 */
+#define PM_DSP_ON_OFF		0x0024	/* Dword offset 0_09 (Mobility Only) */
+#define TIMER_CONFIG		0x0028	/* Dword offset 0_0A */
+#define MEM_BUF_CNTL		0x002C	/* Dword offset 0_0B */
+#define MEM_ADDR_CONFIG		0x0034	/* Dword offset 0_0D */
+
+/* Accelerator CRTC */
+#define CRT_TRAP		0x0038	/* Dword offset 0_0E */
+
+#define I2C_CNTL_0		0x003C	/* Dword offset 0_0F */
+
+/* Overscan */
+#define OVR_CLR			0x0040	/* Dword offset 0_10 */
+#define OVR2_CLR		0x0040	/* Dword offset 0_10 */
+#define OVR_WID_LEFT_RIGHT	0x0044	/* Dword offset 0_11 */
+#define OVR2_WID_LEFT_RIGHT	0x0044	/* Dword offset 0_11 */
+#define OVR_WID_TOP_BOTTOM	0x0048	/* Dword offset 0_12 */
+#define OVR2_WID_TOP_BOTTOM	0x0048	/* Dword offset 0_12 */
+
+/* Memory Buffer Control */
+#define VGA_DSP_CONFIG		0x004C	/* Dword offset 0_13 */
+#define PM_VGA_DSP_CONFIG	0x004C	/* Dword offset 0_13 (Mobility Only) */
+#define VGA_DSP_ON_OFF		0x0050	/* Dword offset 0_14 */
+#define PM_VGA_DSP_ON_OFF	0x0050	/* Dword offset 0_14 (Mobility Only) */
+#define DSP2_CONFIG		0x0054	/* Dword offset 0_15 */
+#define PM_DSP2_CONFIG		0x0054	/* Dword offset 0_15 (Mobility Only) */
+#define DSP2_ON_OFF		0x0058	/* Dword offset 0_16 */
+#define PM_DSP2_ON_OFF		0x0058	/* Dword offset 0_16 (Mobility Only) */
+
+/* Accelerator CRTC */
+#define CRTC2_OFF_PITCH		0x005C	/* Dword offset 0_17 */
+
+/* Hardware Cursor */
+#define CUR_CLR0		0x0060	/* Dword offset 0_18 */
+#define CUR2_CLR0		0x0060	/* Dword offset 0_18 */
+#define CUR_CLR1		0x0064	/* Dword offset 0_19 */
+#define CUR2_CLR1		0x0064	/* Dword offset 0_19 */
+#define CUR_OFFSET		0x0068	/* Dword offset 0_1A */
+#define CUR2_OFFSET		0x0068	/* Dword offset 0_1A */
+#define CUR_HORZ_VERT_POSN	0x006C	/* Dword offset 0_1B */
+#define CUR2_HORZ_VERT_POSN	0x006C	/* Dword offset 0_1B */
+#define CUR_HORZ_VERT_OFF	0x0070	/* Dword offset 0_1C */
+#define CUR2_HORZ_VERT_OFF	0x0070	/* Dword offset 0_1C */
+
+#define CONFIG_PANEL_LG		0x0074	/* Dword offset 0_1D */
+
+/* General I/O Control */
+#define GP_IO			0x0078	/* Dword offset 0_1E */
+
+/* Test and Debug */
+#define HW_DEBUG		0x007C	/* Dword offset 0_1F */
+
+/* Scratch Pad and Test */
+#define SCRATCH_REG0		0x0080	/* Dword offset 0_20 */
+#define SCRATCH_REG1		0x0084	/* Dword offset 0_21 */
+#define SCRATCH_REG2		0x0088	/* Dword offset 0_22 */
+#define SCRATCH_REG3		0x008C	/* Dword offset 0_23 */
+
+/* Clock Control */
+#define CLOCK_CNTL		0x0090	/* Dword offset 0_24 */
+#define CLOCK_SEL_CNTL		0x0090	/* Dword offset 0_24 */
+
+/* Configuration */
+#define CONFIG_STAT1		0x0094	/* Dword offset 0_25 */
+#define CONFIG_STAT2		0x0098	/* Dword offset 0_26 */
+
+/* Bus Control */
+#define BUS_CNTL		0x00A0	/* Dword offset 0_28 */
+
+#define LCD_INDEX		0x00A4	/* Dword offset 0_29 */
+#define LCD_DATA		0x00A8	/* Dword offset 0_2A */
+
+/* Memory Control */
+#define EXT_MEM_CNTL		0x00AC	/* Dword offset 0_2B */
+#define MEM_CNTL		0x00B0	/* Dword offset 0_2C */
+#define MEM_VGA_WP_SEL		0x00B4	/* Dword offset 0_2D */
+#define MEM_VGA_RP_SEL		0x00B8	/* Dword offset 0_2E */
+
+#define I2C_CNTL_1		0x00BC	/* Dword offset 0_2F */
+
+/* DAC Control */
+#define DAC_REGS		0x00C0	/* Dword offset 0_30 */
+#define DAC_W_INDEX		0x00C0	/* Dword offset 0_30 */
+#define DAC_DATA		0x00C1	/* Dword offset 0_30 */
+#define DAC_MASK		0x00C2	/* Dword offset 0_30 */
+#define DAC_R_INDEX		0x00C3	/* Dword offset 0_30 */
+#define DAC_CNTL		0x00C4	/* Dword offset 0_31 */
+
+#define EXT_DAC_REGS		0x00C8	/* Dword offset 0_32 */
+
+/* Test and Debug */
+#define GEN_TEST_CNTL		0x00D0	/* Dword offset 0_34 */
+
+/* Custom Macros */
+#define CUSTOM_MACRO_CNTL	0x00D4	/* Dword offset 0_35 */
+
+#define LCD_GEN_CNTL_LG		0x00D4	/* Dword offset 0_35 */
+
+#define POWER_MANAGEMENT_LG	0x00D8	/* Dword offset 0_36 (LG) */
+
+/* Configuration */
+#define CONFIG_CNTL		0x00DC	/* Dword offset 0_37 (CT, ET, VT) */
+#define CONFIG_CHIP_ID		0x00E0	/* Dword offset 0_38 */
+#define CONFIG_STAT0		0x00E4	/* Dword offset 0_39 */
+
+/* Test and Debug */
+#define CRC_SIG			0x00E8	/* Dword offset 0_3A */
+#define CRC2_SIG		0x00E8	/* Dword offset 0_3A */
+
+
+/* GUI MEMORY MAPPED Registers */
+
+/* Draw Engine Destination Trajectory */
+#define DST_OFF_PITCH		0x0100	/* Dword offset 0_40 */
+#define DST_X			0x0104	/* Dword offset 0_41 */
+#define DST_Y			0x0108	/* Dword offset 0_42 */
+#define DST_Y_X			0x010C	/* Dword offset 0_43 */
+#define DST_WIDTH		0x0110	/* Dword offset 0_44 */
+#define DST_HEIGHT		0x0114	/* Dword offset 0_45 */
+#define DST_HEIGHT_WIDTH	0x0118	/* Dword offset 0_46 */
+#define DST_X_WIDTH		0x011C	/* Dword offset 0_47 */
+#define DST_BRES_LNTH		0x0120	/* Dword offset 0_48 */
+#define DST_BRES_ERR		0x0124	/* Dword offset 0_49 */
+#define DST_BRES_INC		0x0128	/* Dword offset 0_4A */
+#define DST_BRES_DEC		0x012C	/* Dword offset 0_4B */
+#define DST_CNTL		0x0130	/* Dword offset 0_4C */
+#define DST_Y_X__ALIAS__	0x0134	/* Dword offset 0_4D */
+#define TRAIL_BRES_ERR		0x0138	/* Dword offset 0_4E */
+#define TRAIL_BRES_INC		0x013C	/* Dword offset 0_4F */
+#define TRAIL_BRES_DEC		0x0140	/* Dword offset 0_50 */
+#define LEAD_BRES_LNTH		0x0144	/* Dword offset 0_51 */
+#define Z_OFF_PITCH		0x0148	/* Dword offset 0_52 */
+#define Z_CNTL			0x014C	/* Dword offset 0_53 */
+#define ALPHA_TST_CNTL		0x0150	/* Dword offset 0_54 */
+#define SECONDARY_STW_EXP	0x0158	/* Dword offset 0_56 */
+#define SECONDARY_S_X_INC	0x015C	/* Dword offset 0_57 */
+#define SECONDARY_S_Y_INC	0x0160	/* Dword offset 0_58 */
+#define SECONDARY_S_START	0x0164	/* Dword offset 0_59 */
+#define SECONDARY_W_X_INC	0x0168	/* Dword offset 0_5A */
+#define SECONDARY_W_Y_INC	0x016C	/* Dword offset 0_5B */
+#define SECONDARY_W_START	0x0170	/* Dword offset 0_5C */
+#define SECONDARY_T_X_INC	0x0174	/* Dword offset 0_5D */
+#define SECONDARY_T_Y_INC	0x0178	/* Dword offset 0_5E */
+#define SECONDARY_T_START	0x017C	/* Dword offset 0_5F */
+
+/* Draw Engine Source Trajectory */
+#define SRC_OFF_PITCH		0x0180	/* Dword offset 0_60 */
+#define SRC_X			0x0184	/* Dword offset 0_61 */
+#define SRC_Y			0x0188	/* Dword offset 0_62 */
+#define SRC_Y_X			0x018C	/* Dword offset 0_63 */
+#define SRC_WIDTH1		0x0190	/* Dword offset 0_64 */
+#define SRC_HEIGHT1		0x0194	/* Dword offset 0_65 */
+#define SRC_HEIGHT1_WIDTH1	0x0198	/* Dword offset 0_66 */
+#define SRC_X_START		0x019C	/* Dword offset 0_67 */
+#define SRC_Y_START		0x01A0	/* Dword offset 0_68 */
+#define SRC_Y_X_START		0x01A4	/* Dword offset 0_69 */
+#define SRC_WIDTH2		0x01A8	/* Dword offset 0_6A */
+#define SRC_HEIGHT2		0x01AC	/* Dword offset 0_6B */
+#define SRC_HEIGHT2_WIDTH2	0x01B0	/* Dword offset 0_6C */
+#define SRC_CNTL		0x01B4	/* Dword offset 0_6D */
+
+#define SCALE_OFF		0x01C0	/* Dword offset 0_70 */
+#define SECONDARY_SCALE_OFF	0x01C4	/* Dword offset 0_71 */
+
+#define TEX_0_OFF		0x01C0	/* Dword offset 0_70 */
+#define TEX_1_OFF		0x01C4	/* Dword offset 0_71 */
+#define TEX_2_OFF		0x01C8	/* Dword offset 0_72 */
+#define TEX_3_OFF		0x01CC	/* Dword offset 0_73 */
+#define TEX_4_OFF		0x01D0	/* Dword offset 0_74 */
+#define TEX_5_OFF		0x01D4	/* Dword offset 0_75 */
+#define TEX_6_OFF		0x01D8	/* Dword offset 0_76 */
+#define TEX_7_OFF		0x01DC	/* Dword offset 0_77 */
+
+#define SCALE_WIDTH		0x01DC	/* Dword offset 0_77 */
+#define SCALE_HEIGHT		0x01E0	/* Dword offset 0_78 */
+
+#define TEX_8_OFF		0x01E0	/* Dword offset 0_78 */
+#define TEX_9_OFF		0x01E4	/* Dword offset 0_79 */
+#define TEX_10_OFF		0x01E8	/* Dword offset 0_7A */
+#define S_Y_INC			0x01EC	/* Dword offset 0_7B */
+
+#define SCALE_PITCH		0x01EC	/* Dword offset 0_7B */
+#define SCALE_X_INC		0x01F0	/* Dword offset 0_7C */
+
+#define RED_X_INC		0x01F0	/* Dword offset 0_7C */
+#define GREEN_X_INC		0x01F4	/* Dword offset 0_7D */
+
+#define SCALE_Y_INC		0x01F4	/* Dword offset 0_7D */
+#define SCALE_VACC		0x01F8	/* Dword offset 0_7E */
+#define SCALE_3D_CNTL		0x01FC	/* Dword offset 0_7F */
+
+/* Host Data */
+#define HOST_DATA0		0x0200	/* Dword offset 0_80 */
+#define HOST_DATA1		0x0204	/* Dword offset 0_81 */
+#define HOST_DATA2		0x0208	/* Dword offset 0_82 */
+#define HOST_DATA3		0x020C	/* Dword offset 0_83 */
+#define HOST_DATA4		0x0210	/* Dword offset 0_84 */
+#define HOST_DATA5		0x0214	/* Dword offset 0_85 */
+#define HOST_DATA6		0x0218	/* Dword offset 0_86 */
+#define HOST_DATA7		0x021C	/* Dword offset 0_87 */
+#define HOST_DATA8		0x0220	/* Dword offset 0_88 */
+#define HOST_DATA9		0x0224	/* Dword offset 0_89 */
+#define HOST_DATAA		0x0228	/* Dword offset 0_8A */
+#define HOST_DATAB		0x022C	/* Dword offset 0_8B */
+#define HOST_DATAC		0x0230	/* Dword offset 0_8C */
+#define HOST_DATAD		0x0234	/* Dword offset 0_8D */
+#define HOST_DATAE		0x0238	/* Dword offset 0_8E */
+#define HOST_DATAF		0x023C	/* Dword offset 0_8F */
+#define HOST_CNTL		0x0240	/* Dword offset 0_90 */
+
+/* GUI Bus Mastering */
+#define BM_HOSTDATA		0x0244	/* Dword offset 0_91 */
+#define BM_ADDR			0x0248	/* Dword offset 0_92 */
+#define BM_DATA			0x0248	/* Dword offset 0_92 */
+#define BM_GUI_TABLE_CMD	0x024C	/* Dword offset 0_93 */
+
+/* Pattern */
+#define PAT_REG0		0x0280	/* Dword offset 0_A0 */
+#define PAT_REG1		0x0284	/* Dword offset 0_A1 */
+#define PAT_CNTL		0x0288	/* Dword offset 0_A2 */
+
+/* Scissors */
+#define SC_LEFT			0x02A0	/* Dword offset 0_A8 */
+#define SC_RIGHT		0x02A4	/* Dword offset 0_A9 */
+#define SC_LEFT_RIGHT		0x02A8	/* Dword offset 0_AA */
+#define SC_TOP			0x02AC	/* Dword offset 0_AB */
+#define SC_BOTTOM		0x02B0	/* Dword offset 0_AC */
+#define SC_TOP_BOTTOM		0x02B4	/* Dword offset 0_AD */
+
+/* Data Path */
+#define USR1_DST_OFF_PITCH	0x02B8	/* Dword offset 0_AE */
+#define USR2_DST_OFF_PITCH	0x02BC	/* Dword offset 0_AF */
+#define DP_BKGD_CLR		0x02C0	/* Dword offset 0_B0 */
+#define DP_FOG_CLR		0x02C4	/* Dword offset 0_B1 */
+#define DP_FRGD_CLR		0x02C4	/* Dword offset 0_B1 */
+#define DP_WRITE_MASK		0x02C8	/* Dword offset 0_B2 */
+#define DP_CHAIN_MASK		0x02CC	/* Dword offset 0_B3 */
+#define DP_PIX_WIDTH		0x02D0	/* Dword offset 0_B4 */
+#define DP_MIX			0x02D4	/* Dword offset 0_B5 */
+#define DP_SRC			0x02D8	/* Dword offset 0_B6 */
+#define DP_FRGD_CLR_MIX		0x02DC	/* Dword offset 0_B7 */
+#define DP_FRGD_BKGD_CLR	0x02E0	/* Dword offset 0_B8 */
+
+/* Draw Engine Destination Trajectory */
+#define DST_X_Y			0x02E8	/* Dword offset 0_BA */
+#define DST_WIDTH_HEIGHT	0x02EC	/* Dword offset 0_BB */
+
+/* Data Path */
+#define USR_DST_PICTH		0x02F0	/* Dword offset 0_BC */
+#define DP_SET_GUI_ENGINE2	0x02F8	/* Dword offset 0_BE */
+#define DP_SET_GUI_ENGINE	0x02FC	/* Dword offset 0_BF */
+
+/* Color Compare */
+#define CLR_CMP_CLR		0x0300	/* Dword offset 0_C0 */
+#define CLR_CMP_MASK		0x0304	/* Dword offset 0_C1 */
+#define CLR_CMP_CNTL		0x0308	/* Dword offset 0_C2 */
+
+/* Command FIFO */
+#define FIFO_STAT		0x0310	/* Dword offset 0_C4 */
+
+#define CONTEXT_MASK		0x0320	/* Dword offset 0_C8 */
+#define CONTEXT_LOAD_CNTL	0x032C	/* Dword offset 0_CB */
+
+/* Engine Control */
+#define GUI_TRAJ_CNTL		0x0330	/* Dword offset 0_CC */
+
+/* Engine Status/FIFO */
+#define GUI_STAT		0x0338	/* Dword offset 0_CE */
+
+#define TEX_PALETTE_INDEX	0x0340	/* Dword offset 0_D0 */
+#define STW_EXP			0x0344	/* Dword offset 0_D1 */
+#define LOG_MAX_INC		0x0348	/* Dword offset 0_D2 */
+#define S_X_INC			0x034C	/* Dword offset 0_D3 */
+#define S_Y_INC__ALIAS__	0x0350	/* Dword offset 0_D4 */
+
+#define SCALE_PITCH__ALIAS__	0x0350	/* Dword offset 0_D4 */
+
+#define S_START			0x0354	/* Dword offset 0_D5 */
+#define W_X_INC			0x0358	/* Dword offset 0_D6 */
+#define W_Y_INC			0x035C	/* Dword offset 0_D7 */
+#define W_START			0x0360	/* Dword offset 0_D8 */
+#define T_X_INC			0x0364	/* Dword offset 0_D9 */
+#define T_Y_INC			0x0368	/* Dword offset 0_DA */
+
+#define SECONDARY_SCALE_PITCH	0x0368	/* Dword offset 0_DA */
+
+#define T_START			0x036C	/* Dword offset 0_DB */
+#define TEX_SIZE_PITCH		0x0370	/* Dword offset 0_DC */
+#define TEX_CNTL		0x0374	/* Dword offset 0_DD */
+#define SECONDARY_TEX_OFFSET	0x0378	/* Dword offset 0_DE */
+#define TEX_PALETTE		0x037C	/* Dword offset 0_DF */
+
+#define SCALE_PITCH_BOTH	0x0380	/* Dword offset 0_E0 */
+#define SECONDARY_SCALE_OFF_ACC	0x0384	/* Dword offset 0_E1 */
+#define SCALE_OFF_ACC		0x0388	/* Dword offset 0_E2 */
+#define SCALE_DST_Y_X		0x038C	/* Dword offset 0_E3 */
+
+/* Draw Engine Destination Trajectory */
+#define COMPOSITE_SHADOW_ID	0x0398	/* Dword offset 0_E6 */
+
+#define SECONDARY_SCALE_X_INC	0x039C	/* Dword offset 0_E7 */
+
+#define SPECULAR_RED_X_INC	0x039C	/* Dword offset 0_E7 */
+#define SPECULAR_RED_Y_INC	0x03A0	/* Dword offset 0_E8 */
+#define SPECULAR_RED_START	0x03A4	/* Dword offset 0_E9 */
+
+#define SECONDARY_SCALE_HACC	0x03A4	/* Dword offset 0_E9 */
+
+#define SPECULAR_GREEN_X_INC	0x03A8	/* Dword offset 0_EA */
+#define SPECULAR_GREEN_Y_INC	0x03AC	/* Dword offset 0_EB */
+#define SPECULAR_GREEN_START	0x03B0	/* Dword offset 0_EC */
+#define SPECULAR_BLUE_X_INC	0x03B4	/* Dword offset 0_ED */
+#define SPECULAR_BLUE_Y_INC	0x03B8	/* Dword offset 0_EE */
+#define SPECULAR_BLUE_START	0x03BC	/* Dword offset 0_EF */
+
+#define SCALE_X_INC__ALIAS__	0x03C0	/* Dword offset 0_F0 */
+
+#define RED_X_INC__ALIAS__	0x03C0	/* Dword offset 0_F0 */
+#define RED_Y_INC		0x03C4	/* Dword offset 0_F1 */
+#define RED_START		0x03C8	/* Dword offset 0_F2 */
+
+#define SCALE_HACC		0x03C8	/* Dword offset 0_F2 */
+#define SCALE_Y_INC__ALIAS__	0x03CC	/* Dword offset 0_F3 */
+
+#define GREEN_X_INC__ALIAS__	0x03CC	/* Dword offset 0_F3 */
+#define GREEN_Y_INC		0x03D0	/* Dword offset 0_F4 */
+
+#define SECONDARY_SCALE_Y_INC	0x03D0	/* Dword offset 0_F4 */
+#define SECONDARY_SCALE_VACC	0x03D4	/* Dword offset 0_F5 */
+
+#define GREEN_START		0x03D4	/* Dword offset 0_F5 */
+#define BLUE_X_INC		0x03D8	/* Dword offset 0_F6 */
+#define BLUE_Y_INC		0x03DC	/* Dword offset 0_F7 */
+#define BLUE_START		0x03E0	/* Dword offset 0_F8 */
+#define Z_X_INC			0x03E4	/* Dword offset 0_F9 */
+#define Z_Y_INC			0x03E8	/* Dword offset 0_FA */
+#define Z_START			0x03EC	/* Dword offset 0_FB */
+#define ALPHA_X_INC		0x03F0	/* Dword offset 0_FC */
+#define FOG_X_INC		0x03F0	/* Dword offset 0_FC */
+#define ALPHA_Y_INC		0x03F4	/* Dword offset 0_FD */
+#define FOG_Y_INC		0x03F4	/* Dword offset 0_FD */
+#define ALPHA_START		0x03F8	/* Dword offset 0_FE */
+#define FOG_START		0x03F8	/* Dword offset 0_FE */
+
+#define OVERLAY_Y_X_START		0x0400	/* Dword offset 1_00 */
+#define OVERLAY_Y_X_END			0x0404	/* Dword offset 1_01 */
+#define OVERLAY_VIDEO_KEY_CLR		0x0408	/* Dword offset 1_02 */
+#define OVERLAY_VIDEO_KEY_MSK		0x040C	/* Dword offset 1_03 */
+#define OVERLAY_GRAPHICS_KEY_CLR	0x0410	/* Dword offset 1_04 */
+#define OVERLAY_GRAPHICS_KEY_MSK	0x0414	/* Dword offset 1_05 */
+#define OVERLAY_KEY_CNTL		0x0418	/* Dword offset 1_06 */
+
+#define OVERLAY_SCALE_INC	0x0420	/* Dword offset 1_08 */
+#define OVERLAY_SCALE_CNTL	0x0424	/* Dword offset 1_09 */
+#define SCALER_HEIGHT_WIDTH	0x0428	/* Dword offset 1_0A */
+#define SCALER_TEST		0x042C	/* Dword offset 1_0B */
+#define SCALER_BUF0_OFFSET	0x0434	/* Dword offset 1_0D */
+#define SCALER_BUF1_OFFSET	0x0438	/* Dword offset 1_0E */
+#define SCALE_BUF_PITCH		0x043C	/* Dword offset 1_0F */
+
+#define CAPTURE_START_END	0x0440	/* Dword offset 1_10 */
+#define CAPTURE_X_WIDTH		0x0444	/* Dword offset 1_11 */
+#define VIDEO_FORMAT		0x0448	/* Dword offset 1_12 */
+#define VBI_START_END		0x044C	/* Dword offset 1_13 */
+#define CAPTURE_CONFIG		0x0450	/* Dword offset 1_14 */
+#define TRIG_CNTL		0x0454	/* Dword offset 1_15 */
+
+#define OVERLAY_EXCLUSIVE_HORZ	0x0458	/* Dword offset 1_16 */
+#define OVERLAY_EXCLUSIVE_VERT	0x045C	/* Dword offset 1_17 */
+
+#define VAL_WIDTH		0x0460	/* Dword offset 1_18 */
+#define CAPTURE_DEBUG		0x0464	/* Dword offset 1_19 */
+#define VIDEO_SYNC_TEST		0x0468	/* Dword offset 1_1A */
+
+/* GenLocking */
+#define SNAPSHOT_VH_COUNTS	0x0470	/* Dword offset 1_1C */
+#define SNAPSHOT_F_COUNT	0x0474	/* Dword offset 1_1D */
+#define N_VIF_COUNT		0x0478	/* Dword offset 1_1E */
+#define SNAPSHOT_VIF_COUNT	0x047C	/* Dword offset 1_1F */
+
+#define CAPTURE_BUF0_OFFSET	0x0480	/* Dword offset 1_20 */
+#define CAPTURE_BUF1_OFFSET	0x0484	/* Dword offset 1_21 */
+#define CAPTURE_BUF_PITCH	0x0488	/* Dword offset 1_22 */
+
+/* GenLocking */
+#define SNAPSHOT2_VH_COUNTS	0x04B0	/* Dword offset 1_2C */
+#define SNAPSHOT2_F_COUNT	0x04B4	/* Dword offset 1_2D */
+#define N_VIF2_COUNT		0x04B8	/* Dword offset 1_2E */
+#define SNAPSHOT2_VIF_COUNT	0x04BC	/* Dword offset 1_2F */
+
+#define MPP_CONFIG		0x04C0	/* Dword offset 1_30 */
+#define MPP_STROBE_SEQ		0x04C4	/* Dword offset 1_31 */
+#define MPP_ADDR		0x04C8	/* Dword offset 1_32 */
+#define MPP_DATA		0x04CC	/* Dword offset 1_33 */
+#define TVO_CNTL		0x0500	/* Dword offset 1_40 */
+
+/* Test and Debug */
+#define CRT_HORZ_VERT_LOAD	0x0544	/* Dword offset 1_51 */
+
+/* AGP */
+#define AGP_BASE		0x0548	/* Dword offset 1_52 */
+#define AGP_CNTL		0x054C	/* Dword offset 1_53 */
+
+#define SCALER_COLOUR_CNTL	0x0550	/* Dword offset 1_54 */
+#define SCALER_H_COEFF0		0x0554	/* Dword offset 1_55 */
+#define SCALER_H_COEFF1		0x0558	/* Dword offset 1_56 */
+#define SCALER_H_COEFF2		0x055C	/* Dword offset 1_57 */
+#define SCALER_H_COEFF3		0x0560	/* Dword offset 1_58 */
+#define SCALER_H_COEFF4		0x0564	/* Dword offset 1_59 */
+
+/* Command FIFO */
+#define GUI_CMDFIFO_DEBUG	0x0570	/* Dword offset 1_5C */
+#define GUI_CMDFIFO_DATA	0x0574	/* Dword offset 1_5D */
+#define GUI_CNTL		0x0578	/* Dword offset 1_5E */
+
+/* Bus Mastering */
+#define BM_FRAME_BUF_OFFSET	0x0580	/* Dword offset 1_60 */
+#define BM_SYSTEM_MEM_ADDR	0x0584	/* Dword offset 1_61 */
+#define BM_COMMAND		0x0588	/* Dword offset 1_62 */
+#define BM_STATUS		0x058C	/* Dword offset 1_63 */
+#define BM_GUI_TABLE		0x05B8	/* Dword offset 1_6E */
+#define BM_SYSTEM_TABLE		0x05BC	/* Dword offset 1_6F */
+
+#define SCALER_BUF0_OFFSET_U	0x05D4	/* Dword offset 1_75 */
+#define SCALER_BUF0_OFFSET_V	0x05D8	/* Dword offset 1_76 */
+#define SCALER_BUF1_OFFSET_U	0x05DC	/* Dword offset 1_77 */
+#define SCALER_BUF1_OFFSET_V	0x05E0	/* Dword offset 1_78 */
+
+/* Setup Engine */
+#define VERTEX_1_S		0x0640	/* Dword offset 1_90 */
+#define VERTEX_1_T		0x0644	/* Dword offset 1_91 */
+#define VERTEX_1_W		0x0648	/* Dword offset 1_92 */
+#define VERTEX_1_SPEC_ARGB	0x064C	/* Dword offset 1_93 */
+#define VERTEX_1_Z		0x0650	/* Dword offset 1_94 */
+#define VERTEX_1_ARGB		0x0654	/* Dword offset 1_95 */
+#define VERTEX_1_X_Y		0x0658	/* Dword offset 1_96 */
+#define ONE_OVER_AREA		0x065C	/* Dword offset 1_97 */
+#define VERTEX_2_S		0x0660	/* Dword offset 1_98 */
+#define VERTEX_2_T		0x0664	/* Dword offset 1_99 */
+#define VERTEX_2_W		0x0668	/* Dword offset 1_9A */
+#define VERTEX_2_SPEC_ARGB	0x066C	/* Dword offset 1_9B */
+#define VERTEX_2_Z		0x0670	/* Dword offset 1_9C */
+#define VERTEX_2_ARGB		0x0674	/* Dword offset 1_9D */
+#define VERTEX_2_X_Y		0x0678	/* Dword offset 1_9E */
+#define ONE_OVER_AREA		0x065C	/* Dword offset 1_9F */
+#define VERTEX_3_S		0x0680	/* Dword offset 1_A0 */
+#define VERTEX_3_T		0x0684	/* Dword offset 1_A1 */
+#define VERTEX_3_W		0x0688	/* Dword offset 1_A2 */
+#define VERTEX_3_SPEC_ARGB	0x068C	/* Dword offset 1_A3 */
+#define VERTEX_3_Z		0x0690	/* Dword offset 1_A4 */
+#define VERTEX_3_ARGB		0x0694	/* Dword offset 1_A5 */
+#define VERTEX_3_X_Y		0x0698	/* Dword offset 1_A6 */
+#define ONE_OVER_AREA		0x065C	/* Dword offset 1_A7 */
+#define VERTEX_1_S		0x0640	/* Dword offset 1_AB */
+#define VERTEX_1_T		0x0644	/* Dword offset 1_AC */
+#define VERTEX_1_W		0x0648	/* Dword offset 1_AD */
+#define VERTEX_2_S		0x0660	/* Dword offset 1_AE */
+#define VERTEX_2_T		0x0664	/* Dword offset 1_AF */
+#define VERTEX_2_W		0x0668	/* Dword offset 1_B0 */
+#define VERTEX_3_SECONDARY_S	0x06C0	/* Dword offset 1_B0 */
+#define VERTEX_3_S		0x0680	/* Dword offset 1_B1 */
+#define VERTEX_3_SECONDARY_T	0x06C4	/* Dword offset 1_B1 */
+#define VERTEX_3_T		0x0684	/* Dword offset 1_B2 */
+#define VERTEX_3_SECONDARY_W	0x06C8	/* Dword offset 1_B2 */
+#define VERTEX_3_W		0x0688	/* Dword offset 1_B3 */
+#define VERTEX_1_SPEC_ARGB	0x064C	/* Dword offset 1_B4 */
+#define VERTEX_2_SPEC_ARGB	0x066C	/* Dword offset 1_B5 */
+#define VERTEX_3_SPEC_ARGB	0x068C	/* Dword offset 1_B6 */
+#define VERTEX_1_Z		0x0650	/* Dword offset 1_B7 */
+#define VERTEX_2_Z		0x0670	/* Dword offset 1_B8 */
+#define VERTEX_3_Z		0x0690	/* Dword offset 1_B9 */
+#define VERTEX_1_ARGB		0x0654	/* Dword offset 1_BA */
+#define VERTEX_2_ARGB		0x0674	/* Dword offset 1_BB */
+#define VERTEX_3_ARGB		0x0694	/* Dword offset 1_BC */
+#define VERTEX_1_X_Y		0x0658	/* Dword offset 1_BD */
+#define VERTEX_2_X_Y		0x0678	/* Dword offset 1_BE */
+#define VERTEX_3_X_Y		0x0698	/* Dword offset 1_BF */
+#define ONE_OVER_AREA_UC	0x0700	/* Dword offset 1_C0 */
+#define SETUP_CNTL		0x0704	/* Dword offset 1_C1 */
+#define VERTEX_1_SECONDARY_S	0x0728	/* Dword offset 1_CA */
+#define VERTEX_1_SECONDARY_T	0x072C	/* Dword offset 1_CB */
+#define VERTEX_1_SECONDARY_W	0x0730	/* Dword offset 1_CC */
+#define VERTEX_2_SECONDARY_S	0x0734	/* Dword offset 1_CD */
+#define VERTEX_2_SECONDARY_T	0x0738	/* Dword offset 1_CE */
+#define VERTEX_2_SECONDARY_W	0x073C	/* Dword offset 1_CF */
+
+
+#define GTC_3D_RESET_DELAY	3	/* 3D engine reset delay in ms */
+
+/* CRTC control values (mostly CRTC_GEN_CNTL) */
+
+#define CRTC_H_SYNC_NEG		0x00200000
+#define CRTC_V_SYNC_NEG		0x00200000
+
+#define CRTC_DBL_SCAN_EN	0x00000001
+#define CRTC_INTERLACE_EN	0x00000002
+#define CRTC_HSYNC_DIS		0x00000004
+#define CRTC_VSYNC_DIS		0x00000008
+#define CRTC_CSYNC_EN		0x00000010
+#define CRTC_PIX_BY_2_EN	0x00000020	/* unused on RAGE */
+#define CRTC_DISPLAY_DIS	0x00000040
+#define CRTC_VGA_XOVERSCAN	0x00000040
+
+#define CRTC_PIX_WIDTH_MASK	0x00000700
+#define CRTC_PIX_WIDTH_4BPP	0x00000100
+#define CRTC_PIX_WIDTH_8BPP	0x00000200
+#define CRTC_PIX_WIDTH_15BPP	0x00000300
+#define CRTC_PIX_WIDTH_16BPP	0x00000400
+#define CRTC_PIX_WIDTH_24BPP	0x00000500
+#define CRTC_PIX_WIDTH_32BPP	0x00000600
+
+#define CRTC_BYTE_PIX_ORDER	0x00000800
+#define CRTC_PIX_ORDER_MSN_LSN	0x00000000
+#define CRTC_PIX_ORDER_LSN_MSN	0x00000800
+
+#define CRTC_FIFO_LWM		0x000f0000
+
+#define VGA_128KAP_PAGING	0x00100000
+#define VFC_SYNC_TRISTATE	0x00200000
+#define CRTC_LOCK_REGS		0x00400000
+#define CRTC_SYNC_TRISTATE	0x00800000
+
+#define CRTC_EXT_DISP_EN	0x01000000
+#define CRTC_ENABLE		0x02000000
+#define CRTC_DISP_REQ_ENB	0x04000000
+#define VGA_ATI_LINEAR		0x08000000
+#define CRTC_VSYNC_FALL_EDGE	0x10000000
+#define VGA_TEXT_132		0x20000000
+#define VGA_XCRT_CNT_EN		0x40000000
+#define VGA_CUR_B_TEST		0x80000000
+
+#define CRTC_CRNT_VLINE		0x07f00000
+#define CRTC_VBLANK		0x00000001
+
+
+/* DAC control values */
+
+#define DAC_EXT_SEL_RS2		0x01
+#define DAC_EXT_SEL_RS3		0x02
+#define DAC_8BIT_EN		0x00000100
+#define DAC_PIX_DLY_MASK	0x00000600
+#define DAC_PIX_DLY_0NS		0x00000000
+#define DAC_PIX_DLY_2NS		0x00000200
+#define DAC_PIX_DLY_4NS		0x00000400
+#define DAC_BLANK_ADJ_MASK	0x00001800
+#define DAC_BLANK_ADJ_0		0x00000000
+#define DAC_BLANK_ADJ_1		0x00000800
+#define DAC_BLANK_ADJ_2		0x00001000
+
+
+/* Mix control values */
+
+#define MIX_NOT_DST		0x0000
+#define MIX_0			0x0001
+#define MIX_1			0x0002
+#define MIX_DST			0x0003
+#define MIX_NOT_SRC		0x0004
+#define MIX_XOR			0x0005
+#define MIX_XNOR		0x0006
+#define MIX_SRC			0x0007
+#define MIX_NAND		0x0008
+#define MIX_NOT_SRC_OR_DST	0x0009
+#define MIX_SRC_OR_NOT_DST	0x000a
+#define MIX_OR			0x000b
+#define MIX_AND			0x000c
+#define MIX_SRC_AND_NOT_DST	0x000d
+#define MIX_NOT_SRC_AND_DST	0x000e
+#define MIX_NOR			0x000f
+
+/* Maximum engine dimensions */
+#define ENGINE_MIN_X		0
+#define ENGINE_MIN_Y		0
+#define ENGINE_MAX_X		4095
+#define ENGINE_MAX_Y		16383
+
+/* Mach64 engine bit constants - these are typically ORed together */
+
+/* BUS_CNTL register constants */
+#define BUS_FIFO_ERR_ACK	0x00200000
+#define BUS_HOST_ERR_ACK	0x00800000
+
+/* GEN_TEST_CNTL register constants */
+#define GEN_OVR_OUTPUT_EN	0x20
+#define HWCURSOR_ENABLE		0x80
+#define GUI_ENGINE_ENABLE	0x100
+#define BLOCK_WRITE_ENABLE	0x200
+
+/* DSP_CONFIG register constants */
+#define DSP_XCLKS_PER_QW	0x00003fff
+#define DSP_LOOP_LATENCY	0x000f0000
+#define DSP_PRECISION		0x00700000
+
+/* DSP_ON_OFF register constants */
+#define DSP_OFF			0x000007ff
+#define DSP_ON			0x07ff0000
+
+/* CLOCK_CNTL register constants */
+#define CLOCK_SEL		0x0f
+#define CLOCK_DIV		0x30
+#define CLOCK_DIV1		0x00
+#define CLOCK_DIV2		0x10
+#define CLOCK_DIV4		0x20
+#define CLOCK_STROBE		0x40
+#define PLL_WR_EN		0x02
+
+/* PLL register indices */
+#define MPLL_CNTL		0x00
+#define VPLL_CNTL		0x01
+#define PLL_REF_DIV		0x02
+#define PLL_GEN_CNTL		0x03
+#define MCLK_FB_DIV		0x04
+#define PLL_VCLK_CNTL		0x05
+#define VCLK_POST_DIV		0x06
+#define VCLK0_FB_DIV		0x07
+#define VCLK1_FB_DIV		0x08
+#define VCLK2_FB_DIV		0x09
+#define VCLK3_FB_DIV		0x0A
+#define PLL_EXT_CNTL		0x0B
+#define DLL_CNTL		0x0C
+#define DLL1_CNTL		0x0C
+#define VFC_CNTL		0x0D
+#define PLL_TEST_CNTL		0x0E
+#define PLL_TEST_COUNT		0x0F
+#define LVDS_CNTL0		0x10
+#define LVDS_CNTL1		0x11
+#define AGP1_CNTL		0x12
+#define AGP2_CNTL		0x13
+#define DLL2_CNTL		0x14
+#define SCLK_FB_DIV		0x15
+#define SPLL_CNTL1		0x16
+#define SPLL_CNTL2		0x17
+#define APLL_STRAPS		0x18
+#define EXT_VPLL_CNTL		0x19
+#define EXT_VPLL_REF_DIV	0x1A
+#define EXT_VPLL_FB_DIV		0x1B
+#define EXT_VPLL_MSB		0x1C
+#define HTOTAL_CNTL		0x1D
+#define BYTE_CLK_CNTL		0x1E
+#define TV_PLL_CNTL1		0x1F
+#define TV_PLL_CNTL2		0x20
+#define TV_PLL_CNTL		0x21
+#define EXT_TV_PLL		0x22
+#define V2PLL_CNTL		0x23
+#define PLL_V2CLK_CNTL		0x24
+#define EXT_V2PLL_REF_DIV	0x25
+#define EXT_V2PLL_FB_DIV	0x26
+#define EXT_V2PLL_MSB		0x27
+#define HTOTAL2_CNTL		0x28
+#define PLL_YCLK_CNTL		0x29
+#define PM_DYN_CLK_CNTL		0x2A
+
+/* Fields in PLL registers */
+#define PLL_PC_GAIN		0x07
+#define PLL_VC_GAIN		0x18
+#define PLL_DUTY_CYC		0xE0
+#define PLL_OVERRIDE		0x01
+#define PLL_MCLK_RST		0x02
+#define OSC_EN			0x04
+#define EXT_CLK_EN		0x08
+#define MCLK_SRC_SEL		0x70
+#define EXT_CLK_CNTL		0x80
+#define VCLK_SRC_SEL		0x03
+#define PLL_VCLK_RST		0x04
+#define VCLK_INVERT		0x08
+#define VCLK0_POST		0x03
+#define VCLK1_POST		0x0C
+#define VCLK2_POST		0x30
+#define VCLK3_POST		0xC0
+
+/* CONFIG_CNTL register constants */
+#define APERTURE_4M_ENABLE	1
+#define APERTURE_8M_ENABLE	2
+#define VGA_APERTURE_ENABLE	4
+
+/* CONFIG_STAT0 register constants (GX, CX) */
+#define CFG_BUS_TYPE		0x00000007
+#define CFG_MEM_TYPE		0x00000038
+#define CFG_INIT_DAC_TYPE	0x00000e00
+
+/* CONFIG_STAT0 register constants (CT, ET, VT) */
+#define CFG_MEM_TYPE_xT		0x00000007
+
+#define ISA			0
+#define EISA			1
+#define LOCAL_BUS		6
+#define PCI			7
+
+/* Memory types for GX, CX */
+#define DRAMx4			0
+#define VRAMx16			1
+#define VRAMx16ssr		2
+#define DRAMx16			3
+#define GraphicsDRAMx16		4
+#define EnhancedVRAMx16		5
+#define EnhancedVRAMx16ssr	6
+
+/* Memory types for CT, ET, VT, GT */
+#define DRAM			1
+#define EDO			2
+#define PSEUDO_EDO		3
+#define SDRAM			4
+#define SGRAM			5
+#define WRAM			6
+
+#define DAC_INTERNAL		0x00
+#define DAC_IBMRGB514		0x01
+#define DAC_ATI68875		0x02
+#define DAC_TVP3026_A		0x72
+#define DAC_BT476		0x03
+#define DAC_BT481		0x04
+#define DAC_ATT20C491		0x14
+#define DAC_SC15026		0x24
+#define DAC_MU9C1880		0x34
+#define DAC_IMSG174		0x44
+#define DAC_ATI68860_B		0x05
+#define DAC_ATI68860_C		0x15
+#define DAC_TVP3026_B		0x75
+#define DAC_STG1700		0x06
+#define DAC_ATT498		0x16
+#define DAC_STG1702		0x07
+#define DAC_SC15021		0x17
+#define DAC_ATT21C498		0x27
+#define DAC_STG1703		0x37
+#define DAC_CH8398		0x47
+#define DAC_ATT20C408		0x57
+
+#define CLK_ATI18818_0		0
+#define CLK_ATI18818_1		1
+#define CLK_STG1703		2
+#define CLK_CH8398		3
+#define CLK_INTERNAL		4
+#define CLK_ATT20C408		5
+#define CLK_IBMRGB514		6
+
+/* MEM_CNTL register constants */
+#define MEM_SIZE_ALIAS		0x00000007
+#define MEM_SIZE_512K		0x00000000
+#define MEM_SIZE_1M		0x00000001
+#define MEM_SIZE_2M		0x00000002
+#define MEM_SIZE_4M		0x00000003
+#define MEM_SIZE_6M		0x00000004
+#define MEM_SIZE_8M		0x00000005
+#define MEM_SIZE_ALIAS_GTB	0x0000000F
+#define MEM_SIZE_2M_GTB		0x00000003
+#define MEM_SIZE_4M_GTB		0x00000007
+#define MEM_SIZE_6M_GTB		0x00000009
+#define MEM_SIZE_8M_GTB		0x0000000B
+#define MEM_BNDRY		0x00030000
+#define MEM_BNDRY_0K		0x00000000
+#define MEM_BNDRY_256K		0x00010000
+#define MEM_BNDRY_512K		0x00020000
+#define MEM_BNDRY_1M		0x00030000
+#define MEM_BNDRY_EN		0x00040000
+
+/* ATI PCI constants */
+#define PCI_ATI_VENDOR_ID	0x1002
+
+
+/* CONFIG_CHIP_ID register constants */
+#define CFG_CHIP_TYPE		0x0000FFFF
+#define CFG_CHIP_CLASS		0x00FF0000
+#define CFG_CHIP_REV		0xFF000000
+#define CFG_CHIP_MAJOR		0x07000000
+#define CFG_CHIP_FND_ID		0x38000000
+#define CFG_CHIP_MINOR		0xC0000000
+
+
+/* Chip IDs read from CONFIG_CHIP_ID */
+
+/* mach64GX family */
+#define GX_CHIP_ID	0xD7	/* mach64GX (ATI888GX00) */
+#define CX_CHIP_ID	0x57	/* mach64CX (ATI888CX00) */
+
+#define GX_PCI_ID	0x4758	/* mach64GX (ATI888GX00) */
+#define CX_PCI_ID	0x4358	/* mach64CX (ATI888CX00) */
+
+/* mach64CT family */
+#define CT_CHIP_ID	0x4354	/* mach64CT (ATI264CT) */
+#define ET_CHIP_ID	0x4554	/* mach64ET (ATI264ET) */
+
+/* mach64CT family / mach64VT class */
+#define VT_CHIP_ID	0x5654	/* mach64VT (ATI264VT) */
+#define VU_CHIP_ID	0x5655	/* mach64VTB (ATI264VTB) */
+#define VV_CHIP_ID	0x5656	/* mach64VT4 (ATI264VT4) */
+
+/* mach64CT family / mach64GT (3D RAGE) class */
+#define LB_CHIP_ID	0x4c42	/* RAGE LT PRO, AGP */
+#define LD_CHIP_ID	0x4c44	/* RAGE LT PRO */
+#define LG_CHIP_ID	0x4c47	/* RAGE LT */
+#define LI_CHIP_ID	0x4c49	/* RAGE LT PRO */
+#define LP_CHIP_ID	0x4c50	/* RAGE LT PRO */
+#define LT_CHIP_ID	0x4c54	/* RAGE LT */
+#define XL_CHIP_ID	0x4752	/* RAGE (XL) */
+#define GT_CHIP_ID	0x4754	/* RAGE (GT) */
+#define GU_CHIP_ID	0x4755	/* RAGE II/II+ (GTB) */
+#define GV_CHIP_ID	0x4756	/* RAGE IIC, PCI */
+#define GW_CHIP_ID	0x4757	/* RAGE IIC, AGP */
+#define GZ_CHIP_ID	0x475a	/* RAGE IIC, AGP */
+#define GB_CHIP_ID	0x4742	/* RAGE PRO, BGA, AGP 1x and 2x */
+#define GD_CHIP_ID	0x4744	/* RAGE PRO, BGA, AGP 1x only */
+#define GI_CHIP_ID	0x4749	/* RAGE PRO, BGA, PCI33 only */
+#define GP_CHIP_ID	0x4750	/* RAGE PRO, PQFP, PCI33, full 3D */
+#define GQ_CHIP_ID	0x4751	/* RAGE PRO, PQFP, PCI33, limited 3D */
+#define LM_CHIP_ID	0x4c4d	/* RAGE Mobility PCI */
+#define LN_CHIP_ID	0x4c4e	/* RAGE Mobility AGP */
+
+
+/* Mach64 major ASIC revisions */
+#define MACH64_ASIC_NEC_VT_A3		0x08
+#define MACH64_ASIC_NEC_VT_A4		0x48
+#define MACH64_ASIC_SGS_VT_A4		0x40
+#define MACH64_ASIC_SGS_VT_B1S1		0x01
+#define MACH64_ASIC_SGS_GT_B1S1		0x01
+#define MACH64_ASIC_SGS_GT_B1S2		0x41
+#define MACH64_ASIC_UMC_GT_B2U1		0x1a
+#define MACH64_ASIC_UMC_GT_B2U2		0x5a
+#define MACH64_ASIC_UMC_VT_B2U3		0x9a
+#define MACH64_ASIC_UMC_GT_B2U3		0x9a
+#define MACH64_ASIC_UMC_R3B_D_P_A1	0x1b
+#define MACH64_ASIC_UMC_R3B_D_P_A2	0x5b
+#define MACH64_ASIC_UMC_R3B_D_P_A3	0x1c
+#define MACH64_ASIC_UMC_R3B_D_P_A4	0x5c
+
+/* Mach64 foundries */
+#define MACH64_FND_SGS		0
+#define MACH64_FND_NEC		1
+#define MACH64_FND_UMC		3
+
+/* Mach64 chip types */
+#define MACH64_UNKNOWN		0
+#define MACH64_GX		1
+#define MACH64_CX		2
+#define MACH64_CT		3
+#define MACH64_ET		4
+#define MACH64_VT		5
+#define MACH64_GT		6
+
+/* DST_CNTL register constants */
+#define DST_X_RIGHT_TO_LEFT	0
+#define DST_X_LEFT_TO_RIGHT	1
+#define DST_Y_BOTTOM_TO_TOP	0
+#define DST_Y_TOP_TO_BOTTOM	2
+#define DST_X_MAJOR		0
+#define DST_Y_MAJOR		4
+#define DST_X_TILE		8
+#define DST_Y_TILE		0x10
+#define DST_LAST_PEL		0x20
+#define DST_POLYGON_ENABLE	0x40
+#define DST_24_ROTATION_ENABLE	0x80
+
+/* SRC_CNTL register constants */
+#define SRC_PATTERN_ENABLE		1
+#define SRC_ROTATION_ENABLE		2
+#define SRC_LINEAR_ENABLE		4
+#define SRC_BYTE_ALIGN			8
+#define SRC_LINE_X_RIGHT_TO_LEFT	0
+#define SRC_LINE_X_LEFT_TO_RIGHT	0x10
+
+/* HOST_CNTL register constants */
+#define HOST_BYTE_ALIGN		1
+
+/* GUI_TRAJ_CNTL register constants */
+#define PAT_MONO_8x8_ENABLE	0x01000000
+#define PAT_CLR_4x2_ENABLE	0x02000000
+#define PAT_CLR_8x1_ENABLE	0x04000000
+
+/* DP_CHAIN_MASK register constants */
+#define DP_CHAIN_4BPP		0x8888
+#define DP_CHAIN_7BPP		0xD2D2
+#define DP_CHAIN_8BPP		0x8080
+#define DP_CHAIN_8BPP_RGB	0x9292
+#define DP_CHAIN_15BPP		0x4210
+#define DP_CHAIN_16BPP		0x8410
+#define DP_CHAIN_24BPP		0x8080
+#define DP_CHAIN_32BPP		0x8080
+
+/* DP_PIX_WIDTH register constants */
+#define DST_1BPP		0
+#define DST_4BPP		1
+#define DST_8BPP		2
+#define DST_15BPP		3
+#define DST_16BPP		4
+#define DST_32BPP		6
+#define SRC_1BPP		0
+#define SRC_4BPP		0x100
+#define SRC_8BPP		0x200
+#define SRC_15BPP		0x300
+#define SRC_16BPP		0x400
+#define SRC_32BPP		0x600
+#define HOST_1BPP		0
+#define HOST_4BPP		0x10000
+#define HOST_8BPP		0x20000
+#define HOST_15BPP		0x30000
+#define HOST_16BPP		0x40000
+#define HOST_32BPP		0x60000
+#define BYTE_ORDER_MSB_TO_LSB	0
+#define BYTE_ORDER_LSB_TO_MSB	0x1000000
+
+/* DP_MIX register constants */
+#define BKGD_MIX_NOT_D			0
+#define BKGD_MIX_ZERO			1
+#define BKGD_MIX_ONE			2
+#define BKGD_MIX_D			3
+#define BKGD_MIX_NOT_S			4
+#define BKGD_MIX_D_XOR_S		5
+#define BKGD_MIX_NOT_D_XOR_S		6
+#define BKGD_MIX_S			7
+#define BKGD_MIX_NOT_D_OR_NOT_S		8
+#define BKGD_MIX_D_OR_NOT_S		9
+#define BKGD_MIX_NOT_D_OR_S		10
+#define BKGD_MIX_D_OR_S			11
+#define BKGD_MIX_D_AND_S		12
+#define BKGD_MIX_NOT_D_AND_S		13
+#define BKGD_MIX_D_AND_NOT_S		14
+#define BKGD_MIX_NOT_D_AND_NOT_S	15
+#define BKGD_MIX_D_PLUS_S_DIV2		0x17
+#define FRGD_MIX_NOT_D			0
+#define FRGD_MIX_ZERO			0x10000
+#define FRGD_MIX_ONE			0x20000
+#define FRGD_MIX_D			0x30000
+#define FRGD_MIX_NOT_S			0x40000
+#define FRGD_MIX_D_XOR_S		0x50000
+#define FRGD_MIX_NOT_D_XOR_S		0x60000
+#define FRGD_MIX_S			0x70000
+#define FRGD_MIX_NOT_D_OR_NOT_S		0x80000
+#define FRGD_MIX_D_OR_NOT_S		0x90000
+#define FRGD_MIX_NOT_D_OR_S		0xa0000
+#define FRGD_MIX_D_OR_S			0xb0000
+#define FRGD_MIX_D_AND_S		0xc0000
+#define FRGD_MIX_NOT_D_AND_S		0xd0000
+#define FRGD_MIX_D_AND_NOT_S		0xe0000
+#define FRGD_MIX_NOT_D_AND_NOT_S	0xf0000
+#define FRGD_MIX_D_PLUS_S_DIV2		0x170000
+
+/* DP_SRC register constants */
+#define BKGD_SRC_BKGD_CLR	0
+#define BKGD_SRC_FRGD_CLR	1
+#define BKGD_SRC_HOST		2
+#define BKGD_SRC_BLIT		3
+#define BKGD_SRC_PATTERN	4
+#define FRGD_SRC_BKGD_CLR	0
+#define FRGD_SRC_FRGD_CLR	0x100
+#define FRGD_SRC_HOST		0x200
+#define FRGD_SRC_BLIT		0x300
+#define FRGD_SRC_PATTERN	0x400
+#define MONO_SRC_ONE		0
+#define MONO_SRC_PATTERN	0x10000
+#define MONO_SRC_HOST		0x20000
+#define MONO_SRC_BLIT		0x30000
+
+/* CLR_CMP_CNTL register constants */
+#define COMPARE_FALSE		0
+#define COMPARE_TRUE		1
+#define COMPARE_NOT_EQUAL	4
+#define COMPARE_EQUAL		5
+#define COMPARE_DESTINATION	0
+#define COMPARE_SOURCE		0x1000000
+
+/* FIFO_STAT register constants */
+#define FIFO_ERR		0x80000000
+
+/* CONTEXT_LOAD_CNTL constants */
+#define CONTEXT_NO_LOAD			0
+#define CONTEXT_LOAD			0x10000
+#define CONTEXT_LOAD_AND_DO_FILL	0x20000
+#define CONTEXT_LOAD_AND_DO_LINE	0x30000
+#define CONTEXT_EXECUTE			0
+#define CONTEXT_CMD_DISABLE		0x80000000
+
+/* GUI_STAT register constants */
+#define ENGINE_IDLE		0
+#define ENGINE_BUSY		1
+#define SCISSOR_LEFT_FLAG	0x10
+#define SCISSOR_RIGHT_FLAG	0x20
+#define SCISSOR_TOP_FLAG	0x40
+#define SCISSOR_BOTTOM_FLAG	0x80
+
+/* ATI VGA Extended Regsiters */
+#define sioATIEXT		0x1ce
+#define bioATIEXT		0x3ce
+
+#define ATI2E			0xae
+#define ATI32			0xb2
+#define ATI36			0xb6
+
+/* VGA Graphics Controller Registers */
+#define VGAGRA			0x3ce
+#define GRA06			0x06
+
+/* VGA Seququencer Registers */
+#define VGASEQ			0x3c4
+#define SEQ02			0x02
+#define SEQ04			0x04
+
+#define MACH64_MAX_X		ENGINE_MAX_X
+#define MACH64_MAX_Y		ENGINE_MAX_Y
+
+#define INC_X			0x0020
+#define INC_Y			0x0080
+
+#define RGB16_555		0x0000
+#define RGB16_565		0x0040
+#define RGB16_655		0x0080
+#define RGB16_664		0x00c0
+
+#define POLY_TEXT_TYPE		0x0001
+#define IMAGE_TEXT_TYPE		0x0002
+#define TEXT_TYPE_8_BIT		0x0004
+#define TEXT_TYPE_16_BIT	0x0008
+#define POLY_TEXT_TYPE_8	(POLY_TEXT_TYPE | TEXT_TYPE_8_BIT)
+#define IMAGE_TEXT_TYPE_8	(IMAGE_TEXT_TYPE | TEXT_TYPE_8_BIT)
+#define POLY_TEXT_TYPE_16	(POLY_TEXT_TYPE | TEXT_TYPE_16_BIT)
+#define IMAGE_TEXT_TYPE_16	(IMAGE_TEXT_TYPE | TEXT_TYPE_16_BIT)
+
+#define MACH64_NUM_CLOCKS	16
+#define MACH64_NUM_FREQS	50
+
+/* Power Management register constants (LT & LT Pro) */
+#define PWR_MGT_ON		0x00000001
+#define PWR_MGT_MODE_MASK	0x00000006
+#define AUTO_PWR_UP		0x00000008
+#define USE_F32KHZ		0x00000400
+#define TRISTATE_MEM_EN		0x00000800
+#define SELF_REFRESH		0x00000080
+#define PWR_BLON		0x02000000
+#define STANDBY_NOW		0x10000000
+#define SUSPEND_NOW		0x20000000
+#define PWR_MGT_STATUS_MASK	0xC0000000
+#define PWR_MGT_STATUS_SUSPEND	0x80000000
+
+/* PM Mode constants  */
+#define PWR_MGT_MODE_PIN	0x00000000
+#define PWR_MGT_MODE_REG	0x00000002
+#define PWR_MGT_MODE_TIMER	0x00000004
+#define PWR_MGT_MODE_PCI	0x00000006
+
+/* LCD registers (LT Pro) */
+
+/* LCD Index register */
+#define LCD_INDEX_MASK		0x0000003F
+#define LCD_DISPLAY_DIS		0x00000100
+#define LCD_SRC_SEL		0x00000200
+#define CRTC2_DISPLAY_DIS	0x00000400
+
+/* LCD register indices */
+#define CONFIG_PANEL		0x00
+#define LCD_GEN_CTRL		0x01
+#define DSTN_CONTROL		0x02
+#define HFB_PITCH_ADDR		0x03
+#define HORZ_STRETCHING		0x04
+#define VERT_STRETCHING		0x05
+#define EXT_VERT_STRETCH	0x06
+#define LT_GIO			0x07
+#define POWER_MANAGEMENT	0x08
+#define ZVGPIO			0x09
+#define ICON_CLR0		0x0A
+#define ICON_CLR1		0x0B
+#define ICON_OFFSET		0x0C
+#define ICON_HORZ_VERT_POSN	0x0D
+#define ICON_HORZ_VERT_OFF	0x0E
+#define ICON2_CLR0		0x0F
+#define ICON2_CLR1		0x10
+#define ICON2_OFFSET		0x11
+#define ICON2_HORZ_VERT_POSN	0x12
+#define ICON2_HORZ_VERT_OFF	0x13
+#define LCD_MISC_CNTL		0x14
+#define APC_CNTL		0x1C
+#define POWER_MANAGEMENT_2	0x1D
+#define ALPHA_BLENDING		0x25
+#define PORTRAIT_GEN_CNTL	0x26
+#define APC_CTRL_IO		0x27
+#define TEST_IO			0x28
+#define TEST_OUTPUTS		0x29
+#define DP1_MEM_ACCESS		0x2A
+#define DP0_MEM_ACCESS		0x2B
+#define DP0_DEBUG_A		0x2C
+#define DP0_DEBUG_B		0x2D
+#define DP1_DEBUG_A		0x2E
+#define DP1_DEBUG_B		0x2F
+#define DPCTRL_DEBUG_A		0x30
+#define DPCTRL_DEBUG_B		0x31
+#define MEMBLK_DEBUG		0x32
+#define APC_LUT_AB		0x33
+#define APC_LUT_CD		0x34
+#define APC_LUT_EF		0x35
+#define APC_LUT_GH		0x36
+#define APC_LUT_IJ		0x37
+#define APC_LUT_KL		0x38
+#define APC_LUT_MN		0x39
+#define APC_LUT_OP		0x3A
+
+
+/* Values in LCD_MISC_CNTL */
+#define BIAS_MOD_LEVEL_MASK	0x0000ff00
+#define BIAS_MOD_LEVEL_SHIFT	8
+#define BLMOD_EN		0x00010000
+#define BIASMOD_EN		0x00020000
+
+#endif /* REGMACH64_H */
diff -Nru a/include/video/sgivw.h b/include/video/sgivw.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/sgivw.h	Wed Jul 24 14:03:35 2002
@@ -0,0 +1,660 @@
+/*
+ *  linux/drivers/video/sgivwfb.h -- SGI DBE frame buffer device header
+ *
+ *      Copyright (C) 1999 Silicon Graphics, Inc.
+ *      Jeffrey Newquist, newquist@engr.sgi.som
+ *
+ *  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.
+ */
+
+#ifndef __SGIVWFB_H__
+#define __SGIVWFB_H__
+
+#define DBE_GETREG(reg, dest)       ((dest) = DBE_REG_BASE->##reg)
+#define DBE_SETREG(reg, src)        DBE_REG_BASE->##reg = (src)
+#define DBE_IGETREG(reg, idx, dest) ((dest) = DBE_REG_BASE->##reg##[idx])
+#define DBE_ISETREG(reg, idx, src)  (DBE_REG_BASE->##reg##[idx] = (src))
+
+#define MASK(msb, lsb)          ( (((u32)1<<((msb)-(lsb)+1))-1) << (lsb) )
+#define GET(v, msb, lsb)        ( ((u32)(v) & MASK(msb,lsb)) >> (lsb) )
+#define SET(v, f, msb, lsb)     ( (v) = ((v)&~MASK(msb,lsb)) | (( (u32)(f)<<(lsb) ) & MASK(msb,lsb)) )
+
+#define GET_DBE_FIELD(reg, field, v)        GET((v), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB)
+#define SET_DBE_FIELD(reg, field, v, f)     SET((v), (f), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB)
+
+/* NOTE: All loads/stores must be 32 bits and uncached */
+
+#define DBE_REG_PHYS	0xd0000000
+#define DBE_REG_SIZE        0x01000000
+
+typedef struct {
+  volatile u32 ctrlstat;     /* 0x000000 general control */
+  volatile u32 dotclock;     /* 0x000004 dot clock PLL control */
+  volatile u32 i2c;          /* 0x000008 crt I2C control */
+  volatile u32 sysclk;       /* 0x00000c system clock PLL control */
+  volatile u32 i2cfp;        /* 0x000010 flat panel I2C control */
+  volatile u32 id;           /* 0x000014 device id/chip revision */
+  volatile u32 config;       /* 0x000018 power on configuration */
+  volatile u32 bist;         /* 0x00001c internal bist status */
+
+  char _pad0[ 0x010000 - 0x000020 ];
+
+  volatile u32 vt_xy;        /* 0x010000 current dot coords */
+  volatile u32 vt_xymax;     /* 0x010004 maximum dot coords */
+  volatile u32 vt_vsync;     /* 0x010008 vsync on/off */
+  volatile u32 vt_hsync;     /* 0x01000c hsync on/off */
+  volatile u32 vt_vblank;    /* 0x010010 vblank on/off */
+  volatile u32 vt_hblank;    /* 0x010014 hblank on/off */
+  volatile u32 vt_flags;     /* 0x010018 polarity of vt signals */
+  volatile u32 vt_f2rf_lock; /* 0x01001c f2rf & framelck y coord */
+  volatile u32 vt_intr01;    /* 0x010020 intr 0,1 y coords */
+  volatile u32 vt_intr23;    /* 0x010024 intr 2,3 y coords */
+  volatile u32 fp_hdrv;      /* 0x010028 flat panel hdrv on/off */
+  volatile u32 fp_vdrv;      /* 0x01002c flat panel vdrv on/off */
+  volatile u32 fp_de;        /* 0x010030 flat panel de on/off */
+  volatile u32 vt_hpixen;    /* 0x010034 intrnl horiz pixel on/off*/
+  volatile u32 vt_vpixen;    /* 0x010038 intrnl vert pixel on/off */
+  volatile u32 vt_hcmap;     /* 0x01003c cmap write (horiz) */
+  volatile u32 vt_vcmap;     /* 0x010040 cmap write (vert) */
+  volatile u32 did_start_xy; /* 0x010044 eol/f did/xy reset val */
+  volatile u32 crs_start_xy; /* 0x010048 eol/f crs/xy reset val */
+  volatile u32 vc_start_xy;  /* 0x01004c eol/f vc/xy reset val */
+
+  char _pad1[ 0x020000 - 0x010050 ];
+
+  volatile u32 ovr_width_tile; /* 0x020000 overlay plane ctrl 0 */
+  volatile u32 ovr_inhwctrl;   /* 0x020004 overlay plane ctrl 1 */
+  volatile u32 ovr_control;    /* 0x020008 overlay plane ctrl 1 */
+
+  char _pad2[ 0x030000 - 0x02000C ];
+
+  volatile u32 frm_size_tile;  /* 0x030000 normal plane ctrl 0 */
+  volatile u32 frm_size_pixel; /* 0x030004 normal plane ctrl 1 */
+  volatile u32 frm_inhwctrl;   /* 0x030008 normal plane ctrl 2 */
+  volatile u32 frm_control;	   /* 0x03000C normal plane ctrl 3 */
+
+  char _pad3[ 0x040000 - 0x030010 ];
+
+  volatile u32 did_inhwctrl;   /* 0x040000 DID control */
+  volatile u32 did_control;    /* 0x040004 DID shadow */
+
+  char _pad4[ 0x048000 - 0x040008 ];
+
+  volatile u32 mode_regs[32];  /* 0x048000 - 0x04807c WID table */
+
+  char _pad5[ 0x050000 - 0x048080 ];
+
+  volatile u32 cmap[6144];     /* 0x050000 - 0x055ffc color map */
+
+  char _pad6[ 0x058000 - 0x056000 ];
+
+  volatile u32 cm_fifo;        /* 0x058000 color map fifo status */
+
+  char _pad7[ 0x060000 - 0x058004 ];
+
+  volatile u32 gmap[256];      /* 0x060000 - 0x0603fc gamma map */
+
+  char _pad8[ 0x068000 - 0x060400 ];
+
+  volatile u32 gmap10[1024];   /* 0x068000 - 0x068ffc gamma map */
+
+  char _pad9[ 0x070000 - 0x069000 ];
+
+  volatile u32 crs_pos;        /* 0x070000 cusror control 0 */
+  volatile u32 crs_ctl;        /* 0x070004 cusror control 1 */
+  volatile u32 crs_cmap[3];    /* 0x070008 - 0x070010 crs cmap */
+
+  char _pad10[ 0x078000 - 0x070014 ];
+
+  volatile u32 crs_glyph[64];  /* 0x078000 - 0x0780fc crs glyph */
+
+  char _pad11[ 0x080000 - 0x078100 ];
+
+  volatile u32 vc_0;           /* 0x080000 video capture crtl 0 */
+  volatile u32 vc_1;           /* 0x080004 video capture crtl 1 */
+  volatile u32 vc_2;           /* 0x080008 video capture crtl 2 */
+  volatile u32 vc_3;           /* 0x08000c video capture crtl 3 */
+  volatile u32 vc_4;           /* 0x080010 video capture crtl 3 */
+  volatile u32 vc_5;           /* 0x080014 video capture crtl 3 */
+  volatile u32 vc_6;           /* 0x080018 video capture crtl 3 */
+  volatile u32 vc_7;           /* 0x08001c video capture crtl 3 */
+  volatile u32 vc_8;           /* 0x08000c video capture crtl 3 */
+} asregs;
+
+/* Bit mask information */
+
+#define DBE_CTRLSTAT_CHIPID_MSB     3
+#define DBE_CTRLSTAT_CHIPID_LSB     0
+#define DBE_CTRLSTAT_SENSE_N_MSB    4
+#define DBE_CTRLSTAT_SENSE_N_LSB    4
+#define DBE_CTRLSTAT_PCLKSEL_MSB    29
+#define DBE_CTRLSTAT_PCLKSEL_LSB    28
+
+#define DBE_DOTCLK_M_MSB            7
+#define DBE_DOTCLK_M_LSB            0
+#define DBE_DOTCLK_N_MSB            13
+#define DBE_DOTCLK_N_LSB            8
+#define DBE_DOTCLK_P_MSB            15
+#define DBE_DOTCLK_P_LSB            14
+#define DBE_DOTCLK_RUN_MSB          20
+#define DBE_DOTCLK_RUN_LSB          20
+
+#define DBE_VT_XY_VT_FREEZE_MSB     31
+#define DBE_VT_XY_VT_FREEZE_LSB     31
+
+#define DBE_VT_VSYNC_VT_VSYNC_ON_MSB        23
+#define DBE_VT_VSYNC_VT_VSYNC_ON_LSB        12
+#define DBE_VT_VSYNC_VT_VSYNC_OFF_MSB       11
+#define DBE_VT_VSYNC_VT_VSYNC_OFF_LSB       0
+
+#define DBE_VT_HSYNC_VT_HSYNC_ON_MSB        23
+#define DBE_VT_HSYNC_VT_HSYNC_ON_LSB        12
+#define DBE_VT_HSYNC_VT_HSYNC_OFF_MSB       11
+#define DBE_VT_HSYNC_VT_HSYNC_OFF_LSB       0
+
+#define DBE_VT_VBLANK_VT_VBLANK_ON_MSB        23
+#define DBE_VT_VBLANK_VT_VBLANK_ON_LSB        12
+#define DBE_VT_VBLANK_VT_VBLANK_OFF_MSB       11
+#define DBE_VT_VBLANK_VT_VBLANK_OFF_LSB       0
+
+#define DBE_VT_HBLANK_VT_HBLANK_ON_MSB        23
+#define DBE_VT_HBLANK_VT_HBLANK_ON_LSB        12
+#define DBE_VT_HBLANK_VT_HBLANK_OFF_MSB       11
+#define DBE_VT_HBLANK_VT_HBLANK_OFF_LSB       0
+
+#define DBE_VT_VCMAP_VT_VCMAP_ON_MSB        23
+#define DBE_VT_VCMAP_VT_VCMAP_ON_LSB        12
+#define DBE_VT_VCMAP_VT_VCMAP_OFF_MSB       11
+#define DBE_VT_VCMAP_VT_VCMAP_OFF_LSB       0
+
+#define DBE_VT_HCMAP_VT_HCMAP_ON_MSB        23
+#define DBE_VT_HCMAP_VT_HCMAP_ON_LSB        12
+#define DBE_VT_HCMAP_VT_HCMAP_OFF_MSB       11
+#define DBE_VT_HCMAP_VT_HCMAP_OFF_LSB       0
+
+#define DBE_VT_XYMAX_VT_MAXX_MSB    11
+#define DBE_VT_XYMAX_VT_MAXX_LSB    0
+#define DBE_VT_XYMAX_VT_MAXY_MSB    23
+#define DBE_VT_XYMAX_VT_MAXY_LSB    12
+
+#define DBE_VT_HPIXEN_VT_HPIXEN_ON_MSB      23
+#define DBE_VT_HPIXEN_VT_HPIXEN_ON_LSB      12
+#define DBE_VT_HPIXEN_VT_HPIXEN_OFF_MSB     11
+#define DBE_VT_HPIXEN_VT_HPIXEN_OFF_LSB     0
+
+#define DBE_VT_VPIXEN_VT_VPIXEN_ON_MSB      23
+#define DBE_VT_VPIXEN_VT_VPIXEN_ON_LSB      12
+#define DBE_VT_VPIXEN_VT_VPIXEN_OFF_MSB     11
+#define DBE_VT_VPIXEN_VT_VPIXEN_OFF_LSB     0
+
+#define DBE_OVR_CONTROL_OVR_DMA_ENABLE_MSB  0
+#define DBE_OVR_CONTROL_OVR_DMA_ENABLE_LSB  0
+
+#define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_MSB 0
+#define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_LSB 0
+
+#define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_MSB       13
+#define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_LSB       13
+
+#define DBE_FRM_CONTROL_FRM_DMA_ENABLE_MSB  0
+#define DBE_FRM_CONTROL_FRM_DMA_ENABLE_LSB  0
+#define DBE_FRM_CONTROL_FRM_TILE_PTR_MSB    31
+#define DBE_FRM_CONTROL_FRM_TILE_PTR_LSB    9
+#define DBE_FRM_CONTROL_FRM_LINEAR_MSB      1
+#define DBE_FRM_CONTROL_FRM_LINEAR_LSB      1
+
+#define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_MSB 0
+#define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_LSB 0
+
+#define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_MSB        12
+#define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_LSB        5
+#define DBE_FRM_SIZE_TILE_FRM_RHS_MSB       4
+#define DBE_FRM_SIZE_TILE_FRM_RHS_LSB       0
+#define DBE_FRM_SIZE_TILE_FRM_DEPTH_MSB     14
+#define DBE_FRM_SIZE_TILE_FRM_DEPTH_LSB     13
+#define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_MSB        15
+#define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_LSB        15
+
+#define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_MSB        31
+#define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_LSB        16
+
+#define DBE_DID_CONTROL_DID_DMA_ENABLE_MSB  0
+#define DBE_DID_CONTROL_DID_DMA_ENABLE_LSB  0
+#define DBE_DID_INHWCTRL_DID_DMA_ENABLE_MSB 0
+#define DBE_DID_INHWCTRL_DID_DMA_ENABLE_LSB 0
+
+#define DBE_DID_START_XY_DID_STARTY_MSB     23
+#define DBE_DID_START_XY_DID_STARTY_LSB     12
+#define DBE_DID_START_XY_DID_STARTX_MSB     11
+#define DBE_DID_START_XY_DID_STARTX_LSB     0
+
+#define DBE_CRS_START_XY_CRS_STARTY_MSB     23
+#define DBE_CRS_START_XY_CRS_STARTY_LSB     12
+#define DBE_CRS_START_XY_CRS_STARTX_MSB     11
+#define DBE_CRS_START_XY_CRS_STARTX_LSB     0
+
+#define DBE_WID_TYP_MSB     4
+#define DBE_WID_TYP_LSB     2
+#define DBE_WID_BUF_MSB     1
+#define DBE_WID_BUF_LSB     0
+
+#define DBE_VC_START_XY_VC_STARTY_MSB       23
+#define DBE_VC_START_XY_VC_STARTY_LSB       12
+#define DBE_VC_START_XY_VC_STARTX_MSB       11
+#define DBE_VC_START_XY_VC_STARTX_LSB       0
+
+/* Constants */
+
+#define DBE_FRM_DEPTH_8     0
+#define DBE_FRM_DEPTH_16    1
+#define DBE_FRM_DEPTH_32    2
+
+#define DBE_CMODE_I8        0
+#define DBE_CMODE_I12       1
+#define DBE_CMODE_RG3B2     2
+#define DBE_CMODE_RGB4      3
+#define DBE_CMODE_ARGB5     4
+#define DBE_CMODE_RGB8      5
+#define DBE_CMODE_RGBA5     6
+#define DBE_CMODE_RGB10     7
+
+#define DBE_BMODE_BOTH      3
+
+#define DBE_CRS_MAGIC       54
+
+/* Config Register (DBE Only) Definitions */
+
+#define DBE_CONFIG_VDAC_ENABLE       0x00000001
+#define DBE_CONFIG_VDAC_GSYNC        0x00000002
+#define DBE_CONFIG_VDAC_PBLANK       0x00000004
+#define DBE_CONFIG_FPENABLE          0x00000008
+#define DBE_CONFIG_LENDIAN           0x00000020
+#define DBE_CONFIG_TILEHIST          0x00000040
+#define DBE_CONFIG_EXT_ADDR          0x00000080
+
+#define DBE_CONFIG_FBDEV        ( DBE_CONFIG_VDAC_ENABLE | \
+                                      DBE_CONFIG_VDAC_GSYNC  | \
+                                      DBE_CONFIG_VDAC_PBLANK | \
+                                      DBE_CONFIG_LENDIAN     | \
+                                      DBE_CONFIG_EXT_ADDR )
+
+/*
+ * Available Video Timings and Corresponding Indices
+ */
+
+typedef enum {
+  DBE_VT_640_480_60,
+
+  DBE_VT_800_600_60,
+  DBE_VT_800_600_75,
+  DBE_VT_800_600_120,
+
+  DBE_VT_1024_768_50,
+  DBE_VT_1024_768_60,
+  DBE_VT_1024_768_75,
+  DBE_VT_1024_768_85,
+  DBE_VT_1024_768_120,
+
+  DBE_VT_1280_1024_50,
+  DBE_VT_1280_1024_60,
+  DBE_VT_1280_1024_75,
+  DBE_VT_1280_1024_85,
+
+  DBE_VT_1600_1024_53,
+  DBE_VT_1600_1024_60,
+
+  DBE_VT_1600_1200_50,
+  DBE_VT_1600_1200_60,
+  DBE_VT_1600_1200_75,
+
+  DBE_VT_1920_1080_50,
+  DBE_VT_1920_1080_60,
+  DBE_VT_1920_1080_72,
+
+  DBE_VT_1920_1200_50,
+  DBE_VT_1920_1200_60,
+  DBE_VT_1920_1200_66,
+
+  DBE_VT_UNKNOWN
+} dbe_timing_t;
+
+
+
+/*
+ * Crime Video Timing Data Structure
+ */
+
+typedef struct dbe_timing_info
+{
+  dbe_timing_t type;
+  int flags;				
+  short width;		    /* Monitor resolution		*/
+  short height;
+  int fields_sec;	    /* fields/sec  (Hz -3 dec. places */
+  int cfreq;		    /* pixel clock frequency (MHz -3 dec. places) */
+  short htotal;		    /* Horizontal total pixels	*/
+  short hblank_start;	    /* Horizontal blank start	*/
+  short hblank_end;	    /* Horizontal blank end		*/
+  short hsync_start;	    /* Horizontal sync start	*/
+  short hsync_end;	    /* Horizontal sync end		*/
+  short vtotal;		    /* Vertical total lines		*/
+  short vblank_start;	    /* Vertical blank start		*/
+  short vblank_end;	    /* Vertical blank end		*/
+  short vsync_start;	    /* Vertical sync start		*/
+  short vsync_end;	    /* Vertical sync end		*/
+  short pll_m;		    /* PLL M parameter		*/
+  short pll_n;		    /* PLL P parameter		*/
+  short pll_p;		    /* PLL N parameter		*/
+} dbe_timing_info_t;
+
+/* Defines for dbe_vof_info_t flags */
+
+#define DBE_VOF_UNKNOWNMON    1
+#define DBE_VOF_STEREO        2
+#define DBE_VOF_DO_GENSYNC    4          /* enable incoming sync */
+#define DBE_VOF_SYNC_ON_GREEN 8          /* sync on green */
+#define DBE_VOF_FLATPANEL     0x1000     /* FLATPANEL Timing */
+#define DBE_VOF_MAGICKEY      0x2000     /* Backdoor key */
+
+/*
+ * DBE Timing Tables
+ */
+
+#ifdef INCLUDE_TIMING_TABLE_DATA
+struct dbe_timing_info dbeVTimings[] = {
+  {
+    DBE_VT_640_480_60,
+    /*	flags,	width,			height,		fields_sec,		cfreq */
+    0,  	640,			480,		59940,			25175,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    800,	640,		    800,		656,	    	752,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    525,	480,		    525,		490,		    492,
+    /*	pll_m,	pll_n,			pll_p */
+    15,	    2,				3
+  },
+
+  {
+    DBE_VT_800_600_60,
+    /*	flags,	width,			height,		fields_sec,		cfreq */
+    0,	    800,			600,		60317,			40000,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1056,	800,		    1056,		840,		    968,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    628,	600,		    628,		601,		    605,
+    /*	pll_m,	pll_n,			pll_p */
+    3,	    1,				1
+  },
+
+  {
+    DBE_VT_800_600_75,
+    /*	flags,	width,		    height,		fields_sec,	    cfreq */
+    0,	    800,		    600,		75000,		    49500,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1056,	800,		    1056,		816,		    896,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    625,	600,		    625,		601,		    604,
+    /*	pll_m,	pll_n,		    pll_p */
+    11,	    3,		        1
+  },
+
+  {
+    DBE_VT_800_600_120,
+    /*	flags,					width,		height,			fields_sec,	    cfreq */
+    DBE_VOF_STEREO,	    800,		600,			119800,		    82978,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1040,	800,		    1040,		856,		    976,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    666,	600,		    666,		637,		    643,
+    /*	pll_m,	pll_n,		    pll_p */
+    31,	    5,		        1
+  },
+
+  {
+    DBE_VT_1024_768_50,
+    /*	flags,	width,		    height,		fields_sec,	    cfreq */
+    0,	    1024,		    768,		50000,		    54163,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1344,	1024,		    1344,		1048,		    1184,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    806,	768,		    806,		771,		    777,
+    /*	pll_m,	pll_n,		    pll_p */
+    4,	    1,		        1
+  },
+
+  {
+    DBE_VT_1024_768_60,
+    /*	flags,	width,			height,		fields_sec,		cfreq */
+    0,	    1024,			768,		60004,			65000,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1344,	1024,		    1344,		1048,		    1184,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    806,	768,		    806,		771,		    777,
+    /*	pll_m,	pll_n,			pll_p */
+    12,	    5,				0
+  },
+
+  {
+    DBE_VT_1024_768_75,
+    /*	flags,	width,			height,		fields_sec,		cfreq */
+    0,	    1024,			768,		75029,			78750,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1312,	1024,		    1312,		1040,		    1136,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    800,	768,		    800,		769,		    772,
+    /*	pll_m,	pll_n,			pll_p */
+    29,	    5,				1
+  },
+
+  {
+    DBE_VT_1024_768_85,
+    /*	flags,	width,			height,		fields_sec,		cfreq */
+    0,	    1024,			768,		84997,			94500,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1376,	1024,		    1376,		1072,		    1168,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    808,	768,		    808,		769,		    772,
+    /*	pll_m,	pll_n,			pll_p */
+    7,	    2,				0
+  },
+
+  {
+    DBE_VT_1024_768_120,
+    /*	flags,					width,		height,			fields_sec,		cfreq */
+    DBE_VOF_STEREO,	    1024,		768,			119800,			133195,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1376,	1024,		    1376,		1072,		    1168,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    808,	768,		    808,		769,		    772,
+    /*	pll_m,	pll_n,			pll_p */
+    5,	    1,				0
+  },
+
+  {
+    DBE_VT_1280_1024_50,
+    /*	flags,	width,			height,		fields_sec,		cfreq */
+    0,	    1280,			1024,		50000,			89460,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1680,	1280,		    1680,		1360,		    1480,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    1065,	1024,		    1065,		1027,		    1030,
+    /*	pll_m,	pll_n,			pll_p */
+    10,	    3,				0
+  },
+
+  {
+    DBE_VT_1280_1024_60,
+    /*	flags,	width,			height,		fields_sec,		cfreq */
+    0,	    1280,			1024,		60020,			108000,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1688,	1280,		    1688,		1328,		    1440,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    1066,	1024,		    1066,		1025,		    1028,
+    /*	pll_m,	pll_n,			pll_p */
+    4,	    1,			    0
+  },
+
+  {
+    DBE_VT_1280_1024_75,
+    /*	flags,	width,			height,		fields_sec,		cfreq */
+    0,	    1280,			1024,		75025,			135000,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1688,	1280,		    1688,		1296,		    1440,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    1066,	1024,		    1066,		1025,		    1028,
+    /*	pll_m,	pll_n,			pll_p */
+    5,	    1,				0
+  },
+
+  {
+    DBE_VT_1280_1024_85,
+    /*	flags,	width,		    height,		fields_sec,	    cfreq */
+    0,	    1280,		    1024,		85024,		    157500,
+    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
+    1728,	1280,		    1728,		1344,		    1504,
+    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
+    1072,	1024,		    1072,		1025,		    1028,
+    /*	pll_m,	pll_n,		    pll_p */
+    29,	    5,		        0
+  },
+
+  {
+    DBE_VT_1600_1024_53,
+    /* flags,	width,			height,		fields_sec,     cfreq */
+    DBE_VOF_FLATPANEL | DBE_VOF_MAGICKEY,
+    1600,			1024,		53000,			107447,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    1900,   1600,           1900,           1630,           1730,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1067,   1024,           1067,           1027,           1030,
+    /* pll_m,  pll_n,          pll_p */
+    4,      1,              0
+  },
+
+  {
+    DBE_VT_1600_1024_60,
+    /* flags,					width,          height,			fields_sec,     cfreq */
+    DBE_VOF_FLATPANEL,   1600,           1024,			60000,          106913,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    1670,   1600,           1670,           1630,           1650,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1067,   1024,           1067,           1027,           1030,
+    /* pll_m,  pll_n,          pll_p */
+    4,      1,              0
+  },
+
+  {
+    DBE_VT_1600_1200_50,
+    /* flags,  width,          height,         fields_sec,     cfreq */
+    0,      1600,           1200,           50000,          130500,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    2088,   1600,           2088,           1644,           1764,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1250,   1200,           1250,           1205,           1211,
+    /* pll_m,  pll_n,          pll_p */
+    24,     5,              0
+  },
+
+  {
+    DBE_VT_1600_1200_60,
+    /* flags,  width,          height,         fields_sec,     cfreq */
+    0,      1600,           1200,           59940,          162000,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    2160,   1600,           2160,           1644,           1856,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1250,   1200,           1250,           1201,           1204,
+    /* pll_m,  pll_n,          pll_p */
+    6,		1,              0
+  },
+
+  {
+    DBE_VT_1600_1200_75,
+    /* flags,  width,          height,         fields_sec,     cfreq */
+    0,      1600,           1200,           75000,          202500,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    2160,   1600,           2160,           1644,           1856,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1250,   1200,           1250,           1201,           1204,
+    /* pll_m,  pll_n,          pll_p */
+    15,		2,              0
+  },
+
+  {
+    DBE_VT_1920_1080_50,
+    /* flags,  width,          height,         fields_sec,     cfreq */
+    0,      1920,           1080,           50000,          133200,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    2368,   1920,           2368,           1952,           2096,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1125,   1080,           1125,           1083,           1086,
+    /* pll_m,  pll_n,          pll_p */
+    5,      1,              0
+  },
+
+  {
+    DBE_VT_1920_1080_60,
+    /* flags,  width,          height,         fields_sec,     cfreq */
+    0,      1920,           1080,           59940,          159840,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    2368,   1920,           2368,           1952,           2096,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1125,   1080,           1125,           1083,           1086,
+    /* pll_m,  pll_n,          pll_p */
+    6,      1,              0
+  },
+
+  {
+    DBE_VT_1920_1080_72,
+    /* flags,  width,          height,         fields_sec,     cfreq */
+    0,      1920,           1080,           72000,          216023,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    2560,   1920,           2560,           1968,           2184,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1172,   1080,           1172,           1083,           1086,
+    /* pll_m,  pll_n,          pll_p */
+    8,      1,              0
+  },
+
+  {
+    DBE_VT_1920_1200_50,
+    /* flags,  width,          height,         fields_sec,     cfreq */
+    0,      1920,           1200,           50000,          161500,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    2584,   1920,           2584,           1984,           2240,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1250,   1200,           1250,           1203,           1206,
+    /* pll_m,  pll_n,          pll_p */
+    6,      1,              0
+  },
+	
+  {
+    DBE_VT_1920_1200_60,
+    /* flags,  width,          height,         fields_sec,     cfreq */
+    0,      1920,           1200,           59940,          193800,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    2584,   1920,           2584,           1984,           2240,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1250,   1200,           1250,           1203,           1206,
+    /* pll_m,  pll_n,          pll_p */
+    29,     4,              0
+  },
+
+  {
+    DBE_VT_1920_1200_66,
+    /* flags,  width,          height,         fields_sec,     cfreq */
+    0,      1920,           1200,           66000,          213180,
+    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
+    2584,   1920,           2584,           1984,           2240,
+    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
+    1250,   1200,           1250,           1203,           1206,
+    /* pll_m,  pll_n,          pll_p */
+    8,      1,              0
+  }
+};
+
+#define DBE_VT_SIZE  (sizeof(dbeVTimings)/sizeof(dbeVTimings[0]))
+#endif // INCLUDE_TIMING_TABLE_DATA
+
+#endif // ! __SGIVWFB_H__
diff -Nru a/init/main.c b/init/main.c
--- a/init/main.c	Wed Jul 24 14:03:36 2002
+++ b/init/main.c	Wed Jul 24 14:03:36 2002
@@ -373,7 +373,7 @@
 	}
 
 	kmem_cache_init();
-	sti();
+	local_irq_enable();
 	calibrate_delay();
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start && !initrd_below_start_ok &&
diff -Nru a/ipc/shm.c b/ipc/shm.c
--- a/ipc/shm.c	Wed Jul 24 14:03:38 2002
+++ b/ipc/shm.c	Wed Jul 24 14:03:38 2002
@@ -105,12 +105,14 @@
  *
  * @shp: struct to free
  *
- * It has to be called with shp and shm_ids.sem locked
+ * It has to be called with shp and shm_ids.sem locked,
+ * but returns with shp unlocked and freed.
  */
 static void shm_destroy (struct shmid_kernel *shp)
 {
 	shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	shm_rmid (shp->id);
+	shm_unlock(shp->id);
 	shmem_lock(shp->shm_file, 0);
 	fput (shp->shm_file);
 	kfree (shp);
@@ -138,8 +140,8 @@
 	if(shp->shm_nattch == 0 &&
 	   shp->shm_flags & SHM_DEST)
 		shm_destroy (shp);
-
-	shm_unlock(id);
+	else
+		shm_unlock(id);
 	up (&shm_ids.sem);
 }
 
@@ -502,11 +504,9 @@
 			shp->shm_flags |= SHM_DEST;
 			/* Do not find it any more */
 			shp->shm_perm.key = IPC_PRIVATE;
+			shm_unlock(shmid);
 		} else
 			shm_destroy (shp);
-
-		/* Unlock */
-		shm_unlock(shmid);
 		up(&shm_ids.sem);
 		return err;
 	}
@@ -644,7 +644,8 @@
 	if(shp->shm_nattch == 0 &&
 	   shp->shm_flags & SHM_DEST)
 		shm_destroy (shp);
-	shm_unlock(shmid);
+	else
+		shm_unlock(shmid);
 	up (&shm_ids.sem);
 
 	*raddr = (unsigned long) user_addr;
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	Wed Jul 24 14:03:37 2002
+++ b/kernel/exit.c	Wed Jul 24 14:03:37 2002
@@ -184,7 +184,7 @@
 	current->exit_signal = SIGCHLD;
 
 	current->ptrace = 0;
-	if ((current->policy == SCHED_OTHER) && (task_nice(current) < 0))
+	if ((current->policy == SCHED_NORMAL) && (task_nice(current) < 0))
 		set_user_nice(current, 0);
 	/* cpus_allowed? */
 	/* rt_priority? */
@@ -530,10 +530,10 @@
 	tsk->flags |= PF_EXITING;
 	del_timer_sync(&tsk->real_timer);
 
-	if (unlikely(preempt_get_count()))
+	if (unlikely(preempt_count()))
 		printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
 				current->comm, current->pid,
-				preempt_get_count());
+				preempt_count());
 
 fake_volatile:
 	acct_process(code);
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Wed Jul 24 14:03:36 2002
+++ b/kernel/fork.c	Wed Jul 24 14:03:36 2002
@@ -611,7 +611,6 @@
 			    unsigned long stack_size)
 {
 	int retval;
-	unsigned long flags;
 	struct task_struct *p = NULL;
 	struct completion vfork;
 
@@ -675,6 +674,7 @@
 		init_completion(&vfork);
 	}
 	spin_lock_init(&p->alloc_lock);
+	spin_lock_init(&p->switch_lock);
 
 	clear_tsk_thread_flag(p,TIF_SIGPENDING);
 	init_sigpending(&p->pending);
@@ -740,10 +740,15 @@
 	 * total amount of pending timeslices in the system doesnt change,
 	 * resulting in more scheduling fairness.
 	 */
-	__save_flags(flags);
-	__cli();
-	p->time_slice = (current->time_slice + 1) >> 1;
+	local_irq_disable();
+        p->time_slice = (current->time_slice + 1) >> 1;
+	/*
+	 * The remainder of the first timeslice might be recovered by
+	 * the parent if the child exits early enough.
+	 */
+	p->first_time_slice = 1;
 	current->time_slice >>= 1;
+	p->sleep_timestamp = jiffies;
 	if (!current->time_slice) {
 		/*
 	 	 * This case is rare, it happens when the parent has only
@@ -751,11 +756,12 @@
 		 * runqueue lock is not a problem.
 		 */
 		current->time_slice = 1;
+		preempt_disable();
 		scheduler_tick(0, 0);
-	}
-	p->sleep_timestamp = jiffies;
-	__restore_flags(flags);
-
+		local_irq_enable();
+		preempt_enable();
+	} else
+		local_irq_enable();
 	/*
 	 * Ok, add it to the run-queues and make it
 	 * visible to the rest of the system.
diff -Nru a/kernel/kmod.c b/kernel/kmod.c
--- a/kernel/kmod.c	Wed Jul 24 14:03:37 2002
+++ b/kernel/kmod.c	Wed Jul 24 14:03:37 2002
@@ -190,16 +190,19 @@
 	pid_t pid;
 	int waitpid_result;
 	sigset_t tmpsig;
-	int i;
+	int i, ret;
 	static atomic_t kmod_concurrent = ATOMIC_INIT(0);
 #define MAX_KMOD_CONCURRENT 50	/* Completely arbitrary value - KAO */
 	static int kmod_loop_msg;
+	unsigned long saved_policy = current->policy;
 
+	current->policy = SCHED_NORMAL;
 	/* Don't allow request_module() before the root fs is mounted!  */
 	if ( ! current->fs->root ) {
 		printk(KERN_ERR "request_module[%s]: Root fs not mounted\n",
 			module_name);
-		return -EPERM;
+		ret = -EPERM;
+		goto out;
 	}
 
 	/* If modprobe needs a service that is in a module, we get a recursive
@@ -220,14 +223,16 @@
 			printk(KERN_ERR
 			       "kmod: runaway modprobe loop assumed and stopped\n");
 		atomic_dec(&kmod_concurrent);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto out;
 	}
 
 	pid = kernel_thread(exec_modprobe, (void*) module_name, 0);
 	if (pid < 0) {
 		printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
 		atomic_dec(&kmod_concurrent);
-		return pid;
+		ret = pid;
+		goto out;
 	}
 
 	/* Block everything but SIGKILL/SIGSTOP */
@@ -250,7 +255,10 @@
 		printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n",
 		       module_name, pid, -waitpid_result);
 	}
-	return 0;
+	ret = 0;
+out:
+	current->policy = saved_policy;
+	return ret;
 }
 #endif /* CONFIG_KMOD */
 
diff -Nru a/kernel/panic.c b/kernel/panic.c
--- a/kernel/panic.c	Wed Jul 24 14:03:39 2002
+++ b/kernel/panic.c	Wed Jul 24 14:03:39 2002
@@ -94,7 +94,7 @@
 #if defined(CONFIG_ARCH_S390)
         disabled_wait(caller);
 #endif
-	sti();
+	local_irq_enable();
 	for(;;) {
 		CHECK_EMERGENCY_SYNC
 	}
diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c
--- a/kernel/ptrace.c	Wed Jul 24 14:03:39 2002
+++ b/kernel/ptrace.c	Wed Jul 24 14:03:39 2002
@@ -124,12 +124,7 @@
 	struct page *page;
 	void *old_buf = buf;
 
-	/* Worry about races with exit() */
-	task_lock(tsk);
-	mm = tsk->mm;
-	if (mm)
-		atomic_inc(&mm->mm_users);
-	task_unlock(tsk);
+	mm = get_task_mm(tsk);
 	if (!mm)
 		return 0;
 
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Wed Jul 24 14:03:36 2002
+++ b/kernel/sched.c	Wed Jul 24 14:03:36 2002
@@ -12,8 +12,8 @@
  *  2002-01-04	New ultra-scalable O(1) scheduler by Ingo Molnar:
  *		hybrid priority-list and round-robin design with
  *		an array-switch method of distributing timeslices
- *		and per-CPU runqueues.  Additional code by Davide
- *		Libenzi, Robert Love, and Rusty Russell.
+ *		and per-CPU runqueues.  Cleanups and useful suggestions
+ *		by Davide Libenzi, preemptible kernel bits by Robert Love.
  */
 
 #include <linux/mm.h>
@@ -102,16 +102,23 @@
 	((p)->prio <= (p)->static_prio - DELTA(p))
 
 /*
- * TASK_TIMESLICE scales user-nice values [ -20 ... 19 ]
+ * BASE_TIMESLICE scales user-nice values [ -20 ... 19 ]
  * to time slice values.
  *
  * The higher a process's priority, the bigger timeslices
  * it gets during one round of execution. But even the lowest
  * priority process gets MIN_TIMESLICE worth of execution time.
+ *
+ * task_timeslice() is the interface that is used by the scheduler.
  */
 
-#define TASK_TIMESLICE(p) (MIN_TIMESLICE + \
-	((MAX_TIMESLICE - MIN_TIMESLICE) * (MAX_PRIO-1-(p)->static_prio)/39))
+#define BASE_TIMESLICE(p) (MIN_TIMESLICE + \
+	((MAX_TIMESLICE - MIN_TIMESLICE) * (MAX_PRIO-1-(p)->static_prio)/(MAX_USER_PRIO - 1)))
+
+static inline unsigned int task_timeslice(task_t *p)
+{
+	return BASE_TIMESLICE(p);
+}
 
 /*
  * These are the runqueue data structures:
@@ -136,13 +143,15 @@
  */
 struct runqueue {
 	spinlock_t lock;
-	unsigned long nr_running, nr_switches, expired_timestamp;
-	signed long nr_uninterruptible;
+	unsigned long nr_running, nr_switches, expired_timestamp,
+			nr_uninterruptible;
 	task_t *curr, *idle;
 	prio_array_t *active, *expired, arrays[2];
 	int prev_nr_running[NR_CPUS];
+
 	task_t *migration_thread;
 	list_t migration_queue;
+
 } ____cacheline_aligned;
 
 static struct runqueue runqueues[NR_CPUS] __cacheline_aligned;
@@ -154,6 +163,15 @@
 #define rt_task(p)		((p)->prio < MAX_RT_PRIO)
 
 /*
+ * Default context-switch locking:
+ */
+#ifndef prepare_arch_switch
+# define prepare_arch_switch(rq, next)	do { } while(0)
+# define finish_arch_switch(rq, next)	spin_unlock_irq(&(rq)->lock)
+# define task_running(rq, p)		((rq)->curr == (p))
+#endif
+
+/*
  * task_rq_lock - lock the runqueue a given task resides on and disable
  * interrupts.  Note the ordering: we can safely lookup the task_rq without
  * explicitly disabling preemption.
@@ -307,7 +325,7 @@
 repeat:
 	preempt_disable();
 	rq = task_rq(p);
-	if (unlikely(rq->curr == p)) {
+	if (unlikely(task_running(rq, p))) {
 		cpu_relax();
 		/*
 		 * enable/disable preemption just to make this
@@ -318,7 +336,7 @@
 		goto repeat;
 	}
 	rq = task_rq_lock(p, &flags);
-	if (unlikely(rq->curr == p)) {
+	if (unlikely(task_running(rq, p))) {
 		task_rq_unlock(rq, &flags);
 		preempt_enable();
 		goto repeat;
@@ -326,6 +344,7 @@
 	task_rq_unlock(rq, &flags);
 	preempt_enable();
 }
+#endif
 
 /*
  * Kick the remote CPU if the task is running currently,
@@ -338,10 +357,9 @@
  */
 void kick_if_running(task_t * p)
 {
-	if (p == task_rq(p)->curr)
+	if ((task_running(task_rq(p), p)) && (p->thread_info->cpu != smp_processor_id()))
 		resched_task(p);
 }
-#endif
 
 /*
  * Wake up a process. Put it on the run-queue if it's not
@@ -350,6 +368,8 @@
  * progress), and as such you're allowed to do the simpler
  * "current->state = TASK_RUNNING" to mark yourself runnable
  * without the overhead of this.
+ *
+ * returns failure only if the task is already active.
  */
 static int try_to_wake_up(task_t * p, int sync)
 {
@@ -366,7 +386,7 @@
 		 * Fast-migrate the task if it's not running or runnable
 		 * currently. Do not violate hard affinity.
 		 */
-		if (unlikely(sync && (rq->curr != p) &&
+		if (unlikely(sync && !task_running(rq, p) &&
 			(task_cpu(p) != smp_processor_id()) &&
 			(p->cpus_allowed & (1UL << smp_processor_id())))) {
 
@@ -377,9 +397,7 @@
 		if (old_state == TASK_UNINTERRUPTIBLE)
 			rq->nr_uninterruptible--;
 		activate_task(p, rq);
-		/*
-		 * If sync is set, a resched_task() is a NOOP
-		 */
+
 		if (p->prio < rq->curr->prio)
 			resched_task(rq->curr);
 		success = 1;
@@ -427,11 +445,13 @@
  */
 void sched_exit(task_t * p)
 {
-	__cli();
-	current->time_slice += p->time_slice;
-	if (unlikely(current->time_slice > MAX_TIMESLICE))
-		current->time_slice = MAX_TIMESLICE;
-	__sti();
+	local_irq_disable();
+	if (p->first_time_slice) {
+		current->time_slice += p->time_slice;
+		if (unlikely(current->time_slice > MAX_TIMESLICE))
+			current->time_slice = MAX_TIMESLICE;
+	}
+	local_irq_enable();
 	/*
 	 * If the child was a (relative-) CPU hog then decrease
 	 * the sleep_avg of the parent as well.
@@ -444,8 +464,7 @@
 #if CONFIG_SMP || CONFIG_PREEMPT
 asmlinkage void schedule_tail(task_t *prev)
 {
-	finish_arch_switch(this_rq());
-	finish_arch_schedule(prev);
+	finish_arch_switch(this_rq(), prev);
 }
 #endif
 
@@ -502,7 +521,42 @@
 	return sum;
 }
 
+/*
+ * double_rq_lock - safely lock two runqueues
+ *
+ * Note this does not disable interrupts like task_rq_lock,
+ * you need to do so manually before calling.
+ */
+static inline void double_rq_lock(runqueue_t *rq1, runqueue_t *rq2)
+{
+	if (rq1 == rq2)
+		spin_lock(&rq1->lock);
+	else {
+		if (rq1 < rq2) {
+			spin_lock(&rq1->lock);
+			spin_lock(&rq2->lock);
+		} else {
+			spin_lock(&rq2->lock);
+			spin_lock(&rq1->lock);
+		}
+	}
+}
+
+/*
+ * double_rq_unlock - safely unlock two runqueues
+ *
+ * Note this does not restore interrupts like task_rq_unlock,
+ * you need to do so manually after calling.
+ */
+static inline void double_rq_unlock(runqueue_t *rq1, runqueue_t *rq2)
+{
+	spin_unlock(&rq1->lock);
+	if (rq1 != rq2)
+		spin_unlock(&rq2->lock);
+}
+
 #if CONFIG_SMP
+
 /*
  * Lock the busiest runqueue as well, this_rq is locked already.
  * Recalculate nr_running if we have to drop the runqueue lock.
@@ -526,22 +580,10 @@
 	return nr_running;
 }
 
-/*
- * Current runqueue is empty, or rebalance tick: if there is an
- * inbalance (current runqueue is too short) then pull from
- * busiest runqueue(s).
- *
- * We call this with the current runqueue locked,
- * irqs disabled.
- */
-static void load_balance(runqueue_t *this_rq, int idle)
+static inline runqueue_t *find_busiest_queue(runqueue_t *this_rq, int this_cpu, int idle, int *imbalance)
 {
-	int imbalance, nr_running, load, max_load,
-		idx, i, this_cpu = smp_processor_id();
-	task_t *next = this_rq->idle, *tmp;
+	int nr_running, load, max_load, i;
 	runqueue_t *busiest, *rq_src;
-	prio_array_t *array;
-	list_t *head, *curr;
 
 	/*
 	 * We search all runqueues to find the most busy one.
@@ -590,21 +632,67 @@
 	}
 
 	if (likely(!busiest))
-		return;
+		goto out;
 
-	imbalance = (max_load - nr_running) / 2;
+	*imbalance = (max_load - nr_running) / 2;
 
 	/* It needs an at least ~25% imbalance to trigger balancing. */
-	if (!idle && (imbalance < (max_load + 3)/4))
-		return;
+	if (!idle && (*imbalance < (max_load + 3)/4)) {
+		busiest = NULL;
+		goto out;
+	}
 
 	nr_running = double_lock_balance(this_rq, busiest, this_cpu, idle, nr_running);
 	/*
 	 * Make sure nothing changed since we checked the
 	 * runqueue length.
 	 */
-	if (busiest->nr_running <= nr_running + 1)
-		goto out_unlock;
+	if (busiest->nr_running <= nr_running + 1) {
+		spin_unlock(&busiest->lock);
+		busiest = NULL;
+	}
+out:
+	return busiest;
+}
+
+/*
+ * Move a task from a remote runqueue to the local runqueue.
+ * Both runqueues must be locked.
+ */
+static inline void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p, runqueue_t *this_rq, int this_cpu)
+{
+	dequeue_task(p, src_array);
+	src_rq->nr_running--;
+	set_task_cpu(p, this_cpu);
+	this_rq->nr_running++;
+	enqueue_task(p, this_rq->active);
+	/*
+	 * 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)
+		set_need_resched();
+}
+
+/*
+ * Current runqueue is empty, or rebalance tick: if there is an
+ * inbalance (current runqueue is too short) then pull from
+ * busiest runqueue(s).
+ *
+ * We call this with the current runqueue locked,
+ * irqs disabled.
+ */
+static void load_balance(runqueue_t *this_rq, int idle)
+{
+	int imbalance, idx, this_cpu = smp_processor_id();
+	runqueue_t *busiest;
+	prio_array_t *array;
+	list_t *head, *curr;
+	task_t *tmp;
+
+	busiest = find_busiest_queue(this_rq, this_cpu, idle, &imbalance);
+	if (!busiest)
+		goto out;
 
 	/*
 	 * We first consider expired tasks. Those will likely not be
@@ -647,36 +735,28 @@
 
 #define CAN_MIGRATE_TASK(p,rq,this_cpu)					\
 	((jiffies - (p)->sleep_timestamp > cache_decay_ticks) &&	\
-		((p) != (rq)->curr) &&					\
+		!task_running(rq, p) &&					\
 			((p)->cpus_allowed & (1UL << (this_cpu))))
 
+	curr = curr->prev;
+
 	if (!CAN_MIGRATE_TASK(tmp, busiest, this_cpu)) {
-		curr = curr->next;
 		if (curr != head)
 			goto skip_queue;
 		idx++;
 		goto skip_bitmap;
 	}
-	next = tmp;
-	/*
-	 * take the task out of the other runqueue and
-	 * put it into this one:
-	 */
-	dequeue_task(next, array);
-	busiest->nr_running--;
-	set_task_cpu(next, this_cpu);
-	this_rq->nr_running++;
-	enqueue_task(next, this_rq->active);
-	if (next->prio < current->prio)
-		set_need_resched();
+	pull_task(busiest, array, tmp, this_rq, this_cpu);
 	if (!idle && --imbalance) {
-		if (array == busiest->expired) {
-			array = busiest->active;
-			goto new_array;
-		}
+		if (curr != head)
+			goto skip_queue;
+		idx++;
+		goto skip_bitmap;
 	}
 out_unlock:
 	spin_unlock(&busiest->lock);
+out:
+	;
 }
 
 /*
@@ -691,13 +771,13 @@
 #define BUSY_REBALANCE_TICK (HZ/4 ?: 1)
 #define IDLE_REBALANCE_TICK (HZ/1000 ?: 1)
 
-static inline void idle_tick(void)
+static inline void idle_tick(runqueue_t *rq)
 {
 	if (jiffies % IDLE_REBALANCE_TICK)
 		return;
-	spin_lock(&this_rq()->lock);
-	load_balance(this_rq(), 1);
-	spin_unlock(&this_rq()->lock);
+	spin_lock(&rq->lock);
+	load_balance(rq, 1);
+	spin_unlock(&rq->lock);
 }
 
 #endif
@@ -720,25 +800,26 @@
  * This function gets called by the timer code, with HZ frequency.
  * We call it with interrupts disabled.
  */
-void scheduler_tick(int user_tick, int system)
+void scheduler_tick(int user_ticks, int sys_ticks)
 {
 	int cpu = smp_processor_id();
 	runqueue_t *rq = this_rq();
 	task_t *p = current;
 
 	if (p == rq->idle) {
-		if (local_bh_count(cpu) || local_irq_count(cpu) > 1)
-			kstat.per_cpu_system[cpu] += system;
+		/* note: this timer irq context must be accounted for as well */
+		if (irq_count() - HARDIRQ_OFFSET >= SOFTIRQ_OFFSET)
+			kstat.per_cpu_system[cpu] += sys_ticks;
 #if CONFIG_SMP
-		idle_tick();
+		idle_tick(rq);
 #endif
 		return;
 	}
 	if (TASK_NICE(p) > 0)
-		kstat.per_cpu_nice[cpu] += user_tick;
+		kstat.per_cpu_nice[cpu] += user_ticks;
 	else
-		kstat.per_cpu_user[cpu] += user_tick;
-	kstat.per_cpu_system[cpu] += system;
+		kstat.per_cpu_user[cpu] += user_ticks;
+	kstat.per_cpu_system[cpu] += sys_ticks;
 
 	/* Task might have expired already, but not scheduled off yet */
 	if (p->array != rq->active) {
@@ -752,7 +833,8 @@
 		 * FIFO tasks have no timeslices.
 		 */
 		if ((p->policy == SCHED_RR) && !--p->time_slice) {
-			p->time_slice = TASK_TIMESLICE(p);
+			p->time_slice = task_timeslice(p);
+			p->first_time_slice = 0;
 			set_tsk_need_resched(p);
 
 			/* put it at the end of the queue: */
@@ -775,7 +857,8 @@
 		dequeue_task(p, rq->active);
 		set_tsk_need_resched(p);
 		p->prio = effective_prio(p);
-		p->time_slice = TASK_TIMESLICE(p);
+		p->time_slice = task_timeslice(p);
+		p->first_time_slice = 0;
 
 		if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) {
 			if (!rq->expired_timestamp)
@@ -816,8 +899,7 @@
 	prev = current;
 	rq = this_rq();
 
-	release_kernel_lock(prev, smp_processor_id());
-	prepare_arch_schedule(prev);
+	release_kernel_lock(prev);
 	prev->sleep_timestamp = jiffies;
 	spin_lock_irq(&rq->lock);
 
@@ -825,7 +907,7 @@
 	 * if entering off of a kernel preemption go straight
 	 * to picking the next task.
 	 */
-	if (unlikely(preempt_get_count() & PREEMPT_ACTIVE))
+	if (unlikely(preempt_count() & PREEMPT_ACTIVE))
 		goto pick_next_task;
 
 	switch (prev->state) {
@@ -874,14 +956,13 @@
 		rq->nr_switches++;
 		rq->curr = next;
 	
-		prepare_arch_switch(rq);
+		prepare_arch_switch(rq, next);
 		prev = context_switch(prev, next);
 		barrier();
 		rq = this_rq();
-		finish_arch_switch(rq);
+		finish_arch_switch(rq, prev);
 	} else
 		spin_unlock_irq(&rq->lock);
-	finish_arch_schedule(prev);
 
 	reacquire_kernel_lock(current);
 	preempt_enable_no_resched();
@@ -901,6 +982,12 @@
 
 	if (unlikely(ti->preempt_count))
 		return;
+	if (unlikely(irqs_disabled())) {
+		preempt_disable();
+		printk("bad: schedule() with irqs disabled!\n");
+		show_stack(NULL);
+		preempt_enable_no_resched();
+	}
 
 need_resched:
 	ti->preempt_count = PREEMPT_ACTIVE;
@@ -1019,7 +1106,7 @@
 	wait_queue_t wait;			\
 	init_waitqueue_entry(&wait, current);
 
-#define	SLEEP_ON_HEAD					\
+#define SLEEP_ON_HEAD					\
 	spin_lock_irqsave(&q->lock,flags);		\
 	__add_wait_queue(q, &wait);			\
 	spin_unlock(&q->lock);
@@ -1107,7 +1194,8 @@
 		 * If the task is running and lowered its priority,
 		 * or increased its priority then reschedule its CPU:
 		 */
-		if ((NICE_TO_PRIO(nice) < p->static_prio) || (p == rq->curr))
+		if ((NICE_TO_PRIO(nice) < p->static_prio) ||
+							task_running(rq, p))
 			resched_task(rq->curr);
 	}
 out_unlock:
@@ -1221,18 +1309,18 @@
 	else {
 		retval = -EINVAL;
 		if (policy != SCHED_FIFO && policy != SCHED_RR &&
-				policy != SCHED_OTHER)
+				policy != SCHED_NORMAL)
 			goto out_unlock;
 	}
 
 	/*
 	 * Valid priorities for SCHED_FIFO and SCHED_RR are
-	 * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_OTHER is 0.
+	 * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL is 0.
 	 */
 	retval = -EINVAL;
 	if (lp.sched_priority < 0 || lp.sched_priority > MAX_USER_RT_PRIO-1)
 		goto out_unlock;
-	if ((policy == SCHED_OTHER) != (lp.sched_priority == 0))
+	if ((policy == SCHED_NORMAL) != (lp.sched_priority == 0))
 		goto out_unlock;
 
 	retval = -EPERM;
@@ -1253,7 +1341,7 @@
 	retval = 0;
 	p->policy = policy;
 	p->rt_priority = lp.sched_priority;
-	if (policy != SCHED_OTHER)
+	if (policy != SCHED_NORMAL)
 		p->prio = MAX_USER_RT_PRIO-1 - p->rt_priority;
 	else
 		p->prio = p->static_prio;
@@ -1432,41 +1520,25 @@
 	prio_array_t *array = current->array;
 
 	/*
-	 * There are three levels of how a yielding task will give up
-	 * the current CPU:
+	 * We implement yielding by moving the task into the expired
+	 * queue.
 	 *
-	 *  #1 - it decreases its priority by one. This priority loss is
-	 *       temporary, it's recovered once the current timeslice
-	 *       expires.
-	 *
-	 *  #2 - once it has reached the lowest priority level,
-	 *       it will give up timeslices one by one. (We do not
-	 *       want to give them up all at once, it's gradual,
-	 *       to protect the casual yield()er.)
-	 *
-	 *  #3 - once all timeslices are gone we put the process into
-	 *       the expired array.
-	 *
-	 *  (special rule: RT tasks do not lose any priority, they just
-	 *  roundrobin on their current priority level.)
+	 * (special rule: RT tasks will just roundrobin in the active
+	 *  array.)
 	 */
-	if (likely(current->prio == MAX_PRIO-1)) {
-		if (current->time_slice <= 1) {
-			dequeue_task(current, rq->active);
-			enqueue_task(current, rq->expired);
-		} else
-			current->time_slice--;
-	} else if (unlikely(rt_task(current))) {
-		list_move_tail(&current->run_list, array->queue + current->prio);
+	if (likely(!rt_task(current))) {
+		dequeue_task(current, array);
+		enqueue_task(current, rq->expired);
 	} else {
 		list_del(&current->run_list);
-		if (list_empty(array->queue + current->prio))
-			__clear_bit(current->prio, array->bitmap);
-		current->prio++;
 		list_add_tail(&current->run_list, array->queue + current->prio);
-		__set_bit(current->prio, array->bitmap);
 	}
-	spin_unlock_no_resched(&rq->lock);
+	/*
+	 * Since we are going to call schedule() anyway, there's
+	 * no need to preempt:
+	 */
+	_raw_spin_unlock(&rq->lock);
+	preempt_enable_no_resched();
 
 	schedule();
 
@@ -1494,7 +1566,7 @@
 	case SCHED_RR:
 		ret = MAX_USER_RT_PRIO-1;
 		break;
-	case SCHED_OTHER:
+	case SCHED_NORMAL:
 		ret = 0;
 		break;
 	}
@@ -1510,7 +1582,7 @@
 	case SCHED_RR:
 		ret = 1;
 		break;
-	case SCHED_OTHER:
+	case SCHED_NORMAL:
 		ret = 0;
 	}
 	return ret;
@@ -1536,7 +1608,7 @@
 		goto out_unlock;
 
 	jiffies_to_timespec(p->policy & SCHED_FIFO ?
-				0 : TASK_TIMESLICE(p), &t);
+				0 : task_timeslice(p), &t);
 	read_unlock(&tasklist_lock);
 	retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
 out_nounlock:
@@ -1640,47 +1712,12 @@
 	read_unlock(&tasklist_lock);
 }
 
-/*
- * double_rq_lock - safely lock two runqueues
- *
- * Note this does not disable interrupts like task_rq_lock,
- * you need to do so manually before calling.
- */
-static inline void double_rq_lock(runqueue_t *rq1, runqueue_t *rq2)
-{
-	if (rq1 == rq2)
-		spin_lock(&rq1->lock);
-	else {
-		if (rq1 < rq2) {
-			spin_lock(&rq1->lock);
-			spin_lock(&rq2->lock);
-		} else {
-			spin_lock(&rq2->lock);
-			spin_lock(&rq1->lock);
-		}
-	}
-}
-
-/*
- * double_rq_unlock - safely unlock two runqueues
- *
- * Note this does not restore interrupts like task_rq_unlock,
- * you need to do so manually after calling.
- */
-static inline void double_rq_unlock(runqueue_t *rq1, runqueue_t *rq2)
-{
-	spin_unlock(&rq1->lock);
-	if (rq1 != rq2)
-		spin_unlock(&rq2->lock);
-}
-
 void __init init_idle(task_t *idle, int cpu)
 {
 	runqueue_t *idle_rq = cpu_rq(cpu), *rq = cpu_rq(task_cpu(idle));
 	unsigned long flags;
 
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 	double_rq_lock(idle_rq, rq);
 
 	idle_rq->curr = idle_rq->idle = idle;
@@ -1691,61 +1728,14 @@
 	set_task_cpu(idle, cpu);
 	double_rq_unlock(idle_rq, rq);
 	set_tsk_need_resched(idle);
-	__restore_flags(flags);
+	local_irq_restore(flags);
 
 	/* Set the preempt count _outside_ the spinlocks! */
+#if CONFIG_PREEMPT
 	idle->thread_info->preempt_count = (idle->lock_depth >= 0);
-}
-
-extern void init_timervecs(void);
-extern void timer_bh(void);
-extern void tqueue_bh(void);
-extern void immediate_bh(void);
-
-void __init sched_init(void)
-{
-	runqueue_t *rq;
-	int i, j, k;
-
-	for (i = 0; i < NR_CPUS; i++) {
-		prio_array_t *array;
-
-		rq = cpu_rq(i);
-		rq->active = rq->arrays;
-		rq->expired = rq->arrays + 1;
-		spin_lock_init(&rq->lock);
-		INIT_LIST_HEAD(&rq->migration_queue);
-
-		for (j = 0; j < 2; j++) {
-			array = rq->arrays + j;
-			for (k = 0; k < MAX_PRIO; k++) {
-				INIT_LIST_HEAD(array->queue + k);
-				__clear_bit(k, array->bitmap);
-			}
-			// delimiter for bitsearch
-			__set_bit(MAX_PRIO, array->bitmap);
-		}
-	}
-	/*
-	 * We have to do a little magic to get the first
-	 * process right in SMP mode.
-	 */
-	rq = this_rq();
-	rq->curr = current;
-	rq->idle = current;
-	set_task_cpu(current, smp_processor_id());
-	wake_up_process(current);
-
-	init_timervecs();
-	init_bh(TIMER_BH, timer_bh);
-	init_bh(TQUEUE_BH, tqueue_bh);
-	init_bh(IMMEDIATE_BH, immediate_bh);
-
-	/*
-	 * The boot idle thread does lazy MMU switching as well:
-	 */
-	atomic_inc(&init_mm.mm_count);
-	enter_lazy_tlb(&init_mm, current, smp_processor_id());
+#else
+	idle->thread_info->preempt_count = 0;
+#endif
 }
 
 #if CONFIG_SMP
@@ -1806,7 +1796,7 @@
 	 * If the task is not on a runqueue (and not running), then
 	 * it is sufficient to simply update the task's cpu field.
 	 */
-	if (!p->array && (p != rq->curr)) {
+	if (!p->array && !task_running(rq, p)) {
 		set_task_cpu(p, __ffs(p->cpus_allowed));
 		task_rq_unlock(rq, &flags);
 		goto out;
@@ -1924,3 +1914,55 @@
 	}
 }
 #endif
+
+extern void init_timervecs(void);
+extern void timer_bh(void);
+extern void tqueue_bh(void);
+extern void immediate_bh(void);
+
+void __init sched_init(void)
+{
+	runqueue_t *rq;
+	int i, j, k;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		prio_array_t *array;
+
+		rq = cpu_rq(i);
+		rq->active = rq->arrays;
+		rq->expired = rq->arrays + 1;
+		spin_lock_init(&rq->lock);
+		INIT_LIST_HEAD(&rq->migration_queue);
+
+		for (j = 0; j < 2; j++) {
+			array = rq->arrays + j;
+			for (k = 0; k < MAX_PRIO; k++) {
+				INIT_LIST_HEAD(array->queue + k);
+				__clear_bit(k, array->bitmap);
+			}
+			// delimiter for bitsearch
+			__set_bit(MAX_PRIO, array->bitmap);
+		}
+	}
+	/*
+	 * We have to do a little magic to get the first
+	 * process right in SMP mode.
+	 */
+	rq = this_rq();
+	rq->curr = current;
+	rq->idle = current;
+	set_task_cpu(current, smp_processor_id());
+	wake_up_process(current);
+
+	init_timervecs();
+	init_bh(TIMER_BH, timer_bh);
+	init_bh(TQUEUE_BH, tqueue_bh);
+	init_bh(IMMEDIATE_BH, immediate_bh);
+
+	/*
+	 * The boot idle thread does lazy MMU switching as well:
+	 */
+	atomic_inc(&init_mm.mm_count);
+	enter_lazy_tlb(&init_mm, current, smp_processor_id());
+}
+
diff -Nru a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c	Wed Jul 24 14:03:37 2002
+++ b/kernel/signal.c	Wed Jul 24 14:03:37 2002
@@ -500,7 +500,6 @@
 {
 	set_tsk_thread_flag(t,TIF_SIGPENDING);
 
-#ifdef CONFIG_SMP
 	/*
 	 * If the task is running on a different CPU 
 	 * force a reschedule on the other CPU to make
@@ -511,9 +510,8 @@
 	 * process of changing - but no harm is done by that
 	 * other than doing an extra (lightweight) IPI interrupt.
 	 */
-	if ((t->state == TASK_RUNNING) && (t->thread_info->cpu != smp_processor_id()))
+	if (t->state == TASK_RUNNING)
 		kick_if_running(t);
-#endif
 	if (t->state & TASK_INTERRUPTIBLE) {
 		wake_up_process(t);
 		return;
diff -Nru a/kernel/softirq.c b/kernel/softirq.c
--- a/kernel/softirq.c	Wed Jul 24 14:03:36 2002
+++ b/kernel/softirq.c	Wed Jul 24 14:03:36 2002
@@ -26,10 +26,6 @@
      execution. Hence, we get something sort of weak cpu binding.
      Though it is still not clear, will it result in better locality
      or will not.
-   - These softirqs are not masked by global cli() and start_bh_atomic()
-     (by clear reasons). Hence, old parts of code still using global locks
-     MUST NOT use softirqs, but insert interfacing routines acquiring
-     global locks. F.e. look at BHs implementation.
 
    Examples:
    - NET RX softirq. It is multithreaded and does not require
@@ -61,17 +57,17 @@
 
 asmlinkage void do_softirq()
 {
-	int cpu;
 	__u32 pending;
 	long flags;
 	__u32 mask;
+	int cpu;
 
 	if (in_interrupt())
 		return;
 
 	local_irq_save(flags);
-
 	cpu = smp_processor_id();
+
 	pending = softirq_pending(cpu);
 
 	if (pending) {
@@ -111,7 +107,7 @@
 }
 
 /*
- * This function must run with irq disabled!
+ * This function must run with irqs disabled!
  */
 inline void cpu_raise_softirq(unsigned int cpu, unsigned int nr)
 {
@@ -126,7 +122,7 @@
 	 * Otherwise we wake up ksoftirqd to make sure we
 	 * schedule the softirq soon.
 	 */
-	if (!(local_irq_count(cpu) | local_bh_count(cpu)))
+	if (!in_interrupt())
 		wakeup_softirqd(cpu);
 }
 
@@ -290,22 +286,16 @@
 
 static void bh_action(unsigned long nr)
 {
-	int cpu = smp_processor_id();
-
 	if (!spin_trylock(&global_bh_lock))
 		goto resched;
 
-	if (!hardirq_trylock(cpu))
-		goto resched_unlock;
-
 	if (bh_base[nr])
 		bh_base[nr]();
 
-	hardirq_endlock(cpu);
+	hardirq_endlock();
 	spin_unlock(&global_bh_lock);
 	return;
 
-resched_unlock:
 	spin_unlock(&global_bh_lock);
 resched:
 	mark_bh(nr);
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	Wed Jul 24 14:03:37 2002
+++ b/kernel/timer.c	Wed Jul 24 14:03:37 2002
@@ -888,7 +888,7 @@
 
 
 	if (t.tv_sec == 0 && t.tv_nsec <= 2000000L &&
-	    current->policy != SCHED_OTHER)
+	    current->policy != SCHED_NORMAL)
 	{
 		/*
 		 * Short delay requests up to 2 ms will be handled with
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Wed Jul 24 14:03:38 2002
+++ b/mm/memory.c	Wed Jul 24 14:03:38 2002
@@ -344,7 +344,7 @@
 			unsigned long pfn = pte_pfn(pte);
 
 			pte = ptep_get_and_clear(ptep);
-			tlb_remove_tlb_entry(tlb, pte, address+offset);
+			tlb_remove_tlb_entry(tlb, ptep, address+offset);
 			if (pfn_valid(pfn)) {
 				struct page *page = pfn_to_page(pfn);
 				if (!PageReserved(page)) {
diff -Nru a/mm/rmap.c b/mm/rmap.c
--- a/mm/rmap.c	Wed Jul 24 14:03:39 2002
+++ b/mm/rmap.c	Wed Jul 24 14:03:39 2002
@@ -163,7 +163,7 @@
 void page_remove_rmap(struct page * page, pte_t * ptep)
 {
 	struct pte_chain * pc, * prev_pc = NULL;
-	unsigned long pfn = pte_pfn(*ptep);
+	unsigned long pfn = page_to_pfn(page);
 
 	if (!page || !ptep)
 		BUG();
diff -Nru a/mm/shmem.c b/mm/shmem.c
--- a/mm/shmem.c	Wed Jul 24 14:03:37 2002
+++ b/mm/shmem.c	Wed Jul 24 14:03:38 2002
@@ -605,6 +605,7 @@
 		}
 		error = move_from_swap_cache(page, idx, mapping);
 		if (error < 0) {
+			spin_unlock(&info->lock);
 			unlock_page(page);
 			page_cache_release(page);
 			return ERR_PTR(error);
@@ -942,7 +943,6 @@
 fail_write:
 	status = -EFAULT;
 	ClearPageUptodate(page);
-	kunmap(page);
 	goto unlock;
 }
 
@@ -1079,9 +1079,6 @@
 static int shmem_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
 {
 	struct inode *inode = old_dentry->d_inode;
-
-	if (S_ISDIR(inode->i_mode))
-		return -EPERM;
 
 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 	inode->i_nlink++;
diff -Nru a/mm/slab.c b/mm/slab.c
--- a/mm/slab.c	Wed Jul 24 14:03:39 2002
+++ b/mm/slab.c	Wed Jul 24 14:03:39 2002
@@ -1355,7 +1355,11 @@
 		cc_entry(cc)[cc->avail++] =
 				kmem_cache_alloc_one_tail(cachep, slabp);
 	}
-	spin_unlock(&cachep->spinlock);
+	/*
+	 * CAREFUL: do not enable preemption yet, the per-CPU
+	 * entries rely on us being atomic.
+	 */
+	_raw_spin_unlock(&cachep->spinlock);
 
 	if (cc->avail)
 		return cc_entry(cc)[--cc->avail];
@@ -1382,8 +1386,12 @@
 			} else {
 				STATS_INC_ALLOCMISS(cachep);
 				objp = kmem_cache_alloc_batch(cachep,flags);
+				local_irq_restore(save_flags);
+				/* end of non-preemptible region */
+				preempt_enable();
 				if (!objp)
 					goto alloc_new_slab_nolock;
+				return objp;
 			}
 		} else {
 			spin_lock(&cachep->spinlock);
@@ -1399,9 +1407,11 @@
 alloc_new_slab:
 #ifdef CONFIG_SMP
 	spin_unlock(&cachep->spinlock);
-alloc_new_slab_nolock:
 #endif
 	local_irq_restore(save_flags);
+#ifdef CONFIG_SMP
+alloc_new_slab_nolock:
+#endif
 	if (kmem_cache_grow(cachep, flags))
 		/* Someone may have stolen our objs.  Doesn't matter, we'll
 		 * just come back here again.
diff -Nru a/net/802/tr.c b/net/802/tr.c
--- a/net/802/tr.c	Wed Jul 24 14:03:36 2002
+++ b/net/802/tr.c	Wed Jul 24 14:03:36 2002
@@ -36,7 +36,6 @@
 #include <linux/init.h>
 #include <net/arp.h>
 
-static void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct net_device *dev);
 static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev);
 static void rif_check_expire(unsigned long dummy);
 
@@ -230,7 +229,7 @@
  *	We try to do source routing... 
  */
 
-static void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *dev) 
+void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *dev) 
 {
 	int i, slack;
 	unsigned int hash;
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	Wed Jul 24 14:03:37 2002
+++ b/net/socket.c	Wed Jul 24 14:03:37 2002
@@ -288,7 +288,7 @@
 static void sock_destroy_inode(struct inode *inode)
 {
 	kmem_cache_free(sock_inode_cachep,
-			list_entry(inode, struct socket_alloc, vfs_inode));
+			container_of(inode, struct socket_alloc, vfs_inode));
 }
 
 static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
diff -Nru a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
--- a/net/sunrpc/xprt.c	Wed Jul 24 14:03:36 2002
+++ b/net/sunrpc/xprt.c	Wed Jul 24 14:03:36 2002
@@ -966,10 +966,10 @@
 		return;
 
 	if (!xprt_test_and_set_wspace(xprt)) {
-		spin_lock(&xprt->sock_lock);
+		spin_lock_bh(&xprt->sock_lock);
 		if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->pending)
 			rpc_wake_up_task(xprt->snd_task);
-		spin_unlock(&xprt->sock_lock);
+		spin_unlock_bh(&xprt->sock_lock);
 	}
 
 	if (test_bit(SOCK_NOSPACE, &sock->flags)) {
diff -Nru a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c
--- a/sound/oss/esssolo1.c	Wed Jul 24 14:03:36 2002
+++ b/sound/oss/esssolo1.c	Wed Jul 24 14:03:36 2002
@@ -235,16 +235,15 @@
         int i;
 	unsigned long flags;
 
-	/* the __cli stunt is to send the data within the command window */
+	/* the local_irq_save stunt is to send the data within the command window */
         for (i = 0; i < 0xffff; i++) {
-		__save_flags(flags);
-		__cli();
+		local_irq_save(flags);
                 if (!(inb(s->sbbase+0xc) & 0x80)) {
                         outb(data, s->sbbase+0xc);
-			__restore_flags(flags);
+			local_irq_restore(flags);
                         return;
                 }
-		__restore_flags(flags);
+		local_irq_restore(flags);
 	}
 	printk(KERN_ERR "esssolo1: write_seq timeout\n");
 	outb(data, s->sbbase+0xc);
diff -Nru a/sound/pci/ens1370.c b/sound/pci/ens1370.c
--- a/sound/pci/ens1370.c	Wed Jul 24 14:03:37 2002
+++ b/sound/pci/ens1370.c	Wed Jul 24 14:03:37 2002
@@ -1532,7 +1532,7 @@
 	outl(0, ES_REG(ensoniq, CONTROL));	/* switch everything off */
 	outl(0, ES_REG(ensoniq, SERIAL));	/* clear serial interface */
 #endif
-	synchronize_irq();
+	synchronize_irq(ensoniq->irq);
 	pci_set_power_state(ensoniq->pci, 3);
       __hw_end:
 #ifdef CHIP1370
@@ -1720,7 +1720,7 @@
 #ifdef CHIP1371
 	snd_ctl_add(card, snd_ctl_new1(&snd_es1371_joystick_addr, ensoniq));
 #endif
-	synchronize_irq();
+	synchronize_irq(ensoniq->irq);
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) {
 		snd_ensoniq_free(ensoniq);
diff -Nru a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
--- a/sound/pci/intel8x0.c	Wed Jul 24 14:03:38 2002
+++ b/sound/pci/intel8x0.c	Wed Jul 24 14:03:38 2002
@@ -1104,7 +1104,7 @@
 	outb(ICH_RESETREGS, ICHREG(chip, PO_CR));
 	outb(ICH_RESETREGS, ICHREG(chip, MC_CR));
 	/* --- */
-	synchronize_irq();
+	synchronize_irq(chip->irq);
       __hw_end:
 	if (chip->bdbars)
 		snd_free_pci_pages(chip->pci, 3 * sizeof(u32) * ICH_MAX_FRAGS * 2, chip->bdbars, chip->bdbars_addr);
@@ -1335,7 +1335,7 @@
 	}
 	chip->irq = pci->irq;
 	pci_set_master(pci);
-	synchronize_irq();
+	synchronize_irq(chip->irq);
 
 	/* initialize offsets */
 	chip->reg_pi_sr = ICH_REG_PI_SR;
